mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-21 12:31:19 +02:00
works
This commit is contained in:
parent
25c01e0ca4
commit
495c9407a8
@ -75,7 +75,6 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
_currentMicros = currentMicros;
|
||||
if (_currentNode == NULL) _currentNode = _nodeListStart;
|
||||
if (!hasTasks() && _currentNode->isInitialised()) {
|
||||
_cycleStartTime = _currentMicros;
|
||||
uint8_t buffA[3];
|
||||
buffA[0] = (_currentNode->getNodeID());
|
||||
buffA[1] = (0);
|
||||
@ -87,38 +86,24 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
buffB[2] = (EXIORDAN);
|
||||
addTask(buffB, 3, EXIORDAN);
|
||||
_currentNode = _currentNode->getNext();
|
||||
DIAG(F("Polling"));
|
||||
//DIAG(F("Polling"));
|
||||
}
|
||||
|
||||
if ( hasTasks()){
|
||||
_cycleStartTimeA = _currentMicros;
|
||||
if (CurrentTaskID == -1) {
|
||||
CurrentTaskID = 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 == nullptr) return;
|
||||
|
||||
|
||||
|
||||
if (!currentTask->rxMode) { // Check if a task was found
|
||||
currentTask->crcPassFail = 0;
|
||||
uint16_t response_crc = crc16((uint8_t*)currentTask->commandArray, currentTask->byteCount-1);
|
||||
if (_txPin != -1) digitalWrite(_txPin,HIGH);
|
||||
//delayUntil(_currentMicros+10000UL);
|
||||
|
||||
ArduinoPins::fastWriteDigital(_txPin,HIGH);
|
||||
// Send response data with CRC
|
||||
_serial->write(0xFE);
|
||||
_serial->write(0xFE);
|
||||
@ -131,18 +116,13 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
_serial->write(0xFD);
|
||||
_serial->write(0xFD);
|
||||
_serial->flush();
|
||||
if (_txPin != -1) digitalWrite(_txPin,LOW);
|
||||
ArduinoPins::fastWriteDigital(_txPin,LOW);
|
||||
// delete task command after sending, for now
|
||||
currentTask->rxMode = true;
|
||||
DIAG(F("Task"));
|
||||
//DIAG(F("Task %d"), currentTask->taskID);
|
||||
|
||||
} else {
|
||||
if ( _serial->available()) {
|
||||
|
||||
|
||||
uint16_t calculated_crc;
|
||||
int byteCount = 100;
|
||||
|
||||
int curByte = _serial->read();
|
||||
|
||||
if (curByte == 0xFE && flagStart == false) flagStart = true;
|
||||
@ -188,6 +168,7 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// Check CRC validity
|
||||
if (crcPass) {
|
||||
// Data received successfully, process it (e.g., print)
|
||||
@ -199,6 +180,7 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
}
|
||||
|
||||
if (flagProc) {
|
||||
crcPass = false;
|
||||
int nodeFr = received_data[1];
|
||||
EXIO485node *node = findNode(nodeFr);
|
||||
int AddrCode = received_data[2];
|
||||
@ -235,52 +217,61 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
||||
}
|
||||
}
|
||||
}
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
break;}
|
||||
case EXIOINITA: {
|
||||
for (int i = 0; i < node->getnumAnalogPins(); i++) {
|
||||
node->setanalogPinMap(received_data[i+3], i);
|
||||
}
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
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());
|
||||
DIAG(F("EX-IOExpander485: Found node %d v%d.%d.%d"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
|
||||
node->setInitialised();
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
break;
|
||||
}
|
||||
case EXIORDY: {
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
break;
|
||||
}
|
||||
case EXIOERR: {
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
|
||||
flagProc = false;
|
||||
break;
|
||||
}
|
||||
case EXIORDAN: {
|
||||
for (int i = 0; i < node->_numAnaloguePins; i++) {
|
||||
node->setanalogInputBuffer(received_data[i+3], i);
|
||||
}
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
break;
|
||||
}
|
||||
case EXIORDD: {
|
||||
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
|
||||
node->setdigitalInputStates(received_data[i+3], i);
|
||||
}
|
||||
markTaskCompleted(currentTask->taskID);
|
||||
markTaskCompleted(CurrentTaskID);
|
||||
flagProc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
flagProc = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,7 +353,6 @@ void EXIO485node::_begin() {
|
||||
buff[4] = ((_firstVpin & 0xFF));
|
||||
buff[5] = ((_firstVpin >> 8));
|
||||
EXIO485 *bus = EXIO485::findBus(0);
|
||||
bus->initTask();
|
||||
bus->setBusy();
|
||||
bus->addTask(buff, 6, EXIOINIT);
|
||||
|
||||
|
26
IO_EXIO485.h
26
IO_EXIO485.h
@ -22,13 +22,13 @@
|
||||
* EXIO485
|
||||
* =======
|
||||
* To define a EXIO485, example syntax:
|
||||
* EXIO485::create(busNo, serial, baud[, pin]);
|
||||
* EXIO485::create(busNo, serial, baud[, TxPin]);
|
||||
*
|
||||
* busNo = the Bus no of the instance. should = 0, unless more than one bus configured for some reason.
|
||||
* serial = serial port to be used (e.g. Serial3)
|
||||
* baud = baud rate (9600, 19200, 28800, 57600 or 115200)
|
||||
* cycletime = minimum time between successive updates/reads of a node in millisecs (default 500ms)
|
||||
* pin = pin number connected to EXIO485 module's DE and !RE terminals for half-duplex operation (default -1)
|
||||
* TxPin = pin number connected to EXIO485 module's DE and !RE terminals for half-duplex operation (default -1)
|
||||
* if omitted (default), hardware MUST support full-duplex opperation!
|
||||
*
|
||||
*
|
||||
@ -416,7 +416,7 @@ private:
|
||||
public:
|
||||
struct Task {
|
||||
static const int ARRAY_SIZE = 150;
|
||||
int taskID;
|
||||
long taskID;
|
||||
uint8_t commandArray[ARRAY_SIZE];
|
||||
int byteCount;
|
||||
uint8_t retFlag;
|
||||
@ -427,8 +427,8 @@ struct Task {
|
||||
bool processed;
|
||||
};
|
||||
static const int MAX_TASKS = 50;
|
||||
int taskIDCntr = 0;
|
||||
int CurrentTaskID = -1;
|
||||
long taskIDCntr = 1;
|
||||
long CurrentTaskID = -1;
|
||||
int taskResendCount = 0;
|
||||
Task taskBuffer[MAX_TASKS]; // Buffer to hold up to 100 tasks
|
||||
int currentTaskIndex = 0;
|
||||
@ -467,6 +467,9 @@ void addTask(const uint8_t* cmd, int byteCount, uint8_t retFlag) {
|
||||
taskBuffer[emptySlot].gotCallback = false;
|
||||
taskBuffer[emptySlot].completed = false;
|
||||
taskBuffer[emptySlot].processed = false;
|
||||
taskIDCntr++;
|
||||
if (taskIDCntr >= 5000000) taskIDCntr = 1;
|
||||
taskBuffer[emptySlot].taskID = taskIDCntr;
|
||||
currentTaskIndex = emptySlot;
|
||||
}
|
||||
bool hasTasks() {
|
||||
@ -487,7 +490,7 @@ Task* getTaskById(int id) {
|
||||
return nullptr; // Task not found
|
||||
}
|
||||
// Function to get the next task (optional)
|
||||
int getNextTaskId() {
|
||||
long getNextTaskId() {
|
||||
for (int i = 0; i < MAX_TASKS; i++) {
|
||||
if (!taskBuffer[i].completed) {
|
||||
return taskBuffer[i].taskID;
|
||||
@ -499,7 +502,9 @@ int getNextTaskId() {
|
||||
void markTaskCompleted(int id) {
|
||||
for (int i = 0; i < MAX_TASKS; i++) {
|
||||
if (taskBuffer[i].taskID == id) {
|
||||
taskBuffer[i].completed = true;
|
||||
taskBuffer[i].completed = true; // completed
|
||||
taskBuffer[i].taskID = -1; // unassigned
|
||||
CurrentTaskID = getNextTaskId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -512,13 +517,13 @@ bool rxStart = false;
|
||||
bool rxEnd = false;
|
||||
bool crcPass = false;
|
||||
bool flagProc = false;
|
||||
uint16_t calculated_crc;
|
||||
int byteCount = 100;
|
||||
uint8_t received_data[ARRAY_SIZE];
|
||||
uint16_t received_crc;
|
||||
uint8_t crc[2];
|
||||
uint16_t crc16(uint8_t *data, uint16_t length);
|
||||
void remove_nulls(char *str, int len);
|
||||
int getCharsLeft(char *str, char position);
|
||||
void parseRx(uint8_t * outArray, uint8_t retFlag);
|
||||
|
||||
// EX-IOExpander protocol flags
|
||||
enum {
|
||||
EXIOINIT = 0xE0, // Flag to initialise setup procedure
|
||||
@ -562,6 +567,7 @@ uint16_t crc16(uint8_t *data, uint16_t length);
|
||||
unsigned long taskCounter=0ul;
|
||||
// Device-specific initialisation
|
||||
void _begin() override {
|
||||
//initTask();
|
||||
_serial->begin(_baud, SERIAL_8N1);
|
||||
if (_txPin >0) {
|
||||
pinMode(_txPin, OUTPUT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user