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:
parent
74cb0c12b0
commit
8a28cf1d21
@ -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);
|
||||||
|
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user