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:
parent
9c8bdc7728
commit
d105e0c607
100
IO_Modbus.cpp
100
IO_Modbus.cpp
@ -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.
|
||||
|
71
IO_Modbus.h
71
IO_Modbus.h
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user