mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-21 12:31:19 +02:00
code cleaned
This commit is contained in:
parent
495c9407a8
commit
23eb35290f
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* © 2024, Travis Farmer. All rights reserved.
|
* © 2024, Travis Farmer. All rights reserved.
|
||||||
* © 2021 Chris Harlow
|
|
||||||
*
|
*
|
||||||
* This file is part of DCC++EX API
|
* This file is part of DCC++EX API
|
||||||
*
|
*
|
||||||
@ -48,14 +47,7 @@ EXIO485::EXIO485(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8
|
|||||||
_busList = this;
|
_busList = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -= _loop =-
|
// CRC-16 implementation
|
||||||
//
|
|
||||||
// Main loop function for EXIO485.
|
|
||||||
// Work through list of nodes. For each node, in separate loop entries
|
|
||||||
// When the slot time has finished, move on to the next device.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// CRC-16 implementation (replace with your preferred CRC library if needed)
|
|
||||||
uint16_t EXIO485::crc16(uint8_t *data, uint16_t length) {
|
uint16_t EXIO485::crc16(uint8_t *data, uint16_t length) {
|
||||||
uint16_t crc = 0xFFFF;
|
uint16_t crc = 0xFFFF;
|
||||||
for (uint16_t i = 0; i < length; i++) {
|
for (uint16_t i = 0; i < length; i++) {
|
||||||
@ -71,10 +63,18 @@ uint16_t EXIO485::crc16(uint8_t *data, uint16_t length) {
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -= _loop =-
|
||||||
|
//
|
||||||
|
// Main loop function for EXIO485.
|
||||||
|
// Work through list of nodes. For each node, in separate loop entries
|
||||||
|
// When the slot time has finished, move on to the next device.
|
||||||
|
*/
|
||||||
|
|
||||||
void EXIO485::_loop(unsigned long currentMicros) {
|
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()) { // no tasks? lets poll for data
|
||||||
uint8_t buffA[3];
|
uint8_t buffA[3];
|
||||||
buffA[0] = (_currentNode->getNodeID());
|
buffA[0] = (_currentNode->getNodeID());
|
||||||
buffA[1] = (0);
|
buffA[1] = (0);
|
||||||
@ -86,24 +86,19 @@ 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"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hasTasks()){
|
if ( hasTasks()){ // do we have any tasks on the docket
|
||||||
_cycleStartTimeA = _currentMicros;
|
_cycleStartTimeA = _currentMicros;
|
||||||
if (CurrentTaskID == -1) CurrentTaskID = getNextTaskId();
|
if (CurrentTaskID == -1) CurrentTaskID = getNextTaskId();
|
||||||
|
|
||||||
Task* currentTask = getTaskById(CurrentTaskID);
|
Task* currentTask = getTaskById(CurrentTaskID);
|
||||||
//if (currentTask == nullptr) return;
|
|
||||||
|
|
||||||
|
if (!currentTask->rxMode) {
|
||||||
|
|
||||||
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);
|
||||||
//delayUntil(_currentMicros+10000UL);
|
|
||||||
|
|
||||||
ArduinoPins::fastWriteDigital(_txPin,HIGH);
|
if (_txPin != -1) 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);
|
||||||
@ -116,10 +111,9 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
_serial->write(0xFD);
|
_serial->write(0xFD);
|
||||||
_serial->write(0xFD);
|
_serial->write(0xFD);
|
||||||
_serial->flush();
|
_serial->flush();
|
||||||
ArduinoPins::fastWriteDigital(_txPin,LOW);
|
if (_txPin != -1) 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 %d"), currentTask->taskID);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ( _serial->available()) {
|
if ( _serial->available()) {
|
||||||
@ -165,18 +159,15 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
crcPass = true;
|
crcPass = true;
|
||||||
}
|
}
|
||||||
flagEnded = false;
|
flagEnded = false;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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)
|
||||||
int nodeTo = received_data[0];
|
int nodeTo = received_data[0];
|
||||||
if (nodeTo == 0) { // for master. master does not retransmit, or a loop will runaway.
|
if (nodeTo == 0) { // for master.
|
||||||
flagProc = true;
|
flagProc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flagProc) {
|
if (flagProc) {
|
||||||
@ -259,19 +250,15 @@ void EXIO485::_loop(unsigned long currentMicros) {
|
|||||||
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(CurrentTaskID);
|
markTaskCompleted(CurrentTaskID);
|
||||||
flagProc = false;
|
flagProc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
194
IO_EXIO485.h
194
IO_EXIO485.h
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* © 2024, Travis Farmer. All rights reserved.
|
* © 2024, Travis Farmer. All rights reserved.
|
||||||
* © 2021 Chris Harlow
|
|
||||||
*
|
*
|
||||||
* This file is part of DCC++EX API
|
* This file is part of DCC++EX API
|
||||||
*
|
*
|
||||||
@ -39,7 +38,7 @@
|
|||||||
*
|
*
|
||||||
* firstVPIN = first vpin in block allocated to this device
|
* firstVPIN = first vpin in block allocated to this device
|
||||||
* numVPINs = number of vpins
|
* numVPINs = number of vpins
|
||||||
* nodeID = 1-251
|
* nodeID = 1-252
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef IO_EXIO485_H
|
#ifndef IO_EXIO485_H
|
||||||
@ -382,7 +381,7 @@ private:
|
|||||||
byte bufferLength;
|
byte bufferLength;
|
||||||
static const int ARRAY_SIZE = 150;
|
static const int ARRAY_SIZE = 150;
|
||||||
int buffer[ARRAY_SIZE];
|
int buffer[ARRAY_SIZE];
|
||||||
byte inCommandPayload;
|
byte inCommandPayload;
|
||||||
static EXIO485 *_busList; // linked list of defined bus instances
|
static EXIO485 *_busList; // linked list of defined bus instances
|
||||||
bool waitReceive = false;
|
bool waitReceive = false;
|
||||||
int _waitCounter = 0;
|
int _waitCounter = 0;
|
||||||
@ -406,12 +405,6 @@ private:
|
|||||||
uint16_t _receiveDataIndex = 0; // Index of next data byte to be received.
|
uint16_t _receiveDataIndex = 0; // Index of next data byte to be received.
|
||||||
EXIO485 *_nextBus = NULL; // Pointer to next bus instance in list.
|
EXIO485 *_nextBus = NULL; // Pointer to next bus instance in list.
|
||||||
|
|
||||||
// Helper function for error handling
|
|
||||||
void reportError(uint8_t status, bool fail=true) {
|
|
||||||
DIAG(F("EX-IOExpander485 Node:%d Error"), _currentNode->getNodeID());
|
|
||||||
if (fail)
|
|
||||||
_deviceState = DEVSTATE_FAILED;
|
|
||||||
}
|
|
||||||
int byteCounter = 0;
|
int byteCounter = 0;
|
||||||
public:
|
public:
|
||||||
struct Task {
|
struct Task {
|
||||||
@ -426,103 +419,91 @@ struct Task {
|
|||||||
bool completed;
|
bool completed;
|
||||||
bool processed;
|
bool processed;
|
||||||
};
|
};
|
||||||
static const int MAX_TASKS = 50;
|
static const int MAX_TASKS = 50;
|
||||||
long taskIDCntr = 1;
|
long taskIDCntr = 1;
|
||||||
long 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;
|
||||||
void initTask() {
|
|
||||||
for (int i = 0; i <MAX_TASKS; i++) {
|
void addTask(const uint8_t* cmd, int byteCount, uint8_t retFlag) {
|
||||||
taskBuffer[i].completed = true;
|
// Find an empty slot in the buffer
|
||||||
taskBuffer[i].processed = false;
|
int emptySlot = -1;
|
||||||
taskBuffer[i].byteCount = 0;
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
taskBuffer[i].crcPassFail = 0;
|
if (taskBuffer[i].completed) {
|
||||||
taskBuffer[i].gotCallback = false;
|
emptySlot = i;
|
||||||
taskBuffer[i].retFlag = 0;
|
break;
|
||||||
taskBuffer[i].rxMode = false;
|
}
|
||||||
taskBuffer[i].taskID = i;
|
}
|
||||||
memset(taskBuffer[i].commandArray,0,ARRAY_SIZE);
|
// If no empty slot found, return (buffer full)
|
||||||
|
if (emptySlot == -1) {
|
||||||
|
DIAG(F("Task Buffer Full!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < byteCount; i++) taskBuffer[emptySlot].commandArray[i] = cmd[i];
|
||||||
|
taskBuffer[emptySlot].byteCount = byteCount;
|
||||||
|
taskBuffer[emptySlot].retFlag = retFlag;
|
||||||
|
taskBuffer[emptySlot].rxMode = false;
|
||||||
|
taskBuffer[emptySlot].crcPassFail = 0;
|
||||||
|
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() {
|
||||||
void addTask(const uint8_t* cmd, int byteCount, uint8_t retFlag) {
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
// Find an empty slot in the buffer
|
if (!taskBuffer[i].completed) {
|
||||||
int emptySlot = -1;
|
return true; // At least one task is not completed
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
}
|
||||||
if (taskBuffer[i].completed) {
|
}
|
||||||
emptySlot = i;
|
return false; // All tasks are completed
|
||||||
break;
|
}
|
||||||
|
// Function to get a specific task by ID
|
||||||
|
Task* getTaskById(int id) {
|
||||||
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
|
if (taskBuffer[i].taskID == id) {
|
||||||
|
return &taskBuffer[i]; // Return a pointer to the task
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr; // Task not found
|
||||||
|
}
|
||||||
|
// Function to get the next task (optional)
|
||||||
|
long getNextTaskId() {
|
||||||
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
|
if (!taskBuffer[i].completed) {
|
||||||
|
return taskBuffer[i].taskID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // No tasks available
|
||||||
|
}
|
||||||
|
// Function to mark a task as completed
|
||||||
|
void markTaskCompleted(int id) {
|
||||||
|
for (int i = 0; i < MAX_TASKS; i++) {
|
||||||
|
if (taskBuffer[i].taskID == id) {
|
||||||
|
taskBuffer[i].completed = true; // completed
|
||||||
|
taskBuffer[i].taskID = -1; // unassigned
|
||||||
|
CurrentTaskID = getNextTaskId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If no empty slot found, return (buffer full)
|
bool flagEnd = false;
|
||||||
if (emptySlot == -1) {
|
bool flagEnded = false;
|
||||||
DIAG(F("Task Buffer Full!"));
|
bool flagStart = false;
|
||||||
return;
|
bool flagStarted = false;
|
||||||
}
|
bool rxStart = false;
|
||||||
for (int i = 0; i < byteCount; i++) taskBuffer[emptySlot].commandArray[i] = cmd[i];
|
bool rxEnd = false;
|
||||||
taskBuffer[emptySlot].byteCount = byteCount;
|
bool crcPass = false;
|
||||||
taskBuffer[emptySlot].retFlag = retFlag;
|
bool flagProc = false;
|
||||||
taskBuffer[emptySlot].rxMode = false;
|
uint16_t calculated_crc;
|
||||||
taskBuffer[emptySlot].crcPassFail = 0;
|
int byteCount = 100;
|
||||||
taskBuffer[emptySlot].gotCallback = false;
|
uint8_t received_data[ARRAY_SIZE];
|
||||||
taskBuffer[emptySlot].completed = false;
|
uint16_t received_crc;
|
||||||
taskBuffer[emptySlot].processed = false;
|
uint8_t crc[2];
|
||||||
taskIDCntr++;
|
uint16_t crc16(uint8_t *data, uint16_t length);
|
||||||
if (taskIDCntr >= 5000000) taskIDCntr = 1;
|
|
||||||
taskBuffer[emptySlot].taskID = taskIDCntr;
|
|
||||||
currentTaskIndex = emptySlot;
|
|
||||||
}
|
|
||||||
bool hasTasks() {
|
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
|
||||||
if (!taskBuffer[i].completed) {
|
|
||||||
return true; // At least one task is not completed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false; // All tasks are completed
|
|
||||||
}
|
|
||||||
// Function to get a specific task by ID
|
|
||||||
Task* getTaskById(int id) {
|
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
|
||||||
if (taskBuffer[i].taskID == id) {
|
|
||||||
return &taskBuffer[i]; // Return a pointer to the task
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr; // Task not found
|
|
||||||
}
|
|
||||||
// Function to get the next task (optional)
|
|
||||||
long getNextTaskId() {
|
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
|
||||||
if (!taskBuffer[i].completed) {
|
|
||||||
return taskBuffer[i].taskID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; // No tasks available
|
|
||||||
}
|
|
||||||
// Function to mark a task as completed
|
|
||||||
void markTaskCompleted(int id) {
|
|
||||||
for (int i = 0; i < MAX_TASKS; i++) {
|
|
||||||
if (taskBuffer[i].taskID == id) {
|
|
||||||
taskBuffer[i].completed = true; // completed
|
|
||||||
taskBuffer[i].taskID = -1; // unassigned
|
|
||||||
CurrentTaskID = getNextTaskId();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool flagEnd = false;
|
|
||||||
bool flagEnded = false;
|
|
||||||
bool flagStart = false;
|
|
||||||
bool flagStarted = false;
|
|
||||||
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);
|
|
||||||
|
|
||||||
// EX-IOExpander protocol flags
|
// EX-IOExpander protocol flags
|
||||||
enum {
|
enum {
|
||||||
@ -567,25 +548,12 @@ 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);
|
||||||
digitalWrite(_txPin, LOW);
|
digitalWrite(_txPin, LOW);
|
||||||
|
|
||||||
}
|
}
|
||||||
#if defined(EXIO485_STM_OK)
|
|
||||||
pinMode(EXIO485_STM_OK, OUTPUT);
|
|
||||||
ArduinoPins::fastWriteDigital(EXIO485_STM_OK,LOW);
|
|
||||||
#endif
|
|
||||||
#if defined(EXIO485_STM_FAIL)
|
|
||||||
pinMode(EXIO485_STM_FAIL, OUTPUT);
|
|
||||||
ArduinoPins::fastWriteDigital(EXIO485_STM_FAIL,LOW);
|
|
||||||
#endif
|
|
||||||
#if defined(EXIO485_STM_COMM)
|
|
||||||
pinMode(EXIO485_STM_COMM, OUTPUT);
|
|
||||||
ArduinoPins::fastWriteDigital(EXIO485_STM_COMM,LOW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(DIAG_IO)
|
#if defined(DIAG_IO)
|
||||||
_display();
|
_display();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user