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

rename driver class

This commit is contained in:
travis-farmer 2024-12-26 03:16:32 -05:00
parent 74cb0c12b0
commit 8a28cf1d21
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 193 additions and 140 deletions

View File

@ -18,7 +18,7 @@
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. * along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "IO_RSproto.h" #include "IO_EXIO485.h"
#include "defines.h" #include "defines.h"
static const byte PAYLOAD_FALSE = 0; static const byte PAYLOAD_FALSE = 0;
@ -27,11 +27,11 @@ static const byte PAYLOAD_STRING = 2;
/************************************************************ /************************************************************
* RSproto implementation * EXIO485 implementation
************************************************************/ ************************************************************/
// Constructor for RSproto // Constructor for EXIO485
RSproto::RSproto(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin, int cycleTime) { EXIO485::EXIO485(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin, int cycleTime) {
_serial = &serial; _serial = &serial;
_baud = baud; _baud = baud;
@ -43,20 +43,20 @@ RSproto::RSproto(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8
// Add device to HAL device chain // Add device to HAL device chain
IODevice::addDevice(this); IODevice::addDevice(this);
// Add bus to RSproto chain. // Add bus to EXIO485 chain.
_nextBus = _busList; _nextBus = _busList;
_busList = this; _busList = this;
} }
/* -= _loop =- /* -= _loop =-
// //
// Main loop function for RSproto. // Main loop function for EXIO485.
// Work through list of nodes. For each node, in separate loop entries // Work through list of nodes. For each node, in separate loop entries
// When the slot time has finished, move on to the next device. // When the slot time has finished, move on to the next device.
*/ */
// CRC-16 implementation (replace with your preferred CRC library if needed) // CRC-16 implementation (replace with your preferred CRC library if needed)
uint16_t RSproto::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++) {
crc ^= data[i]; crc ^= data[i];
@ -71,18 +71,8 @@ uint16_t RSproto::crc16(uint8_t *data, uint16_t length) {
return crc; return crc;
} }
void RSprotonode::_pollDigital(unsigned long currentMicros) { void EXIO485::_loop(unsigned long currentMicros) {
}
void RSprotonode::_pollAnalog(unsigned long currentMicros) {
RSproto *bus = RSproto::findBus(0);
}
void RSproto::_loop(unsigned long currentMicros) {
_currentMicros = currentMicros; _currentMicros = currentMicros;
//if (_busy == true) return;
if (_currentNode == NULL) _currentNode = _nodeListStart; if (_currentNode == NULL) _currentNode = _nodeListStart;
if (!hasTasks() && _currentNode->isInitialised()) { if (!hasTasks() && _currentNode->isInitialised()) {
_cycleStartTime = _currentMicros; _cycleStartTime = _currentMicros;
@ -96,12 +86,9 @@ void RSproto::_loop(unsigned long currentMicros) {
buffB[1] = (0); buffB[1] = (0);
buffB[2] = (EXIORDAN); buffB[2] = (EXIORDAN);
addTask(buffB, 3, EXIORDAN); addTask(buffB, 3, EXIORDAN);
//DIAG(F("Polling node: %i"), _currentNode->getNodeID());
_currentNode = _currentNode->getNext(); _currentNode = _currentNode->getNext();
} }
//if (currentTask == nullptr) return;
if ( hasTasks() && _currentMicros - _cycleStartTimeA >= _cycleTime){ if ( hasTasks() && _currentMicros - _cycleStartTimeA >= _cycleTime){
_cycleStartTimeA = _currentMicros; _cycleStartTimeA = _currentMicros;
Task* currentTask = getTaskById(getNextTaskId()); Task* currentTask = getTaskById(getNextTaskId());
@ -125,7 +112,6 @@ void RSproto::_loop(unsigned long currentMicros) {
// delete task command after sending, for now // delete task command after sending, for now
currentTask->rxMode = true; currentTask->rxMode = true;
//DIAG(F("Polling Task: %i"), currentTask->taskID);
markTaskCompleted(currentTask->taskID); markTaskCompleted(currentTask->taskID);
} }
} }
@ -174,11 +160,8 @@ void RSproto::_loop(unsigned long currentMicros) {
if (flagEnded) { if (flagEnded) {
calculated_crc = crc16((uint8_t*)received_data, byteCount-6); calculated_crc = crc16((uint8_t*)received_data, byteCount-6);
if (received_crc == calculated_crc) { if (received_crc == calculated_crc) {
//DIAG(F("Loop CRC PASS"));
crcPass = true; crcPass = true;
}else { }
//DIAG(F("Loop CRC Fail %x %x"),received_crc,calculated_crc);
}
flagEnded = false; flagEnded = false;
@ -191,18 +174,12 @@ void RSproto::_loop(unsigned long currentMicros) {
flagProc = true; flagProc = true;
} }
} else {
//DIAG(F("IO_RSproto: CRC Error!"));
} }
if (flagProc) { if (flagProc) {
int nodeTo = received_data[0];
int nodeFr = received_data[1]; int nodeFr = received_data[1];
RSprotonode *node = findNode(nodeFr); EXIO485node *node = findNode(nodeFr);
//DIAG(F("Node from %i %i"), nodeFr, node->getNodeID());
int AddrCode = received_data[2]; int AddrCode = received_data[2];
//DIAG(F("From: %i, To: %i | %i %i %i %i %i"), nodeFr,nodeTo, received_data[3], received_data[4], received_data[5], received_data[6],received_data[7]);
//return;
switch (AddrCode) { switch (AddrCode) {
case EXIOPINS: case EXIOPINS:
@ -218,7 +195,6 @@ void RSproto::_loop(unsigned long currentMicros) {
node->setdigitalPinBytes(digitalBytesNeeded); node->setdigitalPinBytes(digitalBytesNeeded);
} else { } else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded); DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded);
//_deviceState = DEVSTATE_FAILED;
node->setdigitalPinBytes(0); node->setdigitalPinBytes(0);
} }
} }
@ -233,7 +209,6 @@ void RSproto::_loop(unsigned long currentMicros) {
node->setanalogPinBytes(analogueBytesNeeded); node->setanalogPinBytes(analogueBytesNeeded);
} else { } else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr); DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr);
//_deviceState = DEVSTATE_FAILED;
node->setanalogPinBytes(0); node->setanalogPinBytes(0);
} }
} }
@ -251,14 +226,13 @@ void RSproto::_loop(unsigned long currentMicros) {
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 %i v%i.%i.%i"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
node->setInitialised(); node->setInitialised();
//DIAG(F("EX-IOExpander485: Initialized Node:%d "), node->getNodeID());
break; break;
} }
case EXIORDY: { case EXIORDY: {
break; break;
} }
case EXIOERR: { case EXIOERR: {
DIAG(F("EX-IOExplorer485: Some sort of error was received... WHAT DID YOU DO!")); // ;-) DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
break; break;
} }
case EXIORDAN: { case EXIORDAN: {
@ -288,35 +262,33 @@ void RSproto::_loop(unsigned long currentMicros) {
} }
// Link to chain of RSproto instances, left over from RSproto template. // Link to chain of EXIO485 instances, left over from EXIO485 template.
RSproto *RSproto::_busList = NULL; EXIO485 *EXIO485::_busList = NULL;
/************************************************************ /************************************************************
* RSprotonode implementation * EXIO485node implementation
************************************************************/ ************************************************************/
/* -= RSprotonode =- /* -= EXIO485node =-
// //
// Constructor for RSprotonode object // Constructor for EXIO485node object
*/ */
RSprotonode::RSprotonode(VPIN firstVpin, int nPins, uint8_t nodeID) { EXIO485node::EXIO485node(VPIN firstVpin, int nPins, uint8_t nodeID) {
_firstVpin = firstVpin; _firstVpin = firstVpin;
_nPins = nPins; _nPins = nPins;
_busNo = 0; _busNo = 0;
_nodeID = nodeID; _nodeID = nodeID;
_initialised = false; _initialised = false;
memset(resFlag, 0, 255); memset(resFlag, 0, 255);
//bus = bus->findBus(0);
//_serial = bus->_serialD;
if (_nodeID > 252) _nodeID = 252; // cannot have a node with the frame flags if (_nodeID > 252) _nodeID = 252; // cannot have a node with the frame flags
if (_nodeID < 1) _nodeID = 1; // cannot have a node with the master ID if (_nodeID < 1) _nodeID = 1; // cannot have a node with the master ID
// Add this device to HAL device list // Add this device to HAL device list
IODevice::addDevice(this); IODevice::addDevice(this);
_display(); _display();
// Add RSprotonode to RSproto object. // Add EXIO485node to EXIO485 object.
RSproto *bus = RSproto::findBus(_busNo); EXIO485 *bus = EXIO485::findBus(_busNo);
if (bus != NULL) { if (bus != NULL) {
bus->addNode(this); bus->addNode(this);
return; return;
@ -324,7 +296,7 @@ RSprotonode::RSprotonode(VPIN firstVpin, int nPins, uint8_t nodeID) {
} }
bool RSprotonode::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCount, int params[]) { bool EXIO485node::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCount, int params[]) {
if (paramCount != 1) return false; if (paramCount != 1) return false;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
@ -335,33 +307,30 @@ bool RSprotonode::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCoun
buff[2] = (EXIODPUP); buff[2] = (EXIODPUP);
buff[3] = (pin); buff[3] = (pin);
buff[4] = (pullup); buff[4] = (pullup);
unsigned long startMillis = millis(); EXIO485 *bus = EXIO485::findBus(0);
RSproto *bus = RSproto::findBus(0);
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 5, EXIODPUP); bus->addTask(buff, 5, EXIODPUP);
return true; return true;
} }
int RSprotonode::_configureAnalogIn(VPIN vpin) { int EXIO485node::_configureAnalogIn(VPIN vpin) {
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
//RSproto *mainrs = RSproto::findBus(_busNo);
uint8_t buff[ARRAY_SIZE]; uint8_t buff[ARRAY_SIZE];
buff[0] = (_nodeID); buff[0] = (_nodeID);
buff[1] = (0); buff[1] = (0);
buff[2] = (EXIOENAN); buff[2] = (EXIOENAN);
buff[3] = (pin); buff[3] = (pin);
buff[4] = highByte(_firstVpin); buff[4] = lowByte(_firstVpin);
buff[5] = lowByte(_firstVpin); buff[5] = highByte(_firstVpin);
unsigned long startMillis = millis(); EXIO485 *bus = EXIO485::findBus(0);
RSproto *bus = RSproto::findBus(0);
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 6, EXIOENAN); bus->addTask(buff, 6, EXIOENAN);
return false; return false;
} }
void RSprotonode::_begin() { void EXIO485node::_begin() {
uint8_t buff[ARRAY_SIZE]; uint8_t buff[ARRAY_SIZE];
buff[0] = (_nodeID); buff[0] = (_nodeID);
buff[1] = (0); buff[1] = (0);
@ -369,8 +338,7 @@ void RSprotonode::_begin() {
buff[3] = (_nPins); buff[3] = (_nPins);
buff[4] = ((_firstVpin & 0xFF)); buff[4] = ((_firstVpin & 0xFF));
buff[5] = ((_firstVpin >> 8)); buff[5] = ((_firstVpin >> 8));
unsigned long startMillis = millis(); EXIO485 *bus = EXIO485::findBus(0);
RSproto *bus = RSproto::findBus(0);
bus->initTask(); bus->initTask();
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 6, EXIOINIT); bus->addTask(buff, 6, EXIOINIT);
@ -378,32 +346,28 @@ void RSprotonode::_begin() {
buff[0] = (_nodeID); buff[0] = (_nodeID);
buff[1] = (0); buff[1] = (0);
buff[2] = (EXIOINITA); buff[2] = (EXIOINITA);
startMillis = millis();
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 3, EXIOINITA); bus->addTask(buff, 3, EXIOINITA);
buff[0] = (_nodeID); buff[0] = (_nodeID);
buff[1] = (0); buff[1] = (0);
buff[2] = (EXIOVER); buff[2] = (EXIOVER);
startMillis = millis();
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 3, EXIOVER); bus->addTask(buff, 3, EXIOVER);
//setInitialised();
#ifdef DIAG_IO #ifdef DIAG_IO
_display(); _display();
#endif #endif
} }
int RSprotonode::_read(VPIN vpin) { int EXIO485node::_read(VPIN vpin) {
if (_deviceState == DEVSTATE_FAILED) return 0; if (_deviceState == DEVSTATE_FAILED) return 0;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
uint8_t pinByte = pin / 8; uint8_t pinByte = pin / 8;
bool value = bitRead(_digitalInputStates[pinByte], pin - pinByte * 8); bool value = bitRead(_digitalInputStates[pinByte], pin - pinByte * 8);
return value; return value;
} }
void RSprotonode::_write(VPIN vpin, int value) { void EXIO485node::_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 buff[ARRAY_SIZE]; uint8_t buff[ARRAY_SIZE];
@ -412,14 +376,13 @@ void RSprotonode::_write(VPIN vpin, int value) {
buff[2] = (EXIOWRD); buff[2] = (EXIOWRD);
buff[3] = (pin); buff[3] = (pin);
buff[4] = (value); buff[4] = (value);
unsigned long startMillis = millis(); EXIO485 *bus = EXIO485::findBus(0);
RSproto *bus = RSproto::findBus(0);
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 5, EXIOWRD); bus->addTask(buff, 5, EXIOWRD);
} }
int RSprotonode::_readAnalogue(VPIN vpin) { int EXIO485node::_readAnalogue(VPIN vpin) {
if (_deviceState == DEVSTATE_FAILED) return 0; if (_deviceState == DEVSTATE_FAILED) return 0;
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
for (uint8_t aPin = 0; aPin < _numAnaloguePins; aPin++) { for (uint8_t aPin = 0; aPin < _numAnaloguePins; aPin++) {
@ -432,20 +395,19 @@ void RSprotonode::_write(VPIN vpin, int value) {
return -1; // pin not found in table return -1; // pin not found in table
} }
void RSprotonode::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) { void EXIO485node::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) {
int pin = vpin - _firstVpin; int pin = vpin - _firstVpin;
uint8_t buff[ARRAY_SIZE]; uint8_t buff[ARRAY_SIZE];
buff[0] = (_nodeID); buff[0] = (_nodeID);
buff[1] = (0); buff[1] = (0);
buff[2] = (EXIOWRAN); buff[2] = (EXIOWRAN);
buff[3] = (pin); buff[3] = (pin);
buff[4] = highByte(value); buff[4] = lowByte(value);
buff[5] = lowByte(value); buff[5] = highByte(value);
buff[6] = (profile); buff[6] = (profile);
buff[7] = highByte(duration); buff[7] = lowByte(duration);
buff[8] = lowByte(duration); buff[8] = highByte(duration);
unsigned long startMillis = millis(); EXIO485 *bus = EXIO485::findBus(0);
RSproto *bus = RSproto::findBus(0);
bus->setBusy(); bus->setBusy();
bus->addTask(buff, 9, EXIOWRAN); bus->addTask(buff, 9, EXIOWRAN);

View File

@ -19,36 +19,36 @@
*/ */
/* /*
* RSproto * EXIO485
* ======= * =======
* To define a RSproto, example syntax: * To define a EXIO485, example syntax:
* RSproto::create(busNo, serial, baud[, pin]); * EXIO485::create(busNo, serial, baud[, pin]);
* *
* 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 RSproto module's DE and !RE terminals for half-duplex operation (default -1) * pin = 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!
* *
* *
* RSprotoNode * EXIO485Node
* ======== * ========
* To define a RSproto node and associate it with a RSproto bus, * To define a EXIO485 node and associate it with a EXIO485 bus,
* RSprotonode::create(firstVPIN, numVPINs, nodeID); * EXIO485node::create(firstVPIN, numVPINs, nodeID);
* *
* 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-251
*/ */
#ifndef IO_RS485_H #ifndef IO_EXIO485_H
#define IO_RS485_H #define IO_EXIO485_H
#include "IODevice.h" #include "IODevice.h"
class RSproto; class EXIO485;
class RSprotonode; class EXIO485node;
@ -57,44 +57,137 @@ class RSprotonode;
#endif #endif
/********************************************************************** /**********************************************************************
* taskBuffer class * Data Structure
* *
* this stores the task list, and processes the data within it for
* sending. it also handles the incomming data responce.
* Data Frame: * Data Frame:
* 0xFD : toNode : fromNode : ~data packet~ : 0xFE * 0xFE : 0xFE : CRC : CRC : ByteCount : DataPacket : 0xFD : 0xFD
* Start: TO : FROM : DATA : End * --------------------------------------------------------------
* Start Frame : CRC Bytes : Data Size : Data : End Frame
* *
* Data frame must always start with the Start byte, follow with the * Data frame must always start with the Start Frame bytes (two Bytes),
* destination (toNode), follow with the Source (fromNode), contain * follow with the CRC bytes (two bytes), the data byte count
* the data packet, and follow with the End byte. * (one byte), the Data Packet (variable bytes), and the end Frame
* Bytes.
* *
* *
* Data Packet: * Data Packet:
* Command Byte : ~Command Params~ * NodeTo : NodeFrom : AddrCode : ~Command Params~
* -----------------------------------------------
* NodeTo = where the packet is destined for.
* NodeFrom = where the packet came from.
* Address Code = from EXIO enumeration.
* Command Params:
* *
* Data Packet must always precede the parameters with the Command byte. * EXIOINIT:TX CS
* this way the data is processed by the correct routine. * --------
* nPins : FirstPinL : FirstPinH
* -----------------------------
* nPins = Number of allocated pins.
* FirstPinL = First VPIN lowByte.
* FirstPinH = First VPIN highByte.
*
* Sends the allocated pins.
*
* EXIOINITA: Tx CS
* -=no parameters, just a header=-
*
* requests the analog pin map from the node.
*
* EXIOVER: Tx CS
* -=no parameters=-
*
* requests the node software version, but as yet to do anything with it
*
* EXIODPUP: Tx CS
* pin : pullup
*
* pin = VPIN number
* pullup = 1 - Pullup, 0 - no pullup
* configures a digital pin for input
*
* EXIOENAN: TX CS
* pin : FirstPinL : FirstPinH
*
* pin = VPIN number
* FirstPinL = first pin lowByte
* FirstPinH = first pin highByte
*
* EXIOWRD: TX CS
* pin : value
*
* pin = VPIN number
* value = 1 or 0
*
* EXIOWRAN: TX CS
* pin : valueL : valueH : profile : durationL : durationH
*
* pin = VPIN Number
* valueL = value lowByte
* valueH = value highByte
* profile = servo profile
* dueationL = duration lowByte
* durationH = duration highByte
*
* EXIORDD: TX CS
* -=No Parameters=-
*
* Requests digital pin states.
*
* EXIORDAN: TX CS
* -=no parameters=-
*
* Requests analog pin states.
*
* EXIOPINS: TX Node (EXIOINIT)
* numDigital : numAnalog
*
* numDigital = number of digital capable pins
* numAnalog = number of analog capable pins
*
* EXIOINITA: TX Node (EXIOINITA)
* ~analog pin map~
*
* each byte is a analog pin map value, variable length.
*
* EXIORDY/EXIOERR: TX Node (EXIODPUP, EXIOWRD, EXIOENAN, EXIOWRAN)
* -=no parameters=-
*
* Responds EXIORDY for OK, and EXIOERR for FAIL.
*
* EXIORDAN: TX Node (EXIORDAN)
* ~analog pin states~
*
* each byte is a pin state value, perhaps in lowByte/higeByte config.
*
* EXIORDD: TX Node (EXIORDD)
* ~digital pin states~
*
* each byte is a 8-bit grouping of pinstates.
*
* EXIOVER: TX Node (EXIOVER)
* Major Version : Minor Version : Patch Version
*
* each byte represents a numeric version value.
**********************************************************************/ **********************************************************************/
/********************************************************************** /**********************************************************************
* RSprotonode class * EXIO485node class
* *
* This encapsulates the state associated with a single RSproto node, * This encapsulates the state associated with a single EXIO485 node,
* which includes the nodeID, number of discrete inputs and coils, and * which includes the nodeID, number of discrete inputs and coils, and
* the states of the discrete inputs and coils. * the states of the discrete inputs and coils.
**********************************************************************/ **********************************************************************/
class RSprotonode : public IODevice { class EXIO485node : public IODevice {
private: private:
uint8_t _busNo; uint8_t _busNo;
uint8_t _nodeID; uint8_t _nodeID;
char _type; char _type;
RSprotonode *_next = NULL; EXIO485node *_next = NULL;
bool _initialised; bool _initialised;
RSproto *bus; EXIO485 *bus;
HardwareSerial* _serial; HardwareSerial* _serial;
enum { enum {
EXIOINIT = 0xE0, // Flag to initialise setup procedure EXIOINIT = 0xE0, // Flag to initialise setup procedure
@ -112,7 +205,7 @@ private:
}; };
static const int ARRAY_SIZE = 254; static const int ARRAY_SIZE = 254;
public: public:
static RSprotonode *_nodeList; static EXIO485node *_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
@ -122,9 +215,7 @@ public:
Bounce = 4, // For semaphores/turnouts with a bit of bounce!! Bounce = 4, // For semaphores/turnouts with a bit of bounce!!
NoPowerOff = 0x80, // Flag to be ORed in to suppress power off after move. NoPowerOff = 0x80, // Flag to be ORed in to suppress power off after move.
}; };
void _pollDigital(unsigned long currentMicros);
void _pollAnalog(unsigned long currentMicros);
uint8_t _numDigitalPins = 0; uint8_t _numDigitalPins = 0;
uint8_t getnumDigialPins() { uint8_t getnumDigialPins() {
return _numDigitalPins; return _numDigitalPins;
@ -226,19 +317,19 @@ public:
int resFlag[255]; int resFlag[255];
bool _initalized; bool _initalized;
static void create(VPIN firstVpin, int nPins, uint8_t nodeID) { static void create(VPIN firstVpin, int nPins, uint8_t nodeID) {
if (checkNoOverlap(firstVpin, nPins)) new RSprotonode(firstVpin, nPins, nodeID); if (checkNoOverlap(firstVpin, nPins)) new EXIO485node(firstVpin, nPins, nodeID);
} }
RSprotonode(VPIN firstVpin, int nPins, uint8_t nodeID); EXIO485node(VPIN firstVpin, int nPins, uint8_t nodeID);
uint8_t getNodeID() { uint8_t getNodeID() {
return _nodeID; return _nodeID;
} }
RSprotonode *getNext() { EXIO485node *getNext() {
return _next; return _next;
} }
void setNext(RSprotonode *node) { void setNext(EXIO485node *node) {
_next = node; _next = node;
} }
bool isInitialised() { bool isInitialised() {
@ -267,14 +358,14 @@ public:
}; };
/********************************************************************** /**********************************************************************
* RSproto class * EXIO485 class
* *
* This encapsulates the properties state of the bus and the * This encapsulates the properties state of the bus and the
* transmission and reception of data across that bus. Each RSproto * transmission and reception of data across that bus. Each EXIO485
* object owns a set of RSprotonode objects which represent the nodes * object owns a set of EXIO485node objects which represent the nodes
* attached to that bus. * attached to that bus.
**********************************************************************/ **********************************************************************/
class RSproto : public IODevice { class EXIO485 : public IODevice {
private: private:
// Here we define the device-specific variables. // Here we define the device-specific variables.
uint8_t _busNo; uint8_t _busNo;
@ -292,7 +383,7 @@ private:
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 RSproto *_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;
int _waitCounterB = 0; int _waitCounterB = 0;
@ -310,10 +401,10 @@ private:
RSprotonode *_nodeListStart = NULL, *_nodeListEnd = NULL; EXIO485node *_nodeListStart = NULL, *_nodeListEnd = NULL;
RSprotonode *_currentNode = NULL; EXIO485node *_currentNode = NULL;
uint16_t _receiveDataIndex = 0; // Index of next data byte to be received. uint16_t _receiveDataIndex = 0; // Index of next data byte to be received.
RSproto *_nextBus = NULL; // Pointer to next bus instance in list. EXIO485 *_nextBus = NULL; // Pointer to next bus instance in list.
// Helper function for error handling // Helper function for error handling
void reportError(uint8_t status, bool fail=true) { void reportError(uint8_t status, bool fail=true) {
@ -442,7 +533,7 @@ uint16_t crc16(uint8_t *data, uint16_t length);
EXIOERR = 0xEF, // Flag we've received an error EXIOERR = 0xEF, // Flag we've received an error
}; };
static void create(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin=-1, int cycleTime=500) { static void create(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin=-1, int cycleTime=500) {
new RSproto(busNo, serial, baud, txPin, cycleTime); new EXIO485(busNo, serial, baud, txPin, cycleTime);
} }
HardwareSerial* _serial; HardwareSerial* _serial;
int _CommMode = 0; int _CommMode = 0;
@ -475,17 +566,17 @@ uint16_t crc16(uint8_t *data, uint16_t length);
digitalWrite(_txPin, LOW); digitalWrite(_txPin, LOW);
} }
#if defined(RSproto_STM_OK) #if defined(EXIO485_STM_OK)
pinMode(RSproto_STM_OK, OUTPUT); pinMode(EXIO485_STM_OK, OUTPUT);
ArduinoPins::fastWriteDigital(RSproto_STM_OK,LOW); ArduinoPins::fastWriteDigital(EXIO485_STM_OK,LOW);
#endif #endif
#if defined(RSproto_STM_FAIL) #if defined(EXIO485_STM_FAIL)
pinMode(RSproto_STM_FAIL, OUTPUT); pinMode(EXIO485_STM_FAIL, OUTPUT);
ArduinoPins::fastWriteDigital(RSproto_STM_FAIL,LOW); ArduinoPins::fastWriteDigital(EXIO485_STM_FAIL,LOW);
#endif #endif
#if defined(RSproto_STM_COMM) #if defined(EXIO485_STM_COMM)
pinMode(RSproto_STM_COMM, OUTPUT); pinMode(EXIO485_STM_COMM, OUTPUT);
ArduinoPins::fastWriteDigital(RSproto_STM_COMM,LOW); ArduinoPins::fastWriteDigital(EXIO485_STM_COMM,LOW);
#endif #endif
#if defined(DIAG_IO) #if defined(DIAG_IO)
@ -503,9 +594,9 @@ uint16_t crc16(uint8_t *data, uint16_t length);
_deviceState == DEVSTATE_FAILED ? F("OFFLINE") : F("OK")); _deviceState == DEVSTATE_FAILED ? F("OFFLINE") : F("OK"));
} }
// Locate RSprotonode object with specified nodeID. // Locate EXIO485node object with specified nodeID.
RSprotonode *findNode(uint8_t nodeID) { EXIO485node *findNode(uint8_t nodeID) {
for (RSprotonode *node = _nodeListStart; node != NULL; node = node->getNext()) { for (EXIO485node *node = _nodeListStart; node != NULL; node = node->getNext()) {
if (node->getNodeID() == nodeID) if (node->getNodeID() == nodeID)
return node; return node;
} }
@ -514,36 +605,36 @@ uint16_t crc16(uint8_t *data, uint16_t length);
bool nodesInitialized() { bool nodesInitialized() {
bool retval = true; bool retval = true;
for (RSprotonode *node = _nodeListStart; node != NULL; node = node->getNext()) { for (EXIO485node *node = _nodeListStart; node != NULL; node = node->getNext()) {
if (node->_initalized == false) if (node->_initalized == false)
retval = false; retval = false;
} }
return retval; return retval;
} }
// Add new RSprotonode to the list of nodes for this bus. // Add new EXIO485node to the list of nodes for this bus.
void addNode(RSprotonode *newNode) { void addNode(EXIO485node *newNode) {
if (!_nodeListStart) if (!_nodeListStart)
_nodeListStart = newNode; _nodeListStart = newNode;
if (!_nodeListEnd) if (!_nodeListEnd)
_nodeListEnd = newNode; _nodeListEnd = newNode;
else else
_nodeListEnd->setNext(newNode); _nodeListEnd->setNext(newNode);
//DIAG(F("RSproto: 260h nodeID:%d _nodeListStart:%d _nodeListEnd:%d"), newNode, _nodeListStart, _nodeListEnd); //DIAG(F("EXIO485: 260h nodeID:%d _nodeListStart:%d _nodeListEnd:%d"), newNode, _nodeListStart, _nodeListEnd);
} }
protected: protected:
RSproto(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin, int cycleTime); EXIO485(uint8_t busNo, HardwareSerial &serial, unsigned long baud, int8_t txPin, int cycleTime);
public: public:
uint8_t getBusNumber() { uint8_t getBusNumber() {
return _busNo; return _busNo;
} }
RSproto *getNext() { EXIO485 *getNext() {
return _nextBus; return _nextBus;
} }
static RSproto *findBus(uint8_t busNo) { static EXIO485 *findBus(uint8_t busNo) {
for (RSproto *bus = _busList; bus != NULL; bus = bus->getNext()) { for (EXIO485 *bus = _busList; bus != NULL; bus = bus->getNext()) {
if (bus->getBusNumber() == busNo) if (bus->getBusNumber() == busNo)
return bus; return bus;
} }
@ -552,4 +643,4 @@ public:
}; };
#endif // IO_RSproto_H #endif // IO_EXIO485_H