From 25c01e0ca419d1c589ac9eff08c4d4b908c9d33b Mon Sep 17 00:00:00 2001 From: travis-farmer Date: Thu, 26 Dec 2024 17:21:02 -0500 Subject: [PATCH] update for better task handeling, untested --- IO_EXIO485.cpp | 298 ++++++++++++++++++++++++++----------------------- IO_EXIO485.h | 2 + 2 files changed, 162 insertions(+), 138 deletions(-) diff --git a/IO_EXIO485.cpp b/IO_EXIO485.cpp index 878736c..19a05a2 100644 --- a/IO_EXIO485.cpp +++ b/IO_EXIO485.cpp @@ -90,9 +90,31 @@ void EXIO485::_loop(unsigned long currentMicros) { DIAG(F("Polling")); } - if ( hasTasks() && _currentMicros - _cycleStartTimeA >= _cycleTime){ + if ( hasTasks()){ _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 currentTask->crcPassFail = 0; 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 currentTask->rxMode = true; DIAG(F("Task")); - markTaskCompleted(currentTask->taskID); - } - } - 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; - } - } + } 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; + - 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); - } - } + } + // 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 (node->getnumAnalogPins()>0) { - size_t analogueBytesNeeded = node->getnumAnalogPins() * 2; - if (node->getanalogPinBytes() < analogueBytesNeeded) { - // Free any existing buffers and allocate new ones. + } + + 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->cleanAnalogStates(analogueBytesNeeded)) { - node->setanalogPinBytes(analogueBytesNeeded); - } else { - DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr); - node->setanalogPinBytes(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; } - 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; + } } - flagProc = false; } - - // temp debug - - - - - } // Link to chain of EXIO485 instances, left over from EXIO485 template. diff --git a/IO_EXIO485.h b/IO_EXIO485.h index 7974fc5..9fc6eb2 100644 --- a/IO_EXIO485.h +++ b/IO_EXIO485.h @@ -428,6 +428,8 @@ struct Task { }; static const int MAX_TASKS = 50; int taskIDCntr = 0; + int CurrentTaskID = -1; + int taskResendCount = 0; Task taskBuffer[MAX_TASKS]; // Buffer to hold up to 100 tasks int currentTaskIndex = 0; void initTask() {