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

save current

This commit is contained in:
travis-farmer 2024-12-12 12:17:23 -05:00
parent 9c8bdc7728
commit d105e0c607
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 151 additions and 20 deletions

View File

@ -211,14 +211,110 @@ void Modbus::_loop(unsigned long currentMicros) {
if (_currentMicros - _cycleStartTime < _cycleTime) return;
_cycleStartTime = _currentMicros;
if (_currentNode == NULL) return;
const char* errorStrings[16] = { "success", "invalid id", "invalid buffer", "invalid quantity", "response timeout", "frame error", "crc error", "unknown comm error", "unexpected id", "exception response", "unexpected function code", "unexpected response length", "unexpected byte count", "unexpected address", "unexpected value", "unexpected quantity" };
bool flagOK = true;
#if defined(MODBUS_STM_COMM)
ArduinoPins::fastWriteDigital(MODBUS_STM_COMM,HIGH);
#endif
if (taskCnt > 0) {
// run through tasks
int* taskData[25];
getNextTask(taskData);
switch((int) taskData[0]) {
case 0:
// protection for pulling empty task
break;
case 1: // configure pin
if (taskData[4] == (int*) CONFIGURE_INPUT) {
uint8_t pullup = (uint8_t) taskData[6];
uint8_t outBuffer[6] = {EXIODPUP, (uint8_t) taskData[0], (uint8_t)taskData[3], pullup};
uint8_t responseBuffer[3];
updateCrc(outBuffer,sizeof(outBuffer)-2);
if (_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(_txPin, HIGH);
_serialD->write(outBuffer, sizeof(outBuffer));
_serialD->flush();
if (_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(_txPin, LOW);
unsigned long startMillis = millis();
if (!_serialD->available()) {
if (waitReceive == true && _waitCounter > _waitA) {
}
if (millis() - startMillis >= 500) return;
}
uint16_t len = 0;
unsigned long startMicros = micros();
do {
if (_serialD->available()) {
startMicros = micros();
responseBuffer[len] = _serialD->read();
len++;
}
} while (micros() - startMicros <= 500 && len < 256);
if (crcGood(responseBuffer,sizeof(responseBuffer)-2)) {
if (responseBuffer[0] == EXIORDY) {
} else {
DIAG(F("EXIOMB Vpin %u cannot be used as a digital input pin"), (int)taskData[2]);
}
}
} else if (taskData[3] == (int*) CONFIGURE_ANALOGINPUT) {
// TODO: Consider moving code from _configureAnalogIn() to here and remove _configureAnalogIn
// from IODevice class definition. Not urgent, but each virtual function defined
// means increasing the RAM requirement of every HAL device driver, whether it's relevant
// to the driver or not.
}
break;
case 2: // configure analog in
uint8_t commandBuffer[5] = {EXIOENAN, (uint8_t) taskData[0], (uint8_t) taskData[3]};
uint8_t responseBuffer[3];
updateCrc(commandBuffer,sizeof(commandBuffer)-2);
if (_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(_txPin, HIGH);
_serialD->write(commandBuffer, sizeof(commandBuffer));
_serialD->flush();
if (_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(_txPin, LOW);
unsigned long startMillis = millis();
if (!_serialD->available()) {
if (waitReceive == true && _waitCounter > _waitA) {
}
if (millis() - startMillis >= 500) return;
}
uint16_t len = 0;
unsigned long startMicros = micros();
do {
if (_serialD->available()) {
startMicros = micros();
responseBuffer[len] = _serialD->read();
len++;
}
} while (micros() - startMicros <= 500 && len < 256);
if (crcGood(responseBuffer,sizeof(responseBuffer)-2)) {
if (responseBuffer[0] != EXIORDY) {
DIAG(F("EX-IOExpanderMB: Vpin %u on node %d cannot be used as an analogue input pin"), (int) taskData[2], (int) taskData[0]);
}
}
break;
case 3: // write pin
uint8_t digitalOutBuffer[6];
uint8_t responseBuffer[3];
digitalOutBuffer[0] = EXIOWRD;
digitalOutBuffer[1] = (uint8_t) taskData[0];
digitalOutBuffer[2] = (uint8_t) taskData[3];
digitalOutBuffer[3] = value;
uint8_t status = I2CManager.read(_I2CAddress, responseBuffer, 1, digitalOutBuffer, 3);
if (status != I2C_STATUS_OK) {
reportError(status);
} else {
if (responseBuffer[0] != EXIORDY) {
DIAG(F("Vpin %u cannot be used as a digital output pin"), (int)vpin);
}
}
}
} else {
// receive states
}
if (error == MODBUS_RTU_MASTER_WAITING) {
if (_waitCounter > _waitA) { // retry after 10 cycles of waiting, or user setting waitA.

View File

@ -53,7 +53,6 @@
#define IO_MODBUS_H
#include "IODevice.h"
#include <vector>
uint16_t div8RndUp(uint16_t value);
@ -298,7 +297,7 @@ public:
}
uint8_t receiveBuffer[5];
uint8_t commandBuffer[7] = {EXIOINIT, _nodeID, (uint8_t)_nPins, (uint8_t)(_firstVpin & 0xFF), (uint8_t)(_firstVpin >> 8)};
mb->updateCrc(commandBuffer,sizeof(commandBuffer));
mb->updateCrc(commandBuffer,sizeof(commandBuffer)-2);
if (mb->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(mb->_txPin, HIGH);
mb->_serialD->write(commandBuffer, sizeof(commandBuffer));
mb->_serialD->flush();
@ -367,7 +366,7 @@ public:
return;
}
commandBuffer[0] = EXIOINITA;
mb->updateCrc(commandBuffer,sizeof(commandBuffer));
mb->updateCrc(commandBuffer,sizeof(commandBuffer)-2);
if (mb->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(mb->_txPin, HIGH);
mb->_serialD->write(commandBuffer, sizeof(commandBuffer));
mb->_serialD->flush();
@ -392,7 +391,7 @@ public:
}
uint8_t versionBuffer[5];
commandBuffer[0] = EXIOVER;
mb->updateCrc(commandBuffer,sizeof(commandBuffer));
mb->updateCrc(commandBuffer,sizeof(commandBuffer)-2);
if (mb->_txPin != VPIN_NONE) ArduinoPins::fastWriteDigital(mb->_txPin, HIGH);
mb->_serialD->write(commandBuffer, sizeof(commandBuffer));
mb->_serialD->flush();
@ -551,7 +550,7 @@ private:
int _operationCount = 0;
static Modbus *_busList; // linked list of defined bus instances
bool waitReceive = false;
int _waitCounter = 0;
int _waitCounterB = 0;
int _waitA;
@ -590,26 +589,62 @@ private:
EXIOERR = 0xEF, // Flag we've received an error
};
int tasks[255][25];
int taskCnt = 0;
void _moveTasks() {
// used one in lead, so move forward
for (int i = 0; i < taskCnt-1; i++) {
for (int j = 0; j < 25; j++) {
tasks[i][j] = tasks[i+1][j+1];
}
}
taskCnt--;
}
public:
void addTask(int taskNum, int paranCnt, int *param[]) {
tasks[taskCnt][0] = taskNum;
int taskCnt = 0;
void addTask(int nodeID, int taskNum, int paramCnt, int *param[]) {
taskCnt++;
tasks[taskCnt][0] = nodeID;
tasks[taskCnt][1] = taskNum;
tasks[taskCnt][2] = paramCnt;
switch(taskNum) {
case 0: // configure pin
tasks[taskNum][1] = param[0]; // pin
tasks[taskNum][2] = param[1]; // configtype
tasks[taskNum][3] = param[2]; // paramcount
for (int i=0; i < param[2]; i++) {
tasks[taskNum][i+4] = param[i+3]; // params
case 0:
// empty task
case 1: // configure pin
tasks[taskCnt][3] = (int) param[0]; // pin
tasks[taskCnt][4] = (int) param[1]; // configtype
tasks[taskCnt][5] = (int) param[2]; // paramcount
for (int i=0; i < (int) param[2]; i++) {
tasks[taskCnt][i+6] = (int) param[i+3]; // params
}
break;
case 1: // configure analog in
tasks[taskNum][1] = param[0]; // pin
case 2: // configure analog in
tasks[taskCnt][3] = (int) param[0]; // pin
break;
case 3: // write pin
tasks[taskCnt][3] = (int) param[0]; // pin
tasks[taskCnt][4] = (int) param[1]; // value
break;
case 4: // write analog
tasks[taskCnt][3] = (int) param[0]; // pin
tasks[taskCnt][4] = (int) param[1]; // value
tasks[taskCnt][5] = (int) param[2]; // profile
tasks[taskCnt][6] = (int) param[3]; // duration
break;
}
}
int getNextTask(int *buf[]) {
int paramCnt = 0;
for (int i = 0; i < 25; i++) {
if (i == 0) buf[i] = (int*) tasks[0][i]; // NodeID
if (i == 1) buf[i] = (int*) tasks[0][i]; // tasknum
else if (i == 2) paramCnt = tasks[0][i]; // paramcnt
else {
buf[i-1] = (int*) tasks[0][i];
}
}
_moveTasks();
}
int8_t _txPin;
uint8_t *rtu = _adu + 6;