1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-04-21 12:31:19 +02:00

compiles!

This commit is contained in:
travis-farmer 2024-12-15 16:36:02 -05:00
parent 2d1f4ca108
commit 0a6bc136b0
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 89 additions and 199 deletions

View File

@ -25,12 +25,15 @@ static const byte PAYLOAD_FALSE = 0;
static const byte PAYLOAD_NORMAL = 1; static const byte PAYLOAD_NORMAL = 1;
static const byte PAYLOAD_STRING = 2; static const byte PAYLOAD_STRING = 2;
taskBuffer * taskBuffer::first=NULL;
taskBuffer::taskBuffer(Stream * myserial) taskBuffer::taskBuffer(Stream * myserial)
{ {
// constructor serial = myserial;
next=first; next=first;
first=this; first=this;
serial = myserial; bufferLength=0;
inCommandPayload=PAYLOAD_FALSE;
} }
taskBuffer::~taskBuffer() taskBuffer::~taskBuffer()
@ -81,7 +84,7 @@ uint16_t taskBuffer::_calculateCrc(uint8_t *buf, uint16_t len) {
} }
void taskBuffer::doCommand(uint8_t *commandBuffer, int commandSize) { void taskBuffer::doCommand(uint8_t *commandBuffer, int commandSize) {
for (taskBuffer * t=first;t;t=t->next) t->doCommand2(nodeID,commandBuffer,commandSize); for (taskBuffer * t=first;t;t=t->next) t->doCommand2(commandBuffer,commandSize);
} }
void taskBuffer::doCommand2(uint8_t *commandBuffer, int commandSize) { void taskBuffer::doCommand2(uint8_t *commandBuffer, int commandSize) {
@ -100,7 +103,7 @@ void taskBuffer::doCommand2(uint8_t *commandBuffer, int commandSize) {
digitalWrite(_txPin,LOW); digitalWrite(_txPin,LOW);
} }
void taskBuffer::init(unsigned long baud, uint16_t cycleTimeMS, int8_t txPin) { void taskBuffer::init(unsigned long baud, int8_t txPin) {
#ifdef RS485_SERIAL #ifdef RS485_SERIAL
RS485_SERIAL.begin(baud, SERIAL_8N1); RS485_SERIAL.begin(baud, SERIAL_8N1);
new taskBuffer(&RS485_SERIAL); new taskBuffer(&RS485_SERIAL);
@ -175,8 +178,8 @@ void taskBuffer::parseOne(uint8_t *buf) {
if (toNode != 0) return; // not for master if (toNode != 0) return; // not for master
uint8_t fromNode = buf[1]; uint8_t fromNode = buf[1];
uint8_t opcode = buf[2]; uint8_t opcode = buf[2];
RSproto *bus = RSproto::findBus(0);
RSprotonode *node = RSprotonode::findNode(fromNode); RSprotonode *node = bus->findNode(fromNode);
switch (opcode) { switch (opcode) {
case EXIOPINS: case EXIOPINS:
{node->_numDigitalPins = buf[3]; {node->_numDigitalPins = buf[3];
@ -223,17 +226,20 @@ void taskBuffer::parseOne(uint8_t *buf) {
} }
} }
} }
node->resFlag = 1;
break;} break;}
case EXIOPINS: { case EXIOINITA: {
for (int i = 3; i < node->_numAnaloguePins; i++) { for (int i = 3; i < node->_numAnaloguePins; i++) {
node->_analoguePinMap[i] = buf[i]; node->_analoguePinMap[i] = buf[i];
} }
node->resFlag = 1;
break; break;
} }
case EXIOVER: { case EXIOVER: {
node->_majorVer = buf[3]; node->_majorVer = buf[3];
node->_minorVer = buf[4]; node->_minorVer = buf[4];
node->_patchVer = buf[5]; node->_patchVer = buf[5];
node->resFlag = 1;
break; break;
} }
case EXIORDY: { case EXIORDY: {
@ -248,12 +254,14 @@ void taskBuffer::parseOne(uint8_t *buf) {
for (int i = 3; i < (node->_numDigitalPins+7)/8; i++) { for (int i = 3; i < (node->_numDigitalPins+7)/8; i++) {
node->_digitalInputStates[i-3] = buf[i]; node->_digitalInputStates[i-3] = buf[i];
} }
node->resFlag = 1;
break; break;
} }
case EXIORDAN: { case EXIORDAN: {
for (int i = 3; i < node->_numAnaloguePins*2; i++) { for (int i = 3; i < node->_numAnaloguePins*2; i++) {
node->_analogueInputBuffer[i-3] = buf[i]; node->_analogueInputBuffer[i-3] = buf[i];
} }
node->resFlag = 1;
break; break;
} }
} }
@ -264,14 +272,11 @@ void taskBuffer::parseOne(uint8_t *buf) {
************************************************************/ ************************************************************/
// Constructor for RSproto // Constructor for RSproto
RSproto::RSproto(HardwareSerial &serial, unsigned long baud, uint16_t cycleTimeMS, int8_t txPin, int waitA) { RSproto::RSproto(unsigned long baud, int8_t txPin) {
_baud = baud; _baud = baud;
_serialD = &serial;
_txPin = txPin; _txPin = txPin;
_busNo = 0; _busNo = 0;
task->init(baud, cycleTimeMS, txPin); task->init(baud, txPin);
_cycleTime = cycleTimeMS * 1000UL; // convert from milliseconds to microseconds.
_waitA = waitA;
if (_waitA < 3) _waitA = 3; if (_waitA < 3) _waitA = 3;
// Add device to HAL device chain // Add device to HAL device chain
IODevice::addDevice(this); IODevice::addDevice(this);
@ -281,22 +286,6 @@ RSproto::RSproto(HardwareSerial &serial, unsigned long baud, uint16_t cycleTimeM
_busList = this; _busList = this;
} }
/* -= clearRxBuffer =-
//
// BLOCKING method to empty stray data in RX buffer
*/
void RSproto::clearRxBuffer() {
unsigned long startMicros = micros();
do {
if (_serialD->available() > 0) {
startMicros = micros();
_serialD->read();
}
} while (micros() - startMicros < _frameTimeout || !_serialD->available());
}
/* -= _loop =- /* -= _loop =-
// //
// Main loop function for RSproto. // Main loop function for RSproto.
@ -357,95 +346,56 @@ bool RSprotonode::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCoun
uint16_t pullup = params[0]; uint16_t pullup = params[0];
uint8_t outBuffer[6] = {EXIODPUP, pin, pullup}; uint8_t outBuffer[6] = {EXIODPUP, pin, pullup};
task->doCommand(outBuffer,3);
unsigned long startMillis = millis(); unsigned long startMillis = millis();
task->doCommand(outBuffer,3);
while (resFlag == 0 && millis() - startMillis < 500); // blocking for now while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
if (resFlag != 1) { if (resFlag != 1) {
DIAG(F("EX-IOExpander485 Vpin %u cannot be used as a digital input pin"), pin); DIAG(F("EX-IOExpander485 Vpin %u cannot be used as a digital input pin"), pin);
} }
resFlag = 0;
} }
int RSprotonode::_configureAnalogIn(VPIN vpin) { int RSprotonode::_configureAnalogIn(VPIN vpin) {
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
//RSproto *mainrs = RSproto::findBus(_busNo); //RSproto *mainrs = RSproto::findBus(_busNo);
uint8_t commandBuffer[5] = {(uint8_t) _nodeID, EXIOENAN, (uint8_t) pin}; uint8_t commandBuffer[5] = {EXIOENAN, (uint8_t) pin};
uint8_t responseBuffer[3];
bus->_busy = true;
bus->updateCrc(commandBuffer,3);
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, HIGH);
_serial->write(commandBuffer, 5);
_serial->write(initBuffer, 1);
_serial->flush();
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, LOW);
unsigned long startMillis = millis(); unsigned long startMillis = millis();
while (!_serial->available()) { task->doCommand(commandBuffer, 2);
if (millis() - startMillis > 500) return 0; while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
} if (resFlag != 1) {
uint16_t len = 0; DIAG(F("EX-IOExpander485 Vpin %u cannot be used as a digital input pin"), pin);
unsigned long startMicros = micros();
bool rxDone = false;
byte tmpByte;
len = _serial->readBytesUntil(0xFE,responseBuffer, 25);
bus->_busy = false;
if (true/*bus->crcGood(responseBuffer,sizeof(responseBuffer)-2)*/) {
if (!bus->testAndStripMasterFlag(responseBuffer)) DIAG(F("Foreign RSproto Device! no master flag from node %d"),_nodeID);
if (responseBuffer[0] != EXIORDY) {
DIAG(F("EX-IOExpander485: Vpin %u on node %d cannot be used as an analogue input pin"), (int) pin, (int) _nodeID);
}
} else {
DIAG(F("EX-IOExpander485 node %d CRC Error"), (int) _nodeID);
} }
resFlag = 0;
return false; return false;
} }
void RSprotonode::_begin() { void RSprotonode::_begin() {
uint8_t commandBuffer[4] = {EXIOINIT, (uint8_t)_nPins, (uint8_t)(_firstVpin & 0xFF), (uint8_t)(_firstVpin >> 8)};
commandBuffer[0] = _nodeID; unsigned long startMillis = millis();
commandBuffer[1] = EXIOINITA; task->doCommand(commandBuffer,4);
bus->updateCrc(commandBuffer,2); while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, HIGH); if (resFlag != 1) {
_serial->write(commandBuffer, 4); DIAG(F("EX-IOExpander485 Node:%d ERROR EXIOINIT"), _nodeID);
_serial->write(initBuffer, 1); }
_serial->flush(); resFlag = 0;
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, LOW); commandBuffer[0] = EXIOINITA;
startMillis = millis(); startMillis = millis();
while (!_serial->available()) { task->doCommand(commandBuffer,1);
if (millis() - startMillis >= 500) return; while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
if (resFlag != 1) {
DIAG(F("EX-IOExpander485 Node:%d ERROR EXIOINITA"), _nodeID);
} }
len = 0; resFlag = 0;
startMicros = micros(); commandBuffer[0] = EXIOVER;
rxDone = false;
len = _serial->readBytesUntil(0xFE,receiveBuffer, 25);
DIAG(F("rxcode:%d from node"),receiveBuffer[1]);
if (true/*bus->crcGood(receiveBuffer,sizeof(receiveBuffer)-2)*/) {
if (!bus->testAndStripMasterFlag(receiveBuffer)) DIAG(F("Foreign RSproto Device! no master flag from node %d"),_nodeID);
}
uint8_t versionBuffer[5];
commandBuffer[0] = _nodeID;
commandBuffer[1] = EXIOVER;
bus->updateCrc(commandBuffer,2);
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, HIGH);
_serial->write(commandBuffer, 4);
_serial->write(initBuffer, 1);
_serial->flush();
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, LOW);
startMillis = millis(); startMillis = millis();
while (!_serial->available()) { task->doCommand(commandBuffer,1);
if (millis() - startMillis >= 500) return; while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
} if (resFlag != 1) {
len = 0; DIAG(F("EX-IOExpander485 Node:%d ERROR EXIOVER"), _nodeID);
startMicros = micros(); } else DIAG(F("EX-IOExpander device found, Node:%d, Version v%d.%d.%d"), _nodeID, _majorVer, _minorVer, _patchVer);
rxDone = false; resFlag = 0;
len = _serial->readBytesUntil(0xFE,receiveBuffer, 25);
DIAG(F("rxcode:%d.%d.%d from node"),versionBuffer[1],versionBuffer[2],versionBuffer[3]);
if (true/*bus->crcGood(versionBuffer,sizeof(versionBuffer)-2)*/) {
if (!bus->testAndStripMasterFlag(versionBuffer)) DIAG(F("Foreign RSproto Device! no master flag from node %d"),_nodeID);
DIAG(F("EX-IOExpander485 device found, node:%d, Version v%d.%d.%d"), _nodeID, _majorVer, _minorVer, _patchVer);
}
#ifdef DIAG_IO #ifdef DIAG_IO
_display(); _display();
#endif #endif
@ -462,43 +412,18 @@ void RSprotonode::_write(VPIN vpin, int value) {
if (_deviceState == DEVSTATE_FAILED) return; if (_deviceState == DEVSTATE_FAILED) return;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
uint8_t digitalOutBuffer[6]; uint8_t digitalOutBuffer[6];
uint8_t responseBuffer[3];
digitalOutBuffer[0] = (uint8_t) _nodeID;
digitalOutBuffer[1] = EXIOWRD; digitalOutBuffer[1] = EXIOWRD;
digitalOutBuffer[2] = (uint8_t) pin; digitalOutBuffer[2] = (uint8_t) pin;
digitalOutBuffer[3] = (uint8_t) value; digitalOutBuffer[3] = (uint8_t) value;
bus->_busy = true;
bus->updateCrc(digitalOutBuffer,4);
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, HIGH);
_serial->write(digitalOutBuffer, 6);
_serial->write(initBuffer, 1);
_serial->flush();
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, LOW);
unsigned long startMillis = millis(); unsigned long startMillis = millis();
while (!_serial->available()) { task->doCommand(digitalOutBuffer,3);
if (millis() - startMillis >= 500) return; while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
} if (resFlag != 1) {
uint16_t len = 0; DIAG(F("EX-IOExpander485 Node:%d ERROR EXIOVER"), _nodeID);
unsigned long startMicros = micros();
bool rxDone = false;
byte tmpByte;
len = _serial->readBytesUntil(0xFE,responseBuffer, 25);
bus->_busy = false;
if (true/*bus->crcGood(responseBuffer,sizeof(responseBuffer)-2)*/) {
if (!testAndStripMasterFlag(responseBuffer)) DIAG(F("Foreign RSproto Device! no master flag from node %d"),_nodeID);
if (responseBuffer[0] != EXIORDY) {
DIAG(F("EX-IOExpander485 Vpin %u cannot be used as a digital output pin"), pin);
}
} else {
DIAG(F("EX-IOExpander485 node %d CRC Error"), _nodeID);
} }
resFlag = 0;
} }
bool RSprotonode::testAndStripMasterFlag(uint8_t *buf) {
if (buf[0] != 0xFF) return false; // why did we not get a master flag? bad node?
for (int i = 0; i < sizeof(buf)-1; i++) buf[i] = buf[i+1]; // shift array to begining
return true;
}
int RSprotonode::_readAnalogue(VPIN vpin) { int RSprotonode::_readAnalogue(VPIN vpin) {
if (_deviceState == DEVSTATE_FAILED) return 0; if (_deviceState == DEVSTATE_FAILED) return 0;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
@ -515,41 +440,19 @@ void RSprotonode::_write(VPIN vpin, int value) {
void RSprotonode::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) { void RSprotonode::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) {
uint8_t servoBuffer[7]; uint8_t servoBuffer[7];
uint8_t responseBuffer[1]; uint8_t responseBuffer[1];
if (_deviceState == DEVSTATE_FAILED) return;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
servoBuffer[0] = (uint8_t) _nodeID; servoBuffer[0] = EXIOWRAN;
servoBuffer[1] = EXIOWRAN; servoBuffer[1] = (uint8_t) pin;
servoBuffer[2] = (uint8_t) pin; servoBuffer[2] = (uint8_t) value & 0xFF;
servoBuffer[3] = (uint8_t) value & 0xFF; servoBuffer[3] = (uint8_t) value >> 8;
servoBuffer[4] = (uint8_t) value >> 8; servoBuffer[4] = (uint8_t) profile;
servoBuffer[5] = (uint8_t) profile; servoBuffer[5] = (uint8_t) duration & 0xFF;
servoBuffer[6] = (uint8_t) duration & 0xFF; servoBuffer[6] = (uint8_t) duration >> 8;
servoBuffer[7] = (uint8_t) duration >> 8;
bus->_busy = true;
bus->updateCrc(servoBuffer,8);
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, HIGH);
_serial->write(servoBuffer, 10);
_serial->write(initBuffer, 1);
_serial->flush();
if (bus->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(bus->_txPin, LOW);
unsigned long startMillis = millis(); unsigned long startMillis = millis();
while (!_serial->available()) { task->doCommand(servoBuffer,7);
if (millis() - startMillis >= 500) return; while (resFlag == 0 && millis() - startMillis < 500); // blocking for now
} if (resFlag != 1) {
uint16_t len = 0; DIAG(F("EX-IOExpander485 Node:%d ERROR EXIOVER"), _nodeID);
unsigned long startMicros = micros();
bool rxDone = false;
byte tmpByte;
len = _serial->readBytesUntil(0xFE,responseBuffer, 25);
bus->_busy = false;
if (!true/*bus->crcGood(responseBuffer,sizeof(responseBuffer)-2)*/) {
DIAG(F("EX-IOExpander485 node %d CRC Error"), (int) _nodeID);
//_deviceState = DEVSTATE_FAILED;
} else {
if (!bus->testAndStripMasterFlag(responseBuffer)) DIAG(F("Foreign RSproto Device! no master flag from node %d"),_nodeID);
if (responseBuffer[0] != EXIORDY) {
DIAG(F("EX-IOExpander485 Vpin %u cannot be used as a servo/PWM pin"), pin);
}
} }
resFlag = 0;
} }

View File

@ -99,7 +99,7 @@ public:
void updateCrc(uint8_t *crcBuf, uint8_t *buf, uint16_t len); void updateCrc(uint8_t *crcBuf, uint8_t *buf, uint16_t len);
bool crcGood(uint8_t *buf, uint16_t len); bool crcGood(uint8_t *buf, uint16_t len);
static void doCommand(uint8_t *commandBuffer=NULL, int commandSize=0); static void doCommand(uint8_t *commandBuffer=NULL, int commandSize=0);
static void init(unsigned long baud, uint16_t cycleTimeMS=500, int8_t txPin=-1); static void init(unsigned long baud, int8_t txPin=-1);
static void loop(); static void loop();
}; };
@ -140,8 +140,9 @@ private:
EXIOWRAN = 0xEA, // Flag we're sending an analogue write (PWM) EXIOWRAN = 0xEA, // Flag we're sending an analogue write (PWM)
EXIOERR = 0xEF, // Flag we've received an error EXIOERR = 0xEF, // Flag we've received an error
}; };
static RSprotonode *_nodeList;
public: public:
static RSprotonode *_nodeList;
enum ProfileType : int { enum ProfileType : int {
Instant = 0, // Moves immediately between positions (if duration not specified) Instant = 0, // Moves immediately between positions (if duration not specified)
UseDuration = 0, // Use specified duration UseDuration = 0, // Use specified duration
@ -182,13 +183,7 @@ public:
RSprotonode *getNext() { RSprotonode *getNext() {
return _next; return _next;
} }
static RSprotonode *findNode(uint8_t nodeID) {
for (RSprotonode *node = _nodeList; node != NULL; node = node->getNext()) {
if (node->getNodeID() == nodeID)
return node;
}
return NULL;
}
void setNext(RSprotonode *node) { void setNext(RSprotonode *node) {
_next = node; _next = node;
} }
@ -285,6 +280,10 @@ private:
} }
public: public:
static void create(unsigned long baud, int8_t txPin=-1) {
new RSproto(baud, txPin);
}
int _CommMode = 0; int _CommMode = 0;
int _opperation = 0; int _opperation = 0;
uint16_t _pullup; uint16_t _pullup;
@ -294,18 +293,6 @@ public:
unsigned long _baud; unsigned long _baud;
int taskCnt = 0; int taskCnt = 0;
uint8_t initBuffer[1] = {0xFE}; uint8_t initBuffer[1] = {0xFE};
bool testAndStripMasterFlag(uint8_t *buf) {
if (buf[0] != 0xFD) return false; // why did we not get a master flag? bad node?
for (int i = 0; i < sizeof(buf)-1; i++) buf[i] = buf[i+1]; // shift array to begining
return true;
}
void clearRxBuffer();
static void create(unsigned long baud, uint16_t cycleTimeMS=500, int8_t txPin=-1, int waitA=10) {
new RSproto(baud, cycleTimeMS, txPin, waitA);
}
// Device-specific initialisation // Device-specific initialisation
void _begin() override { void _begin() override {
@ -367,7 +354,7 @@ public:
} }
protected: protected:
RSproto(unsigned long baud, uint16_t cycleTimeMS, int8_t txPin, int waitA); RSproto(unsigned long baud, int8_t txPin);
public: public: