diff --git a/arduino/common/lib/CommsControl/CommsCommon.h b/arduino/common/lib/CommsControl/CommsCommon.h index 801b44c5855f4925195cb04ccb7485710f9727d1..b9e7e90e028ff33e398cf077d417e3a237f4b9ac 100644 --- a/arduino/common/lib/CommsControl/CommsCommon.h +++ b/arduino/common/lib/CommsControl/CommsCommon.h @@ -7,12 +7,20 @@ #define CONST_TIMEOUT_DATA 10 #define CONST_TIMEOUT_CMD 50 +#define PAYLOAD_MAX_SIZE_BUFFER 64 + +// UNO struggles with the RAM size for ring buffers +#ifdef ARDUINO_AVR_UNO +#define COMMS_MAX_SIZE_RB_RECEIVING 1 +#define COMMS_MAX_SIZE_RB_SENDING 1 +#else +#define COMMS_MAX_SIZE_RB_RECEIVING 10 +#define COMMS_MAX_SIZE_RB_SENDING 5 +#endif -#define CONST_MAX_SIZE_RB_RECEIVING 2 -#define CONST_MAX_SIZE_RB_SENDING 2 -#define CONST_MAX_SIZE_PACKET 64 -#define CONST_MAX_SIZE_BUFFER 128 -#define CONST_MIN_SIZE_PACKET 7 +#define COMMS_MAX_SIZE_PACKET 64 +#define COMMS_MAX_SIZE_BUFFER 128 +#define COMMS_MIN_SIZE_PACKET 7 #define COMMS_FRAME_BOUNDARY 0x7E #define COMMS_FRAME_ESCAPE 0x7D @@ -31,127 +39,9 @@ #define PACKET_DATA 0x40 #define PACKET_SET 0x20 //set vs get ? -#define HEV_FORMAT_VERSION 0xA2 - -// struct for all data sent -#pragma pack(1) -// fast values - read every ~10 ms -struct fast_data_format { - uint8_t version = HEV_FORMAT_VERSION; - uint32_t timestamp = 0; - uint8_t fsm_state = 0; - uint16_t pressure_air_supply = 0; - uint16_t pressure_air_regulated = 0; - uint16_t pressure_o2_supply = 0; - uint16_t pressure_o2_regulated = 0; - uint16_t pressure_buffer = 0; - uint16_t pressure_inhale = 0; - uint16_t pressure_patient = 0; - uint16_t temperature_buffer = 0; - uint16_t pressure_diff_patient = 0; - uint16_t ambient_pressure = 0; - uint16_t ambient_temperature = 0; - float airway_pressure = 0; - float flow = 0; - float volume = 0; -}; -#pragma pack() - - -#pragma pack(1) -// readback values -struct readback_data_format { - uint8_t version = HEV_FORMAT_VERSION; - uint32_t timestamp = 0; - uint16_t duration_calibration = 0; - uint16_t duration_buff_purge = 0; - uint16_t duration_buff_flush = 0; - uint16_t duration_buff_prefill = 0; - uint16_t duration_buff_fill = 0; - uint16_t duration_buff_loaded = 0; - uint16_t duration_buff_pre_inhale = 0; - uint16_t duration_inhale = 0; - uint16_t duration_pause = 0; - uint16_t duration_exhale_fill = 0; - uint16_t duration_exhale = 0; - - uint8_t valve_air_in = 0; - uint8_t valve_o2_in = 0; - uint8_t valve_inhale = 0; - uint8_t valve_exhale = 0; - uint8_t valve_purge = 0; - uint8_t ventilation_mode = 0; - - uint8_t valve_inhale_percent = 0; - uint8_t valve_exhale_percent = 0; - uint8_t valve_air_in_enable = 0; - uint8_t valve_o2_in_enable = 0; - uint8_t valve_purge_enable = 0; - uint8_t inhale_trigger_enable = 0; - uint8_t exhale_trigger_enable = 0; - uint8_t peep = 0; - float inhale_exhate_ratio = 0.0; -}; -#pragma pack() - -#pragma pack(1) -struct cycle_data_format { -// per breath values - uint8_t version = HEV_FORMAT_VERSION; - uint32_t timestamp = 0; - - float respiratory_rate = 0; - - float tidal_volume = 0; - float exhaled_tidal_volume = 0; - float inhaled_tidal_volume = 0; - - float minute_volume = 0; - float exhaled_minute_volume = 0; - float inhaled_minute_volume = 0; - - float lung_compliance = 0; - float static_compliance = 0; - - uint16_t inhalation_pressure = 0; - uint16_t peak_inspiratory_pressure = 0; - uint16_t plateau_pressure = 0; - uint16_t mean_airway_pressure = 0; - - uint8_t fi02_percent = 0; - - uint16_t apnea_index = 0; - uint16_t apnea_time = 0; - - uint8_t mandatory_breath = 0; -}; -#pragma pack() - -#pragma pack(1) -struct cmd_format { - uint8_t version = HEV_FORMAT_VERSION; - uint32_t timestamp = 0; - uint8_t cmd_type = 0; - uint8_t cmd_code = 0; - uint32_t param = 0; -}; -#pragma pack() - -#pragma pack(1) -struct alarm_format { - uint8_t version = HEV_FORMAT_VERSION; - uint32_t timestamp = 0; - uint8_t alarm_type = 0; - uint8_t alarm_code = 0; - uint32_t param = 0; -}; -#pragma pack() - // enum of all transfer types enum PAYLOAD_TYPE { - FASTDATA, - READBACKDATA, - CYCLEDATA, + DATA, CMD, ALARM, UNSET @@ -162,122 +52,39 @@ enum PAYLOAD_TYPE { // information is set as information in the protocol class Payload { public: - Payload(PAYLOAD_TYPE type = PAYLOAD_TYPE::UNSET) {_type = type; } //data_ = nullptr; cmd_ = nullptr; alarm_ = nullptr; } + Payload(PAYLOAD_TYPE type = PAYLOAD_TYPE::UNSET) {_type = type; } Payload(const Payload &other) { _type = other._type; - memcpy(&_fast_data , &other._fast_data , sizeof( fast_data_format)); - memcpy(&_readback_data , &other._readback_data , sizeof(readback_data_format)); - memcpy(&_cycle_data , &other._cycle_data , sizeof( cycle_data_format)); - memcpy(&_cmd , &other._cmd , sizeof( cmd_format)); - memcpy(&_alarm , &other._alarm , sizeof( alarm_format)); + memcpy(&_buffer, &other._buffer, sizeof (other._size)); } Payload& operator=(const Payload& other) { _type = other._type; - memcpy(&_fast_data , &other._fast_data , sizeof( fast_data_format)); - memcpy(&_readback_data , &other._readback_data , sizeof(readback_data_format)); - memcpy(&_cycle_data , &other._cycle_data , sizeof( cycle_data_format)); - memcpy(&_cmd , &other._cmd , sizeof( cmd_format)); - memcpy(&_alarm , &other._alarm , sizeof( alarm_format)); + memcpy(&_buffer, &other._buffer, sizeof (other._size)); return *this; } - ~Payload() { unsetAll(); } + ~Payload() { unset(); } + void unset() { memset( _buffer, 0, COMMS_MAX_SIZE_BUFFER); _type = PAYLOAD_TYPE::UNSET; } void setType(PAYLOAD_TYPE type) { _type = type; } PAYLOAD_TYPE getType() {return _type; } - // requires argument as new struct - void setFastData (fast_data_format *data ) { _type = PAYLOAD_TYPE::FASTDATA ; memcpy(&_fast_data , data, sizeof( fast_data_format)); } - void setReadbackData (readback_data_format *data ) { _type = PAYLOAD_TYPE::READBACKDATA; memcpy(&_readback_data, data, sizeof(readback_data_format)); } - void setCycleData (cycle_data_format *data ) { _type = PAYLOAD_TYPE::CYCLEDATA ; memcpy(&_cycle_data , data, sizeof( cycle_data_format)); } - void setCmd (cmd_format *cmd ) { _type = PAYLOAD_TYPE::CMD ; memcpy(&_cmd , cmd, sizeof( cmd_format)); } - void setAlarm (alarm_format *alarm ) { _type = PAYLOAD_TYPE::ALARM ; memcpy(&_alarm , alarm, sizeof( alarm_format)); } - - // get pointers to particular payload types - fast_data_format *getFastData () {return &_fast_data ; } - readback_data_format *getReadbackData () {return &_readback_data; } - cycle_data_format *getCycleData () {return &_cycle_data ; } - cmd_format *getCmd () {return &_cmd ; } - alarm_format *getAlarm () {return &_alarm ; } + void setSize(uint8_t size) { _size = size; } + uint8_t getSize() { return _size; } - void unsetAll() {unsetFastData(); unsetReadbackData(); unsetCycleData(); unsetAlarm(); unsetCmd(); _type = PAYLOAD_TYPE::UNSET; } - void unsetFastData() { memset(&_fast_data , 0, sizeof( fast_data_format)); } - void unsetReadbackData(){ memset(&_readback_data, 0, sizeof(readback_data_format)); } - void unsetCycleData() { memset(&_cycle_data , 0, sizeof( cycle_data_format)); } - void unsetCmd() { memset(&_cmd , 0, sizeof( cmd_format)); } - void unsetAlarm() { memset(&_alarm , 0, sizeof( alarm_format)); } - - void setPayload(PAYLOAD_TYPE type, void* information) { + void setPayload(PAYLOAD_TYPE type, void* information, uint8_t size) { setType(type); + setSize(size); setInformation(information); } - void setInformation(void* information) { - switch (_type) { - case PAYLOAD_TYPE::FASTDATA: - setFastData (reinterpret_cast< fast_data_format*>(information)); - break; - case PAYLOAD_TYPE::READBACKDATA: - setReadbackData(reinterpret_cast< readback_data_format*>(information)); - break; - case PAYLOAD_TYPE::CYCLEDATA: - setCycleData (reinterpret_cast< cycle_data_format*>(information)); - break; - case PAYLOAD_TYPE::CMD: - setCmd (reinterpret_cast< cmd_format*>(information)); - break; - case PAYLOAD_TYPE::ALARM: - setAlarm (reinterpret_cast< alarm_format*>(information)); - break; - default: - break; - } - } - - // returns void pointer, in case you know what to do with data or dont care what the format is - void *getInformation() { - switch (_type) { - case PAYLOAD_TYPE::FASTDATA: - return reinterpret_cast<void*>(getFastData ()); - case PAYLOAD_TYPE::READBACKDATA: - return reinterpret_cast<void*>(getReadbackData()); - case PAYLOAD_TYPE::CYCLEDATA: - return reinterpret_cast<void*>(getCycleData ()); - case PAYLOAD_TYPE::CMD: - return reinterpret_cast<void*>(getCmd ()); - case PAYLOAD_TYPE::ALARM: - return reinterpret_cast<void*>(getAlarm ()); - default: - return nullptr; - } - } - - // returns payload information size - uint8_t getSize() { - switch (_type) { - case PAYLOAD_TYPE::FASTDATA: - return static_cast<uint8_t>(sizeof( fast_data_format)); - case PAYLOAD_TYPE::READBACKDATA: - return static_cast<uint8_t>(sizeof( readback_data_format)); - case PAYLOAD_TYPE::CYCLEDATA: - return static_cast<uint8_t>(sizeof( cycle_data_format)); - case PAYLOAD_TYPE::CMD: - return static_cast<uint8_t>(sizeof( cmd_format)); - case PAYLOAD_TYPE::ALARM: - return static_cast<uint8_t>(sizeof( alarm_format)); - default: - return 0; - } - } + void setInformation(void* information) { memcpy(_buffer, information, _size); } + void *getInformation() { return reinterpret_cast<void*>(_buffer); } private: PAYLOAD_TYPE _type; - - fast_data_format _fast_data; - readback_data_format _readback_data; - cycle_data_format _cycle_data; - cmd_format _cmd; - alarm_format _alarm; + uint8_t _buffer[PAYLOAD_MAX_SIZE_BUFFER]; + uint8_t _size; }; #endif diff --git a/arduino/common/lib/CommsControl/CommsControl.cpp b/arduino/common/lib/CommsControl/CommsControl.cpp index ff465dbe5fe28f04e3f4205343ea69d29b78c3be..bb57819f040896857824870fba84069c80b752dc 100644 --- a/arduino/common/lib/CommsControl/CommsControl.cpp +++ b/arduino/common/lib/CommsControl/CommsControl.cpp @@ -15,13 +15,13 @@ CommsControl::CommsControl(uint32_t baudrate) { memset(_comms_received, 0, sizeof(_comms_received)); memset(_comms_send , 0, sizeof(_comms_send )); - _ring_buff_alarm = RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING>(); - _ring_buff_data = RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING>(); - _ring_buff_cmd = RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING>(); +// _ring_buff_alarm = RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING>(); +// _ring_buff_data = RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING>(); +// _ring_buff_cmd = RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING>(); - _ring_buff_received = RingBuf<Payload, CONST_MAX_SIZE_RB_RECEIVING>(); +// _ring_buff_received = RingBuf<Payload, COMMS_MAX_SIZE_RB_RECEIVING>(); - _comms_tmp = CommsFormat(CONST_MAX_SIZE_PACKET - CONST_MIN_SIZE_PACKET ); +// _comms_tmp = CommsFormat(COMMS_MAX_SIZE_PACKET - COMMS_MIN_SIZE_PACKET ); CommsFormat::generateACK(_comms_ack); CommsFormat::generateNACK(_comms_nck); @@ -41,16 +41,15 @@ void CommsControl::beginSerial() { // main function to always call and try and send data // _last_trans_time is changed when transmission occurs in sendQueue void CommsControl::sender() { - uint32_t tnow = static_cast<uint32_t>(millis()); - if (tnow - _last_trans_time > CONST_TIMEOUT_ALARM) { + if (static_cast<uint32_t>(millis()) - _last_trans_time > CONST_TIMEOUT_ALARM) { sendQueue(&_ring_buff_alarm); } - if (tnow - _last_trans_time > CONST_TIMEOUT_CMD) { + if (static_cast<uint32_t>(millis()) - _last_trans_time > CONST_TIMEOUT_CMD) { sendQueue(&_ring_buff_cmd); } - if (tnow - _last_trans_time > CONST_TIMEOUT_DATA) { + if (static_cast<uint32_t>(millis()) - _last_trans_time > CONST_TIMEOUT_DATA) { sendQueue(&_ring_buff_data); } } @@ -70,7 +69,7 @@ void CommsControl::receiver() { _last_trans_index += Serial.readBytes(_last_trans + _last_trans_index, 1); // if managed to read at least 1 byte - if (_last_trans_index > 0 && _last_trans_index < CONST_MAX_SIZE_BUFFER) { + if (_last_trans_index > 0 && _last_trans_index < COMMS_MAX_SIZE_BUFFER) { current_trans_index = _last_trans_index - 1; // find the boundary of frames @@ -102,15 +101,18 @@ void CommsControl::receiver() { finishPacket(type); break; default: + Serial.print("add: "); uint8_t sequence_receive = (control >> 1 ) & 0x7F; sequence_receive += 1; + uint8_t address = *_comms_tmp.getAddress(); // received DATA if (receivePacket(type)) { - _comms_ack.setAddress(_comms_tmp.getAddress()); + _comms_ack.setAddress(&address); + Serial.println(*_comms_ack.getAddress()); _comms_ack.setSequenceReceive(sequence_receive); sendPacket(_comms_ack); } else { - _comms_nck.setAddress(_comms_tmp.getAddress()); + _comms_nck.setAddress(&address); _comms_nck.setSequenceReceive(sequence_receive); sendPacket(_comms_nck); } @@ -128,7 +130,7 @@ void CommsControl::receiver() { break; } } - } else if (_last_trans_index >= CONST_MAX_SIZE_BUFFER) { + } else if (_last_trans_index >= COMMS_MAX_SIZE_BUFFER) { _last_trans_index = 0; } } @@ -138,10 +140,10 @@ void CommsControl::receiver() { bool CommsControl::writePayload(Payload &pl) { PAYLOAD_TYPE payload_type = pl.getType(); if (payload_type != PAYLOAD_TYPE::UNSET) { - // create comms format using payload, the type is actually deduced from the payload + // create comms format using payload, the type is deduced from the payload itself CommsFormat comms = CommsFormat(pl); - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue = getQueue(payload_type); + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue = getQueue(payload_type); // add new entry to the queue if (queue->isFull()) { CommsFormat comms_rm; @@ -188,7 +190,6 @@ bool CommsControl::encoder(uint8_t *data, uint8_t data_size) { return false; } - // general decoder of any transmission bool CommsControl::decoder(uint8_t* data, uint8_t data_start, uint8_t data_stop) { // need to have more than 1 byte transferred @@ -216,7 +217,7 @@ bool CommsControl::decoder(uint8_t* data, uint8_t data_start, uint8_t data_stop) } // sending anything of commsDATA format -void CommsControl::sendQueue(RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue) { +void CommsControl::sendQueue(RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue) { // if have data to send if (!queue->isEmpty()) { queue->operator [](0).setSequenceSend(_sequence_send); @@ -238,35 +239,29 @@ void CommsControl::sendPacket(CommsFormat &packet) { // resending the packet, can lower the timeout since either NACK or wrong FCS already checked //WIP -void CommsControl::resendPacket(RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue) { +void CommsControl::resendPacket(RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue) { ; } // receiving anything of commsFormat bool CommsControl::receivePacket(PAYLOAD_TYPE &type) { - _payload_tmp.unsetAll(); - _payload_tmp.setType(type); - void *information = _payload_tmp.getInformation(); - // if type is definet, copy information from comms to payload - if (information != nullptr) { - memcpy(information, _comms_tmp.getInformation(), _comms_tmp.getInfoSize()); - - // remove first entry if queue is full - if (_ring_buff_received.isFull()) { - Payload payload_rm; - if (_ring_buff_received.pop(payload_rm)) { - ; - } + _payload_tmp.unset(); + _payload_tmp.setPayload(type, _comms_tmp.getInformation(), _comms_tmp.getInfoSize()); + + // remove first entry if queue is full + if (_ring_buff_received.isFull()) { + Payload payload_rm; + if (_ring_buff_received.pop(payload_rm)) { + ; } - return _ring_buff_received.push(_payload_tmp); } - return false; + return _ring_buff_received.push(_payload_tmp); } // if FCS is ok, remove from queue void CommsControl::finishPacket(PAYLOAD_TYPE &type) { - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue = getQueue(type); + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue = getQueue(type); if (queue != nullptr && !queue->isEmpty()) { // get the sequence send from first entry in the queue, add one as that should be return @@ -288,20 +283,20 @@ PAYLOAD_TYPE CommsControl::getInfoType(uint8_t *address) { case PACKET_CMD: return PAYLOAD_TYPE::CMD; case PACKET_DATA: - return PAYLOAD_TYPE::FASTDATA; + return PAYLOAD_TYPE::DATA; default: return PAYLOAD_TYPE::UNSET; } } // get link to queue according to packet format -RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *CommsControl::getQueue(PAYLOAD_TYPE &type) { +RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *CommsControl::getQueue(PAYLOAD_TYPE &type) { switch (type) { case PAYLOAD_TYPE::ALARM: return &_ring_buff_alarm; case PAYLOAD_TYPE::CMD: return &_ring_buff_cmd; - case PAYLOAD_TYPE::FASTDATA: + case PAYLOAD_TYPE::DATA: return &_ring_buff_data; default: return nullptr; diff --git a/arduino/common/lib/CommsControl/CommsControl.h b/arduino/common/lib/CommsControl/CommsControl.h index 13c30a7eed4958f8f71c9db49c585ef364cf69ed..65fc62f11cae64ecc44a075b45d0157d5bae347c 100644 --- a/arduino/common/lib/CommsControl/CommsControl.h +++ b/arduino/common/lib/CommsControl/CommsControl.h @@ -26,11 +26,11 @@ public: void receiver(); private: - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *getQueue(PAYLOAD_TYPE &type); + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *getQueue(PAYLOAD_TYPE &type); PAYLOAD_TYPE getInfoType(uint8_t *address); - void sendQueue (RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue); - void resendPacket (RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> *queue); + void sendQueue (RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue); + void resendPacket (RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> *queue); bool receivePacket(PAYLOAD_TYPE &type); void finishPacket (PAYLOAD_TYPE &type); @@ -46,11 +46,11 @@ private: CommsFormat _comms_ack; CommsFormat _comms_nck; - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> _ring_buff_alarm; - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> _ring_buff_data; - RingBuf<CommsFormat, CONST_MAX_SIZE_RB_SENDING> _ring_buff_cmd; + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> _ring_buff_alarm; + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> _ring_buff_data; + RingBuf<CommsFormat, COMMS_MAX_SIZE_RB_SENDING> _ring_buff_cmd; - RingBuf<Payload, CONST_MAX_SIZE_RB_RECEIVING> _ring_buff_received; + RingBuf<Payload, COMMS_MAX_SIZE_RB_RECEIVING> _ring_buff_received; Payload _payload_tmp; CommsFormat _comms_tmp; @@ -59,12 +59,12 @@ private: uint32_t _last_trans_time; - uint8_t _comms_received[CONST_MAX_SIZE_BUFFER]; + uint8_t _comms_received[COMMS_MAX_SIZE_BUFFER]; uint8_t _comms_received_size; - uint8_t _comms_send [CONST_MAX_SIZE_BUFFER]; + uint8_t _comms_send [COMMS_MAX_SIZE_BUFFER]; uint8_t _comms_send_size; - uint8_t _last_trans[CONST_MAX_SIZE_BUFFER]; + uint8_t _last_trans[COMMS_MAX_SIZE_BUFFER]; uint8_t _start_trans_index; uint8_t _last_trans_index; diff --git a/arduino/common/lib/CommsControl/CommsFormat.cpp b/arduino/common/lib/CommsControl/CommsFormat.cpp index 04416111b1f0d6937c4d8cb9e2fd3395dc1cf2cb..1d034227560e3c1e61f7505273e3b0897b581c60 100644 --- a/arduino/common/lib/CommsControl/CommsFormat.cpp +++ b/arduino/common/lib/CommsControl/CommsFormat.cpp @@ -14,7 +14,7 @@ CommsFormat::CommsFormat(Payload &pl) { case PAYLOAD_TYPE::CMD: address = PACKET_CMD; break; - case PAYLOAD_TYPE::FASTDATA: + case PAYLOAD_TYPE::DATA: address = PACKET_DATA; break; default: @@ -29,13 +29,13 @@ void CommsFormat::init(uint8_t info_size, uint8_t address, uint16_t control) { memset(_data, 0, sizeof(_data)); _info_size = info_size; - _packet_size = info_size + CONST_MIN_SIZE_PACKET ; // minimum size (start,address,control,fcs,stop) - if (_packet_size > CONST_MAX_SIZE_PACKET) { + _packet_size = info_size + COMMS_MIN_SIZE_PACKET ; // minimum size (start,address,control,fcs,stop) + if (_packet_size > COMMS_MAX_SIZE_PACKET) { return; } - assignBytes(getAddress(), &address, 1, false); - assignBytes(getControl(), reinterpret_cast<uint8_t*>(&control), 2, false); + setAddress(&address, false); + setControl(reinterpret_cast<uint8_t*>(&control), false); // hardcoded defaults *getStart() = COMMS_FRAME_BOUNDARY; // fixed start flag @@ -46,7 +46,7 @@ void CommsFormat::init(uint8_t info_size, uint8_t address, uint16_t control) { void CommsFormat::assignBytes(uint8_t* target, uint8_t* source, uint8_t size, bool calcCrc) { - memcpy(target, source, size); + memcpy(reinterpret_cast<void *>(target), reinterpret_cast<void *>(source), size); if (calcCrc) { generateCrc(); } @@ -103,13 +103,18 @@ void CommsFormat::generateCrc(bool assign) { } // assign received information to packet +// NOTE: possible confusion when using set information, the address or control are not changed! void CommsFormat::setInformation(Payload *pl) { - assignBytes(getInformation(), reinterpret_cast<uint8_t*>(pl->getInformation()), getInfoSize()); + // if the info size changed only the info size + if (_info_size != pl->getSize()) { + init(pl->getSize(), _address, _control); + } + assignBytes(getInformation(), reinterpret_cast<uint8_t*>(pl->getInformation()), _info_size); } void CommsFormat::copyData(uint8_t* data, uint8_t dataSize) { _packet_size = dataSize; - _info_size = dataSize - CONST_MIN_SIZE_PACKET; + _info_size = dataSize - COMMS_MIN_SIZE_PACKET; memset(getData(), 0, sizeof(_data)); assignBytes(getData(), data, dataSize); diff --git a/arduino/common/lib/CommsControl/CommsFormat.h b/arduino/common/lib/CommsControl/CommsFormat.h index d39716ec60f1976201966d7eced33113fc9d3c66..60334a9896c00abd339444172919a115e2f6526c 100644 --- a/arduino/common/lib/CommsControl/CommsFormat.h +++ b/arduino/common/lib/CommsControl/CommsFormat.h @@ -19,13 +19,13 @@ public: _crc = other._crc; _packet_size = other._packet_size; _info_size = other._info_size; - memcpy(_data, other._data, CONST_MAX_SIZE_PACKET); + memcpy(_data, other._data, COMMS_MAX_SIZE_PACKET); } CommsFormat& operator=(const CommsFormat& other) { _crc = other._crc; _packet_size = other._packet_size; _info_size = other._info_size; - memcpy(_data, other._data, CONST_MAX_SIZE_PACKET); + memcpy(_data, other._data, COMMS_MAX_SIZE_PACKET); return *this; } @@ -33,8 +33,8 @@ public: uint8_t* getData() { return _data; } uint8_t getSize() { return _packet_size; } - void setAddress(uint8_t* address) {assignBytes(getAddress(), address, 1); } - void setControl(uint8_t* control) {assignBytes(getControl(), control, 2); } + void setAddress(uint8_t* address, bool calcCrc = true) {_address = *address; assignBytes(getAddress(), address, 1, calcCrc); } + void setControl(uint8_t* control, bool calcCrc = true) {_control = *control; assignBytes(getControl(), control, 2, calcCrc); } void setInformation(Payload *pl); void assignBytes(uint8_t* target, uint8_t* source, uint8_t size, bool calcCrc = true); @@ -66,9 +66,12 @@ public: private: void init(uint8_t info_size = 0, uint8_t address = 0x00, uint16_t control = 0x0000); - uint8_t _data[CONST_MAX_SIZE_PACKET]; + uint8_t _data[COMMS_MAX_SIZE_PACKET]; uint8_t _packet_size; uint8_t _info_size; + + uint8_t _address; + uint16_t _control; uint16_t _crc; }; diff --git a/arduino/hev_prototype_v1/src/common.h b/arduino/hev_prototype_v1/src/common.h index acf4a14bb5253c3fccde2dc84d78c43f56122493..dfe41d26e323f9c3584783c59354cb500d76db41 100644 --- a/arduino/hev_prototype_v1/src/common.h +++ b/arduino/hev_prototype_v1/src/common.h @@ -26,6 +26,8 @@ #include <Arduino_Yun_pinout.h> #endif +#define HEV_FORMAT_VERSION 0xA2 + // const float MAX_VALVE_FRAC_OPEN = 0.68; // input params @@ -66,6 +68,17 @@ enum CMD_SET_MODE : uint8_t { HEV_MODE_TEST }; +#pragma pack(1) +struct cmd_format { + uint8_t version = HEV_FORMAT_VERSION; + uint32_t timestamp = 0; + uint8_t cmd_type = 0; + uint8_t cmd_code = 0; + uint32_t param = 0; +}; +#pragma pack() + + enum ALARM_TYPE: uint8_t { LP = 1, MP = 2, @@ -100,6 +113,119 @@ enum ALARM_CODES: uint8_t { ARDUINO_FAIL = 25 // HP }; +#pragma pack(1) +struct alarm_format { + uint8_t version = HEV_FORMAT_VERSION; + uint32_t timestamp = 0; + uint8_t alarm_type = 0; + uint8_t alarm_code = 0; + uint32_t param = 0; +}; +#pragma pack() + +enum DATA_TYPE: uint8_t { + FAST = 1, + READBACK = 2, + CYCLE = 3 +}; + +// struct for all data sent +#pragma pack(1) +struct fast_data_format { +// fast values - read every ~10 ms + uint8_t version = HEV_FORMAT_VERSION; + uint32_t timestamp = 0; + uint8_t data_type = DATA_TYPE::FAST; + uint8_t fsm_state = 0; + uint16_t pressure_air_supply = 0; + uint16_t pressure_air_regulated = 0; + uint16_t pressure_o2_supply = 0; + uint16_t pressure_o2_regulated = 0; + uint16_t pressure_buffer = 0; + uint16_t pressure_inhale = 0; + uint16_t pressure_patient = 0; + uint16_t temperature_buffer = 0; + uint16_t pressure_diff_patient = 0; + uint16_t ambient_pressure = 0; + uint16_t ambient_temperature = 0; + float airway_pressure = 0; + float flow = 0; + float volume = 0; +}; +#pragma pack() + +#pragma pack(1) +struct readback_data_format { +// readback values + uint8_t version = HEV_FORMAT_VERSION; + uint32_t timestamp = 0; + uint8_t data_type = DATA_TYPE::READBACK; + uint16_t duration_calibration = 0; + uint16_t duration_buff_purge = 0; + uint16_t duration_buff_flush = 0; + uint16_t duration_buff_prefill = 0; + uint16_t duration_buff_fill = 0; + uint16_t duration_buff_loaded = 0; + uint16_t duration_buff_pre_inhale = 0; + uint16_t duration_inhale = 0; + uint16_t duration_pause = 0; + uint16_t duration_exhale_fill = 0; + uint16_t duration_exhale = 0; + + uint8_t valve_air_in = 0; + uint8_t valve_o2_in = 0; + uint8_t valve_inhale = 0; + uint8_t valve_exhale = 0; + uint8_t valve_purge = 0; + uint8_t ventilation_mode = 0; + + uint8_t valve_inhale_percent = 0; + uint8_t valve_exhale_percent = 0; + uint8_t valve_air_in_enable = 0; + uint8_t valve_o2_in_enable = 0; + uint8_t valve_purge_enable = 0; + uint8_t inhale_trigger_enable = 0; + uint8_t exhale_trigger_enable = 0; + uint8_t peep = 0; + float inhale_exhate_ratio = 0.0; +}; +#pragma pack() + +#pragma pack(1) +struct cycle_data_format { +// per breath values + uint8_t version = HEV_FORMAT_VERSION; + uint32_t timestamp = 0; + uint8_t data_type = DATA_TYPE::CYCLE; + + float respiratory_rate = 0; + + float tidal_volume = 0; + float exhaled_tidal_volume = 0; + float inhaled_tidal_volume = 0; + + float minute_volume = 0; + float exhaled_minute_volume = 0; + float inhaled_minute_volume = 0; + + float lung_compliance = 0; + float static_compliance = 0; + + uint16_t inhalation_pressure = 0; + uint16_t peak_inspiratory_pressure = 0; + uint16_t plateau_pressure = 0; + uint16_t mean_airway_pressure = 0; + + uint8_t fi02_percent = 0; + + uint16_t apnea_index = 0; + uint16_t apnea_time = 0; + + uint8_t mandatory_breath = 0; +}; +#pragma pack() + + enum VALVE_STATES : bool { V_OPEN = HIGH, V_CLOSED = LOW diff --git a/arduino/hev_prototype_v1/src/main.cpp b/arduino/hev_prototype_v1/src/main.cpp index 4f1dbc2ad744f552464e511bc2270a0fedc1b1f4..070d79dc6474ca01d681c847ff78b50f4fdee1b4 100644 --- a/arduino/hev_prototype_v1/src/main.cpp +++ b/arduino/hev_prototype_v1/src/main.cpp @@ -105,9 +105,8 @@ void setup() pinMode(pin_buzzer, OUTPUT); pinMode(pin_button_0, INPUT); - while (!Serial) ; +// while (!Serial) ; comms.beginSerial(); - } void loop() @@ -164,8 +163,7 @@ void loop() uint32_t tnow = static_cast<uint32_t>(millis()); if(tnow - report_time > report_timeout) { - plSend.setType(PAYLOAD_TYPE::FASTDATA); - plSend.setFastData(&data); + plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&data), sizeof(data)); // data2.ventilation_mode = plSend.getSize(); comms.writePayload(plSend); report_time = tnow; @@ -177,11 +175,16 @@ void loop() // check any received payload if(comms.readPayload(plReceive)) { + if (plReceive.getType() == PAYLOAD_TYPE::CMD) { // apply received cmd to ui loop - ui_loop.doCommand(plReceive.getCmd()); - plReceive.setType(PAYLOAD_TYPE::UNSET); + cmd_format cmd; + memcpy(reinterpret_cast<void*>(&cmd), plReceive.getInformation(), plReceive.getSize()); + ui_loop.doCommand(&cmd); } + + // unset received type not to read it again + plReceive.setType(PAYLOAD_TYPE::UNSET); } // run value readings