mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-21 12:31:19 +02:00
update for better task handeling, untested
This commit is contained in:
parent
51058a66f3
commit
25c01e0ca4
318
IO_EXIO485.cpp
318
IO_EXIO485.cpp
@ -90,9 +90,31 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
DIAG(F("Polling"));
|
DIAG(F("Polling"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hasTasks() && _currentMicros - _cycleStartTimeA >= _cycleTime){
|
if ( hasTasks()){
|
||||||
_cycleStartTimeA = _currentMicros;
|
_cycleStartTimeA = _currentMicros;
|
||||||
Task* currentTask = getTaskById(getNextTaskId());
|
if (CurrentTaskID == -1) {
|
||||||
|
CurrentTaskID = getNextTaskId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Task* currentTask = getTaskById(CurrentTaskID);
|
||||||
|
if (_currentMicros - _cycleStartTime > 1000000UL) { // timout every 1000ms
|
||||||
|
_cycleStartTime = _currentMicros;// reset timout
|
||||||
|
if (taskResendCount >= 2) { // max resends
|
||||||
|
markTaskCompleted(CurrentTaskID); // kill task and move on
|
||||||
|
CurrentTaskID = getNextTaskId(); // move on
|
||||||
|
taskResendCount = 0;
|
||||||
|
DIAG(F("Move on"));
|
||||||
|
} else {
|
||||||
|
currentTask->rxMode = false; // resend
|
||||||
|
taskResendCount++;
|
||||||
|
DIAG(F("Resend"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!currentTask->rxMode) { // Check if a task was found
|
if (!currentTask->rxMode) { // Check if a task was found
|
||||||
currentTask->crcPassFail = 0;
|
currentTask->crcPassFail = 0;
|
||||||
uint16_t response_crc = crc16((uint8_t*)currentTask->commandArray, currentTask->byteCount-1);
|
uint16_t response_crc = crc16((uint8_t*)currentTask->commandArray, currentTask->byteCount-1);
|
||||||
@ -113,154 +135,154 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
// delete task command after sending, for now
|
// delete task command after sending, for now
|
||||||
currentTask->rxMode = true;
|
currentTask->rxMode = true;
|
||||||
DIAG(F("Task"));
|
DIAG(F("Task"));
|
||||||
markTaskCompleted(currentTask->taskID);
|
|
||||||
|
} else {
|
||||||
|
if ( _serial->available()) {
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t calculated_crc;
|
||||||
|
int byteCount = 100;
|
||||||
|
|
||||||
|
int curByte = _serial->read();
|
||||||
|
|
||||||
|
if (curByte == 0xFE && flagStart == false) flagStart = true;
|
||||||
|
else if ( curByte == 0xFE && flagStart == true) {
|
||||||
|
flagProc = false;
|
||||||
|
byteCounter = 0;
|
||||||
|
flagStarted = true;
|
||||||
|
flagStart = false;
|
||||||
|
flagEnded = false;
|
||||||
|
rxStart = true;
|
||||||
|
rxEnd = false;
|
||||||
|
crcPass = false;
|
||||||
|
memset(received_data, 0, ARRAY_SIZE);
|
||||||
|
}else if (flagStarted) {
|
||||||
|
crc[0] = curByte;
|
||||||
|
byteCounter++;
|
||||||
|
flagStarted = false;
|
||||||
|
} else if (byteCounter == 1) {
|
||||||
|
crc[1] = curByte;
|
||||||
|
received_crc = (crc[0] << 8) | crc[1];
|
||||||
|
byteCounter++;
|
||||||
|
} else if (byteCounter == 2) {
|
||||||
|
byteCount = curByte;
|
||||||
|
byteCounter++;
|
||||||
|
} else if (flagEnded == false && byteCounter >= 3) {
|
||||||
|
received_data[byteCounter-3] = curByte;
|
||||||
|
byteCounter++;
|
||||||
|
}
|
||||||
|
if (curByte == 0xFD && flagEnd == false) flagEnd = true;
|
||||||
|
else if ( curByte == 0xFD && flagEnd == true) {
|
||||||
|
flagEnded = true;
|
||||||
|
flagEnd = false;
|
||||||
|
rxEnd = true;
|
||||||
|
byteCount = byteCounter;
|
||||||
|
byteCounter = 0;
|
||||||
|
}
|
||||||
|
if (flagEnded) {
|
||||||
|
calculated_crc = crc16((uint8_t*)received_data, byteCount-6);
|
||||||
|
if (received_crc == calculated_crc) {
|
||||||
|
crcPass = true;
|
||||||
|
}
|
||||||
|
flagEnded = false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// Check CRC validity
|
||||||
|
if (crcPass) {
|
||||||
|
// Data received successfully, process it (e.g., print)
|
||||||
|
int nodeTo = received_data[0];
|
||||||
|
if (nodeTo == 0) { // for master. master does not retransmit, or a loop will runaway.
|
||||||
|
flagProc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flagProc) {
|
||||||
|
int nodeFr = received_data[1];
|
||||||
|
EXIO485node *node = findNode(nodeFr);
|
||||||
|
int AddrCode = received_data[2];
|
||||||
|
|
||||||
|
switch (AddrCode) {
|
||||||
|
case EXIOPINS:
|
||||||
|
{node->setnumDigitalPins(received_data[3]);
|
||||||
|
node->setnumAnalogPins(received_data[4]);
|
||||||
|
|
||||||
|
// See if we already have suitable buffers assigned
|
||||||
|
if (node->getnumDigialPins()>0) {
|
||||||
|
size_t digitalBytesNeeded = (node->getnumDigialPins() + 7) / 8;
|
||||||
|
if (node->getdigitalPinBytes() < digitalBytesNeeded) {
|
||||||
|
// Not enough space, free any existing buffer and allocate a new one
|
||||||
|
if (node->cleandigitalPinStates(digitalBytesNeeded)) {
|
||||||
|
node->setdigitalPinBytes(digitalBytesNeeded);
|
||||||
|
} else {
|
||||||
|
DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded);
|
||||||
|
node->setdigitalPinBytes(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->getnumAnalogPins()>0) {
|
||||||
|
size_t analogueBytesNeeded = node->getnumAnalogPins() * 2;
|
||||||
|
if (node->getanalogPinBytes() < analogueBytesNeeded) {
|
||||||
|
// Free any existing buffers and allocate new ones.
|
||||||
|
|
||||||
|
if (node->cleanAnalogStates(analogueBytesNeeded)) {
|
||||||
|
node->setanalogPinBytes(analogueBytesNeeded);
|
||||||
|
} else {
|
||||||
|
DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr);
|
||||||
|
node->setanalogPinBytes(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;}
|
||||||
|
case EXIOINITA: {
|
||||||
|
for (int i = 0; i < node->getnumAnalogPins(); i++) {
|
||||||
|
node->setanalogPinMap(received_data[i+3], i);
|
||||||
|
}
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXIOVER: {
|
||||||
|
node->setMajVer(received_data[3]);
|
||||||
|
node->setMinVer(received_data[4]);
|
||||||
|
node->setPatVer(received_data[5]);
|
||||||
|
DIAG(F("EX-IOExpander485: Found node %i v%i.%i.%i"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
|
||||||
|
node->setInitialised();
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXIORDY: {
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXIOERR: {
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXIORDAN: {
|
||||||
|
for (int i = 0; i < node->_numAnaloguePins; i++) {
|
||||||
|
node->setanalogInputBuffer(received_data[i+3], i);
|
||||||
|
}
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXIORDD: {
|
||||||
|
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
|
||||||
|
node->setdigitalInputStates(received_data[i+3], i);
|
||||||
|
}
|
||||||
|
markTaskCompleted(currentTask->taskID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
flagProc = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( _serial->available()) {
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t calculated_crc;
|
|
||||||
int byteCount = 100;
|
|
||||||
|
|
||||||
int curByte = _serial->read();
|
|
||||||
|
|
||||||
if (curByte == 0xFE && flagStart == false) flagStart = true;
|
|
||||||
else if ( curByte == 0xFE && flagStart == true) {
|
|
||||||
flagProc = false;
|
|
||||||
byteCounter = 0;
|
|
||||||
flagStarted = true;
|
|
||||||
flagStart = false;
|
|
||||||
flagEnded = false;
|
|
||||||
rxStart = true;
|
|
||||||
rxEnd = false;
|
|
||||||
crcPass = false;
|
|
||||||
memset(received_data, 0, ARRAY_SIZE);
|
|
||||||
}else if (flagStarted) {
|
|
||||||
crc[0] = curByte;
|
|
||||||
byteCounter++;
|
|
||||||
flagStarted = false;
|
|
||||||
} else if (byteCounter == 1) {
|
|
||||||
crc[1] = curByte;
|
|
||||||
received_crc = (crc[0] << 8) | crc[1];
|
|
||||||
byteCounter++;
|
|
||||||
} else if (byteCounter == 2) {
|
|
||||||
byteCount = curByte;
|
|
||||||
byteCounter++;
|
|
||||||
} else if (flagEnded == false && byteCounter >= 3) {
|
|
||||||
received_data[byteCounter-3] = curByte;
|
|
||||||
byteCounter++;
|
|
||||||
}
|
|
||||||
if (curByte == 0xFD && flagEnd == false) flagEnd = true;
|
|
||||||
else if ( curByte == 0xFD && flagEnd == true) {
|
|
||||||
flagEnded = true;
|
|
||||||
flagEnd = false;
|
|
||||||
rxEnd = true;
|
|
||||||
byteCount = byteCounter;
|
|
||||||
byteCounter = 0;
|
|
||||||
}
|
|
||||||
if (flagEnded) {
|
|
||||||
calculated_crc = crc16((uint8_t*)received_data, byteCount-6);
|
|
||||||
if (received_crc == calculated_crc) {
|
|
||||||
crcPass = true;
|
|
||||||
}
|
|
||||||
flagEnded = false;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// Check CRC validity
|
|
||||||
if (crcPass) {
|
|
||||||
// Data received successfully, process it (e.g., print)
|
|
||||||
int nodeTo = received_data[0];
|
|
||||||
if (nodeTo == 0) { // for master. master does not retransmit, or a loop will runaway.
|
|
||||||
flagProc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flagProc) {
|
|
||||||
int nodeFr = received_data[1];
|
|
||||||
EXIO485node *node = findNode(nodeFr);
|
|
||||||
int AddrCode = received_data[2];
|
|
||||||
|
|
||||||
switch (AddrCode) {
|
|
||||||
case EXIOPINS:
|
|
||||||
{node->setnumDigitalPins(received_data[3]);
|
|
||||||
node->setnumAnalogPins(received_data[4]);
|
|
||||||
|
|
||||||
// See if we already have suitable buffers assigned
|
|
||||||
if (node->getnumDigialPins()>0) {
|
|
||||||
size_t digitalBytesNeeded = (node->getnumDigialPins() + 7) / 8;
|
|
||||||
if (node->getdigitalPinBytes() < digitalBytesNeeded) {
|
|
||||||
// Not enough space, free any existing buffer and allocate a new one
|
|
||||||
if (node->cleandigitalPinStates(digitalBytesNeeded)) {
|
|
||||||
node->setdigitalPinBytes(digitalBytesNeeded);
|
|
||||||
} else {
|
|
||||||
DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded);
|
|
||||||
node->setdigitalPinBytes(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->getnumAnalogPins()>0) {
|
|
||||||
size_t analogueBytesNeeded = node->getnumAnalogPins() * 2;
|
|
||||||
if (node->getanalogPinBytes() < analogueBytesNeeded) {
|
|
||||||
// Free any existing buffers and allocate new ones.
|
|
||||||
|
|
||||||
if (node->cleanAnalogStates(analogueBytesNeeded)) {
|
|
||||||
node->setanalogPinBytes(analogueBytesNeeded);
|
|
||||||
} else {
|
|
||||||
DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr);
|
|
||||||
node->setanalogPinBytes(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;}
|
|
||||||
case EXIOINITA: {
|
|
||||||
for (int i = 0; i < node->getnumAnalogPins(); i++) {
|
|
||||||
node->setanalogPinMap(received_data[i+3], i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXIOVER: {
|
|
||||||
node->setMajVer(received_data[3]);
|
|
||||||
node->setMinVer(received_data[4]);
|
|
||||||
node->setPatVer(received_data[5]);
|
|
||||||
DIAG(F("EX-IOExpander485: Found node %i v%i.%i.%i"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
|
|
||||||
node->setInitialised();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXIORDY: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXIOERR: {
|
|
||||||
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXIORDAN: {
|
|
||||||
for (int i = 0; i < node->_numAnaloguePins; i++) {
|
|
||||||
node->setanalogInputBuffer(received_data[i+3], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXIORDD: {
|
|
||||||
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
|
|
||||||
node->setdigitalInputStates(received_data[i+3], i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
flagProc = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// temp debug
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link to chain of EXIO485 instances, left over from EXIO485 template.
|
// Link to chain of EXIO485 instances, left over from EXIO485 template.
|
||||||
|
@ -428,6 +428,8 @@ struct Task {
|
|||||||
};
|
};
|
||||||
static const int MAX_TASKS = 50;
|
static const int MAX_TASKS = 50;
|
||||||
int taskIDCntr = 0;
|
int taskIDCntr = 0;
|
||||||
|
int CurrentTaskID = -1;
|
||||||
|
int taskResendCount = 0;
|
||||||
Task taskBuffer[MAX_TASKS]; // Buffer to hold up to 100 tasks
|
Task taskBuffer[MAX_TASKS]; // Buffer to hold up to 100 tasks
|
||||||
int currentTaskIndex = 0;
|
int currentTaskIndex = 0;
|
||||||
void initTask() {
|
void initTask() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user