Skip to content
Snippets Groups Projects
Unverified Commit df60b426 authored by svihra's avatar svihra Committed by GitHub
Browse files

Merge pull request #13 from svihra/master

payload transmission fixes
parents 8898bf87 e6d35330
Branches
No related merge requests found
......@@ -85,64 +85,67 @@ class payload {
public:
payload(payloadType type = payloadType::payloadUnset) {type_ = type; } //data_ = nullptr; cmd_ = nullptr; alarm_ = nullptr; }
payload(const payload &other) {
// unsetAll();
type_ = other.type_;
/*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; }
/*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; }
/*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; }
memcpy(& data_, &other. data_, sizeof( dataFormat));
memcpy(& cmd_, &other. cmd_, sizeof( cmdFormat));
memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));
}
payload& operator=(const payload& other) {
// unsetAll();
type_ = other.type_;
/*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; }
/*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; }
/*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; }
memcpy(& data_, &other. data_, sizeof( dataFormat));
memcpy(& cmd_, &other. cmd_, sizeof( cmdFormat));
memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));
return *this;
}
~payload() {;}//unsetData(); unsetAlarm(); unsetCmd();}
~payload() { unsetAll(); }
void setType(payloadType type) { type_ = type; }
payloadType getType() {return type_; }
// requires argument as new struct
void setData (dataFormat *data) { /*unsetAll(); */ type_ = payloadType::payloadData; /* data_ = new dataFormat( *data); }*/ memcpy(& data_, data, sizeof( dataFormat)); }
void setCmd (cmdFormat *cmd) { /*unsetAll(); */ type_ = payloadType::payloadCmd; /* cmd_ = new cmdFormat( *cmd); }*/ memcpy(& cmd_, cmd, sizeof( cmdFormat)); }
void setAlarm(alarmFormat *alarm) { /*unsetAll(); */ type_ = payloadType::payloadAlarm;/* alarm_ = new alarmFormat( *alarm); }*/ memcpy(&alarm_, alarm, sizeof(alarmFormat)); }
void setData (dataFormat *data) { type_ = payloadType::payloadData; memcpy(& data_, data, sizeof( dataFormat)); }
void setCmd (cmdFormat *cmd) { type_ = payloadType::payloadCmd; memcpy(& cmd_, cmd, sizeof( cmdFormat)); }
void setAlarm(alarmFormat *alarm) { type_ = payloadType::payloadAlarm; memcpy(&alarm_, alarm, sizeof(alarmFormat)); }
dataFormat *getData () {return &data_; }
cmdFormat *getCmd () {return &cmd_; }
// get pointers to particular payload types
dataFormat *getData () {return & data_; }
cmdFormat *getCmd () {return & cmd_; }
alarmFormat *getAlarm() {return &alarm_; }
// void unsetAll() { unsetData(); unsetAlarm(); unsetCmd(); type_ = payloadType::payloadUnset; }
// void unsetData() { if ( data_ != nullptr) { delete data_; data_ = nullptr; } }
// void unsetCmd() { if ( cmd_ != nullptr) { delete cmd_; cmd_ = nullptr; } }
// void unsetAlarm() { if (alarm_ != nullptr) { delete alarm_; alarm_ = nullptr; } }
void unsetAll() { unsetData(); unsetAlarm(); unsetCmd(); type_ = payloadType::payloadUnset; }
void unsetData() { memset(& data_, 0, sizeof( dataFormat)); }
void unsetCmd() { memset(& cmd_, 0, sizeof( cmdFormat)); }
void unsetAlarm() { memset(&alarm_, 0, sizeof(alarmFormat)); }
void setPayload(payloadType type, void* information) {
setType(type);
setInformation(information);
}
void setPayload(payloadType type, void* dt) {
switch (type) {
void setInformation(void* information) {
switch (type_) {
case payloadType::payloadData:
setData(reinterpret_cast<dataFormat*>(dt));
setData (reinterpret_cast< dataFormat*>(information));
break;
case payloadType::payloadCmd:
setCmd(reinterpret_cast<cmdFormat*>(dt));
setCmd (reinterpret_cast< cmdFormat*>(information));
break;
case payloadType::payloadAlarm:
setAlarm(reinterpret_cast<alarmFormat*>(dt));
setAlarm(reinterpret_cast<alarmFormat*>(information));
break;
default:
break;
}
}
// returns void pointer, in case you know what to do with data
// returns void pointer, in case you know what to do with data or dont care what the format is
void *getInformation() {
switch (type_) {
case payloadType::payloadData:
return reinterpret_cast<void*>(getData());
return reinterpret_cast<void*>(getData ());
case payloadType::payloadCmd:
return reinterpret_cast<void*>(getCmd());
return reinterpret_cast<void*>(getCmd ());
case payloadType::payloadAlarm:
return reinterpret_cast<void*>(getAlarm());
default:
......@@ -150,7 +153,8 @@ public:
}
}
uint8_t getInformationSize() {
// returns payload information size
uint8_t getSize() {
switch (type_) {
case payloadType::payloadData:
return static_cast<uint8_t>(sizeof( dataFormat));
......
......@@ -99,13 +99,13 @@ void commsControl::receiver() {
break;
case COMMS_CONTROL_ACK:
// received ACK
finishPacket(&type);
finishPacket(type);
break;
default:
uint8_t tmpSequenceReceive = (control >> 1 ) & 0x7F;
tmpSequenceReceive += 1;
// received DATA
if (receivePacket(&type)) {
if (receivePacket(type)) {
commsAck_->setAddress(commsTmp_.getAddress());
commsAck_->setSequenceReceive(tmpSequenceReceive);
sendPacket(commsAck_);
......@@ -155,16 +155,16 @@ bool commsControl::writePayload(payload &pl) {
return false;
}
RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(&type);
RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue = getQueue(type);
// add new entry to the queue
if (tmpQueue->isFull()) {
if (queue->isFull()) {
commsFormat *tmpCommsRm;
if (tmpQueue->pop(tmpCommsRm)) {
if (queue->pop(tmpCommsRm)) {
delete tmpCommsRm;
}
}
if (tmpQueue->push(tmpComms) ) {
if (queue->push(tmpComms) ) {
return true;
}
return false;
......@@ -258,46 +258,28 @@ void commsControl::resendPacket(RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING
// receiving anything of commsFormat
bool commsControl::receivePacket(payloadType *type) {
payload tmpPl = payload(*type);
void *tmpInformation = nullptr;
switch (*type) {
case payloadType::payloadData:
tmpInformation = reinterpret_cast<void*>(tmpPl.getData());
// tmpInformation = reinterpret_cast<void*>(new dataFormat);
break;
case payloadType::payloadCmd:
tmpInformation = reinterpret_cast<void*>(tmpPl.getCmd());
// tmpInformation = reinterpret_cast<void*>(new cmdFormat);
break;
case payloadType::payloadAlarm:
tmpInformation = reinterpret_cast<void*>(tmpPl.getAlarm());
// tmpInformation = reinterpret_cast<void*>(new alarmFormat);
break;
default:
break;
}
if (tmpInformation == nullptr) {
return false;
}
memcpy(tmpInformation, commsTmp_.getInformation(), commsTmp_.getInfoSize());
tmpPl.setPayload(*type, tmpInformation);
// remove first entry if RB is full
if (queueReceived_->isFull()) {
payload tmpPlRm;
if (queueReceived_->pop(tmpPlRm)) {
;
bool commsControl::receivePacket(payloadType &type) {
payloadTmp_.unsetAll();
payloadTmp_.setType(type);
void *tmpInformation = payloadTmp_.getInformation();
// if type is definet, copy information from comms to payload
if (tmpInformation != nullptr) {
memcpy(tmpInformation, commsTmp_.getInformation(), commsTmp_.getInfoSize());
// remove first entry if queue is full
if (queueReceived_->isFull()) {
payload tmpPlRm;
if (queueReceived_->pop(tmpPlRm)) {
;
}
}
return queueReceived_->push(payloadTmp_);
}
return queueReceived_->push(tmpPl);
return false;
}
// if FCS is ok, remove from queue
void commsControl::finishPacket(payloadType *type) {
void commsControl::finishPacket(payloadType &type) {
RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(type);
if (tmpQueue != nullptr && !tmpQueue->isEmpty()) {
......@@ -327,8 +309,8 @@ payloadType commsControl::getInfoType(uint8_t *address) {
}
// get link to queue according to packet format
RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *commsControl::getQueue(payloadType *type) {
switch (*type) {
RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *commsControl::getQueue(payloadType &type) {
switch (type) {
case payloadType::payloadAlarm:
return queueAlarm_;
case payloadType::payloadCmd:
......
......@@ -26,13 +26,13 @@ public:
void receiver();
private:
RingBuf<commsFormat *,CONST_MAX_SIZE_RB_SENDING> *getQueue(payloadType *type);
RingBuf<commsFormat *,CONST_MAX_SIZE_RB_SENDING> *getQueue(payloadType &type);
payloadType getInfoType(uint8_t *address);
void sendQueue (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue);
void resendPacket (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue);
bool receivePacket(payloadType *type);
void finishPacket (payloadType *type);
bool receivePacket(payloadType &type);
void finishPacket (payloadType &type);
bool encoder(uint8_t* payload, uint8_t dataSize);
bool decoder(uint8_t* payload, uint8_t dataStart, uint8_t dataStop);
......@@ -52,6 +52,7 @@ private:
RingBuf<payload, CONST_MAX_SIZE_RB_RECEIVING> *queueReceived_;
payload payloadTmp_;
commsFormat commsTmp_;
uint32_t baudrate_;
......
......@@ -94,17 +94,17 @@ void commsFormat::copyData(uint8_t* data, uint8_t dataSize) {
// STATIC METHODS
// TODO rewrite in a slightly better way using the enum
commsFormat* commsFormat::generateALARM(payload *pl) {
commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_ALARM);
commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_ALARM);
tmpComms->setInformation(pl);
return tmpComms;
}
commsFormat* commsFormat::generateCMD (payload *pl) {
commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_CMD );
commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_CMD );
tmpComms->setInformation(pl);
return tmpComms;
}
commsFormat* commsFormat::generateDATA (payload *pl) {
commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_DATA );
commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_DATA );
tmpComms->setInformation(pl);
return tmpComms;
}
......
......@@ -17,6 +17,7 @@ lib_deps =
5390 ; uCRC16Lib
5418 ; RingBuffer
build_flags = -fpermissive -I../common/include/
lib_extra_dirs = ../common/lib
[env:uno]
platform = atmelavr
......
......@@ -6,7 +6,7 @@ else {
}
INCLUDEPATH += "$${_PRO_FILE_PWD_}/include"
INCLUDEPATH += "$${_PRO_FILE_PWD_}/src"
INCLUDEPATH += "$${_PRO_FILE_PWD_}/lib/commsControl"
INCLUDEPATH += "$${_PRO_FILE_PWD_}/../common/lib/commsControl"
INCLUDEPATH += "$${_PRO_FILE_PWD_}/.pio/libdeps/uno/uCRC16Lib_ID5390/src"
INCLUDEPATH += "$${_PRO_FILE_PWD_}/.pio/libdeps/uno/RingBuffer_ID5418/src"
INCLUDEPATH += "$${HOMEDIR}/.platformio/packages/framework-arduino-avr/cores/arduino"
......@@ -31,9 +31,9 @@ DEFINES += "__AVR_ATmega328P__"
OTHER_FILES += platformio.ini
SOURCES += src/protocol.cpp \
lib/commsControl/commsControl.cpp \
lib/commsControl/commsFormat.cpp
../common/lib/commsControl/commsControl.cpp \
../common/lib/commsControl/commsFormat.cpp
HEADERS += lib/commsControl/commsConstants.h \
lib/commsControl/commsControl.h \
lib/commsControl/commsFormat.h
HEADERS += ../common/lib/commsControl/commsConstants.h \
../common/lib/commsControl/commsControl.h \
../common/lib/commsControl/commsFormat.h
......@@ -21,6 +21,11 @@ bool blue_ = false;
bool green_ = false;
bool red_ = false;
bool enabled_ = false;
uint32_t lastTime_ = 0;
uint32_t offset_ = 10;
// dirty function to switch one of the LEDs
void switchLED(int led) {
......@@ -76,23 +81,40 @@ void loop() {
}
previousState_ = currentState_;
}
// switchLED(LED_BLUE);
// counter increase on button press
// plSend_.getData()->fsm_state += 1;
// comms_.writePayload(plSend_);
if (enabled_ & (millis() > (lastTime_ + offset_)))
{
lastTime_ = millis();
plSend_.getData()->readback_valve_air_in = static_cast<uint8_t>((lastTime_ >> 24) & 0xFF);
plSend_.getData()->readback_valve_o2_in = static_cast<uint8_t>((lastTime_ >> 16) & 0xFF);
plSend_.getData()->readback_valve_inhale = static_cast<uint8_t>((lastTime_ >> 8 ) & 0xFF);
plSend_.getData()->readback_valve_exhale = static_cast<uint8_t>((lastTime_ >> 0 ) & 0xFF);
switchLED(LED_BLUE);
plSend_.setType(payloadType::payloadData);
plSend_.getData()->fsm_state += 1;
comms_.writePayload(plSend_);
}
// per cycle sender
comms_.sender();
// per cycle receiver
comms_.receiver();
// per cycle data checker - the received entry is automatically removed from the buffer
if (comms_.readPayload(plReceive_)) {
switch (plReceive_.getType()) {
case payloadType::payloadCmd:
switchLED(plReceive_.getCmd()->cmdCode);
alarm_.alarmCode = plReceive_.getCmd()->cmdCode + 1;
if (plReceive_.getCmd()->cmdCode % 2 == 0) {
enabled_ = false;
} else {
enabled_ = true;
}
offset_ = plReceive_.getCmd()->param;
alarm_.alarmCode = plReceive_.getCmd()->cmdCode;
alarm_.param = millis() & 0xFFFFFFFF;
plSend_.setAlarm(&alarm_);
comms_.writePayload(plSend_);
break;
......@@ -102,5 +124,4 @@ void loop() {
plReceive_.setType(payloadType::payloadUnset);
}
delay(50);
}
......@@ -59,7 +59,7 @@ class dataFormat(BaseFormat):
# < = little endian
# > = big endian
# ! = network format (big endian)
self._dataStruct = Struct("!BBHHHHHHHHHBBBBBB")
self._dataStruct = Struct("<BBHHHHHHHHHBBBBBB")
self._byteArray = None
self._type = payloadType.payloadData
......@@ -184,7 +184,7 @@ class dataFormat(BaseFormat):
class commandFormat(BaseFormat):
def __init__(self):
super().__init__()
self._dataStruct = Struct("!BBI")
self._dataStruct = Struct("<BBI")
self._byteArray = None
self._type = payloadType.payloadCmd
......@@ -231,7 +231,7 @@ class command_codes(Enum):
class alarmFormat(BaseFormat):
def __init__(self):
super().__init__()
self._dataStruct = Struct("!BBI")
self._dataStruct = Struct("<BBI")
self._byteArray = None
self._type = payloadType.payloadAlarm
......
......@@ -15,7 +15,7 @@ from collections import deque
import binascii
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# communication class that governs talking between devices
......@@ -44,21 +44,19 @@ class commsControl():
self._sequenceReceive = 0
# initialize of the multithreading
self._lock = threading.Lock()
self._lockSerial = threading.Lock()
self._receiving = True
receivingWorker = threading.Thread(target=self.receiver, daemon=True)
receivingWorker.start()
threading.Thread(target=self.receiver, daemon=True).start()
self._sending = True
self._datavalid = threading.Event() # callback for send process
self._dvlock = threading.Lock() # make callback threadsafe
sendingWorker = threading.Thread(target=self.sender, daemon=True)
sendingWorker.start()
threading.Thread(target=self.sender, daemon=True).start()
# open serial port
def openSerial(self, port, baudrate = 115200, timeout = 2):
if port is not None:
self._serial = serial.Serial(port = port, baudrate=baudrate, timeout = timeout)
self._serial = serial.Serial(port = port, baudrate=baudrate, timeout = timeout, dsrdtr = True)
else:
try:
self._serial.close()
......@@ -74,14 +72,21 @@ class commsControl():
self.sendQueue(self._alarms , 10)
self.sendQueue(self._commands, 50)
self.sendQueue(self._data , 200)
with self._dvlock:
self._datavalid.clear()
if self.finishedSending():
with self._dvlock:
self._datavalid.clear()
def finishedSending(self):
if (len(self._alarms) + len(self._data) + len(self._commands)) > 0:
return False
else:
return True
def receiver(self):
while self._receiving:
if self._serial is not None:
if self._serial.in_waiting > 0:
with self._lock:
with self._lockSerial:
logging.debug("Receiving data...")
data = self._serial.read(self._serial.in_waiting)
self.processPacket(data)
......@@ -91,7 +96,7 @@ class commsControl():
logging.debug(f'Queue length: {len(queue)}')
currentTime = int(round(time.time() * 1000))
if currentTime > (self._timeLastTransmission + timeout):
with self._lock:
with self._lockSerial:
self._timeLastTransmission = currentTime
queue[0].setSequenceSend(self._sequenceSend)
self.sendPacket(queue[0])
......@@ -154,8 +159,6 @@ class commsControl():
else:
sequenceReceive = ((control >> 1) & 0x7F) + 1
address = tmpComms.getData()[tmpComms.getAddress():tmpComms.getControl()]
#payload = tmpComms.getData()[tmpComms.getInformation() : tmpComms.getFcs()]
if self.receivePacket(payloadType, tmpComms):
logging.debug("Preparing ACK")
......@@ -169,7 +172,7 @@ class commsControl():
self._received.clear()
self._foundStart = False
self._receivedStart = -1
self._receivedStart = -1
def writePayload(self, payload):
payloadType = payload.getType()
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment