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;
|
_currentMicros = currentMicros;
|
||||||
if (_currentNode == NULL) _currentNode = _nodeListStart;
|
if (_currentNode == NULL) _currentNode = _nodeListStart;
|
||||||
if (!hasTasks() && _currentNode->isInitialised()) {
|
if (!hasTasks() && _currentNode->isInitialised()) {
|
||||||
_cycleStartTime = _currentMicros;
|
|
||||||
uint8_t buffA[3];
|
uint8_t buffA[3];
|
||||||
buffA[0] = (_currentNode->getNodeID());
|
buffA[0] = (_currentNode->getNodeID());
|
||||||
buffA[1] = (0);
|
buffA[1] = (0);
|
||||||
@ -87,38 +86,24 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
buffB[2] = (EXIORDAN);
|
buffB[2] = (EXIORDAN);
|
||||||
addTask(buffB, 3, EXIORDAN);
|
addTask(buffB, 3, EXIORDAN);
|
||||||
_currentNode = _currentNode->getNext();
|
_currentNode = _currentNode->getNext();
|
||||||
DIAG(F("Polling"));
|
//DIAG(F("Polling"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hasTasks()){
|
if ( hasTasks()){
|
||||||
_cycleStartTimeA = _currentMicros;
|
_cycleStartTimeA = _currentMicros;
|
||||||
if (CurrentTaskID == -1) {
|
if (CurrentTaskID == -1) CurrentTaskID = getNextTaskId();
|
||||||
CurrentTaskID = getNextTaskId();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Task* currentTask = getTaskById(CurrentTaskID);
|
Task* currentTask = getTaskById(CurrentTaskID);
|
||||||
if (_currentMicros - _cycleStartTime > 1000000UL) { // timout every 1000ms
|
//if (currentTask == nullptr) return;
|
||||||
_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);
|
||||||
if (_txPin != -1) digitalWrite(_txPin,HIGH);
|
//delayUntil(_currentMicros+10000UL);
|
||||||
|
|
||||||
|
ArduinoPins::fastWriteDigital(_txPin,HIGH);
|
||||||
// Send response data with CRC
|
// Send response data with CRC
|
||||||
_serial->write(0xFE);
|
_serial->write(0xFE);
|
||||||
_serial->write(0xFE);
|
_serial->write(0xFE);
|
||||||
@ -131,18 +116,13 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
_serial->write(0xFD);
|
_serial->write(0xFD);
|
||||||
_serial->write(0xFD);
|
_serial->write(0xFD);
|
||||||
_serial->flush();
|
_serial->flush();
|
||||||
if (_txPin != -1) digitalWrite(_txPin,LOW);
|
ArduinoPins::fastWriteDigital(_txPin,LOW);
|
||||||
// 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 %d"), currentTask->taskID);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ( _serial->available()) {
|
if ( _serial->available()) {
|
||||||
|
|
||||||
|
|
||||||
uint16_t calculated_crc;
|
|
||||||
int byteCount = 100;
|
|
||||||
|
|
||||||
int curByte = _serial->read();
|
int curByte = _serial->read();
|
||||||
|
|
||||||
if (curByte == 0xFE && flagStart == false) flagStart = true;
|
if (curByte == 0xFE && flagStart == false) flagStart = true;
|
||||||
@ -188,6 +168,7 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Check CRC validity
|
// Check CRC validity
|
||||||
if (crcPass) {
|
if (crcPass) {
|
||||||
// Data received successfully, process it (e.g., print)
|
// Data received successfully, process it (e.g., print)
|
||||||
@ -199,6 +180,7 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flagProc) {
|
if (flagProc) {
|
||||||
|
crcPass = false;
|
||||||
int nodeFr = received_data[1];
|
int nodeFr = received_data[1];
|
||||||
EXIO485node *node = findNode(nodeFr);
|
EXIO485node *node = findNode(nodeFr);
|
||||||
int AddrCode = received_data[2];
|
int AddrCode = received_data[2];
|
||||||
@ -235,52 +217,61 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;}
|
break;}
|
||||||
case EXIOINITA: {
|
case EXIOINITA: {
|
||||||
for (int i = 0; i < node->getnumAnalogPins(); i++) {
|
for (int i = 0; i < node->getnumAnalogPins(); i++) {
|
||||||
node->setanalogPinMap(received_data[i+3], i);
|
node->setanalogPinMap(received_data[i+3], i);
|
||||||
}
|
}
|
||||||
markTaskCompleted(currentTask->taskID);
|
|
||||||
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXIOVER: {
|
case EXIOVER: {
|
||||||
node->setMajVer(received_data[3]);
|
node->setMajVer(received_data[3]);
|
||||||
node->setMinVer(received_data[4]);
|
node->setMinVer(received_data[4]);
|
||||||
node->setPatVer(received_data[5]);
|
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();
|
node->setInitialised();
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXIORDY: {
|
case EXIORDY: {
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXIOERR: {
|
case EXIOERR: {
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
|
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXIORDAN: {
|
case EXIORDAN: {
|
||||||
for (int i = 0; i < node->_numAnaloguePins; i++) {
|
for (int i = 0; i < node->_numAnaloguePins; i++) {
|
||||||
node->setanalogInputBuffer(received_data[i+3], i);
|
node->setanalogInputBuffer(received_data[i+3], i);
|
||||||
}
|
}
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXIORDD: {
|
case EXIORDD: {
|
||||||
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
|
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
|
||||||
node->setdigitalInputStates(received_data[i+3], i);
|
node->setdigitalInputStates(received_data[i+3], i);
|
||||||
}
|
}
|
||||||
markTaskCompleted(currentTask->taskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
flagProc = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,7 +353,6 @@ void EXIO485node::_begin() {
|
|||||||
buff[4] = ((_firstVpin & 0xFF));
|
buff[4] = ((_firstVpin & 0xFF));
|
||||||
buff[5] = ((_firstVpin >> 8));
|
buff[5] = ((_firstVpin >> 8));
|
||||||
EXIO485 *bus = EXIO485::findBus(0);
|
EXIO485 *bus = EXIO485::findBus(0);
|
||||||
bus->initTask();
|
|
||||||
bus->setBusy();
|
bus->setBusy();
|
||||||
bus->addTask(buff, 6, EXIOINIT);
|
bus->addTask(buff, 6, EXIOINIT);
|
||||||
|
|
||||||
|
26
IO_EXIO485.h
26
IO_EXIO485.h
@ -22,13 +22,13 @@
|
|||||||
* EXIO485
|
* EXIO485
|
||||||
* =======
|
* =======
|
||||||
* To define a EXIO485, example syntax:
|
* 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.
|
* 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)
|
* serial = serial port to be used (e.g. Serial3)
|
||||||
* baud = baud rate (9600, 19200, 28800, 57600 or 115200)
|
* baud = baud rate (9600, 19200, 28800, 57600 or 115200)
|
||||||
* cycletime = minimum time between successive updates/reads of a node in millisecs (default 500ms)
|
* 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!
|
* if omitted (default), hardware MUST support full-duplex opperation!
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -416,7 +416,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
struct Task {
|
struct Task {
|
||||||
static const int ARRAY_SIZE = 150;
|
static const int ARRAY_SIZE = 150;
|
||||||
int taskID;
|
long taskID;
|
||||||
uint8_t commandArray[ARRAY_SIZE];
|
uint8_t commandArray[ARRAY_SIZE];
|
||||||
int byteCount;
|
int byteCount;
|
||||||
uint8_t retFlag;
|
uint8_t retFlag;
|
||||||
@ -427,8 +427,8 @@ struct Task {
|
|||||||
bool processed;
|
bool processed;
|
||||||
};
|
};
|
||||||
static const int MAX_TASKS = 50;
|
static const int MAX_TASKS = 50;
|
||||||
int taskIDCntr = 0;
|
long taskIDCntr = 1;
|
||||||
int CurrentTaskID = -1;
|
long CurrentTaskID = -1;
|
||||||
int taskResendCount = 0;
|
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;
|
||||||
@ -467,6 +467,9 @@ void addTask(const uint8_t* cmd, int byteCount, uint8_t retFlag) {
|
|||||||
taskBuffer[emptySlot].gotCallback = false;
|
taskBuffer[emptySlot].gotCallback = false;
|
||||||
taskBuffer[emptySlot].completed = false;
|
taskBuffer[emptySlot].completed = false;
|
||||||
taskBuffer[emptySlot].processed = false;
|
taskBuffer[emptySlot].processed = false;
|
||||||
|
taskIDCntr++;
|
||||||
|
if (taskIDCntr >= 5000000) taskIDCntr = 1;
|
||||||
|
taskBuffer[emptySlot].taskID = taskIDCntr;
|
||||||
currentTaskIndex = emptySlot;
|
currentTaskIndex = emptySlot;
|
||||||
}
|
}
|
||||||
bool hasTasks() {
|
bool hasTasks() {
|
||||||
@ -487,7 +490,7 @@ Task* getTaskById(int id) {
|
|||||||
return nullptr; // Task not found
|
return nullptr; // Task not found
|
||||||
}
|
}
|
||||||
// Function to get the next task (optional)
|
// Function to get the next task (optional)
|
||||||
int getNextTaskId() {
|
long getNextTaskId() {
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
if (!taskBuffer[i].completed) {
|
if (!taskBuffer[i].completed) {
|
||||||
return taskBuffer[i].taskID;
|
return taskBuffer[i].taskID;
|
||||||
@ -499,7 +502,9 @@ int getNextTaskId() {
|
|||||||
void markTaskCompleted(int id) {
|
void markTaskCompleted(int id) {
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
if (taskBuffer[i].taskID == id) {
|
if (taskBuffer[i].taskID == id) {
|
||||||
taskBuffer[i].completed = true;
|
taskBuffer[i].completed = true; // completed
|
||||||
|
taskBuffer[i].taskID = -1; // unassigned
|
||||||
|
CurrentTaskID = getNextTaskId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -512,13 +517,13 @@ bool rxStart = false;
|
|||||||
bool rxEnd = false;
|
bool rxEnd = false;
|
||||||
bool crcPass = false;
|
bool crcPass = false;
|
||||||
bool flagProc = false;
|
bool flagProc = false;
|
||||||
|
uint16_t calculated_crc;
|
||||||
|
int byteCount = 100;
|
||||||
uint8_t received_data[ARRAY_SIZE];
|
uint8_t received_data[ARRAY_SIZE];
|
||||||
uint16_t received_crc;
|
uint16_t received_crc;
|
||||||
uint8_t crc[2];
|
uint8_t crc[2];
|
||||||
uint16_t crc16(uint8_t *data, uint16_t length);
|
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
|
// EX-IOExpander protocol flags
|
||||||
enum {
|
enum {
|
||||||
EXIOINIT = 0xE0, // Flag to initialise setup procedure
|
EXIOINIT = 0xE0, // Flag to initialise setup procedure
|
||||||
@ -562,6 +567,7 @@ uint16_t crc16(uint8_t *data, uint16_t length);
|
|||||||
unsigned long taskCounter=0ul;
|
unsigned long taskCounter=0ul;
|
||||||
// Device-specific initialisation
|
// Device-specific initialisation
|
||||||
void _begin() override {
|
void _begin() override {
|
||||||
|
//initTask();
|
||||||
_serial->begin(_baud, SERIAL_8N1);
|
_serial->begin(_baud, SERIAL_8N1);
|
||||||
if (_txPin >0) {
|
if (_txPin >0) {
|
||||||
pinMode(_txPin, OUTPUT);
|
pinMode(_txPin, OUTPUT);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user