mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-07-29 02:13:45 +02:00
Compare commits
3 Commits
v5.4.14-Pr
...
ex-io-debu
Author | SHA1 | Date | |
---|---|---|---|
|
fe24671ad2 | ||
|
0029762fc6 | ||
|
1de7857e00 |
@@ -61,9 +61,13 @@ static const FSH * guessI2CDeviceType(uint8_t address) {
|
|||||||
else if (address >= 0x40 && address <= 0x4f)
|
else if (address >= 0x40 && address <= 0x4f)
|
||||||
return F("PWM");
|
return F("PWM");
|
||||||
else if (address >= 0x50 && address <= 0x5f)
|
else if (address >= 0x50 && address <= 0x5f)
|
||||||
return F("EEPROM");
|
return F("EEPROM");
|
||||||
|
else if (address == 0x60)
|
||||||
|
return F("EX-Turntable");
|
||||||
|
else if (address == 0x65)
|
||||||
|
return F("EX-IOExpander");
|
||||||
else if (address == 0x68)
|
else if (address == 0x68)
|
||||||
return F("Real-time clock");
|
return F("Real-time clock or Rotary Encoder");
|
||||||
else if (address >= 0x70 && address <= 0x77)
|
else if (address >= 0x70 && address <= 0x77)
|
||||||
return F("I2C Mux");
|
return F("I2C Mux");
|
||||||
else
|
else
|
||||||
|
@@ -46,6 +46,45 @@
|
|||||||
#include "DIAG.h"
|
#include "DIAG.h"
|
||||||
#include "FSH.h"
|
#include "FSH.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
* ConfiguredInput class to maintain a cache of configured input pins.
|
||||||
|
* This enables reconfiguring defined input pins when <D HAL RESET> is issued, otherwise all input pins
|
||||||
|
* are left unconfigured after calling _begin, as EXRAIL inputs are only configured at startup.
|
||||||
|
*/
|
||||||
|
class ConfiguredInput {
|
||||||
|
public:
|
||||||
|
ConfiguredInput(VPIN vpin, IODevice::ConfigTypeEnum inputType, uint8_t pullup) :
|
||||||
|
_vpin(vpin), _inputType(inputType), _pullup(pullup) {}
|
||||||
|
|
||||||
|
int getVpin() {
|
||||||
|
return _vpin;
|
||||||
|
}
|
||||||
|
|
||||||
|
IODevice::ConfigTypeEnum getInputType() {
|
||||||
|
return _inputType;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getPullup() {
|
||||||
|
return _pullup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNext(ConfiguredInput *input) {
|
||||||
|
_next = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfiguredInput *getNext() {
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VPIN _vpin;
|
||||||
|
IODevice::ConfigTypeEnum _inputType;
|
||||||
|
uint8_t _pullup;
|
||||||
|
ConfiguredInput *_next = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
* IODevice subclass for EX-IOExpander.
|
* IODevice subclass for EX-IOExpander.
|
||||||
@@ -75,6 +114,7 @@ private:
|
|||||||
if (nPins > 256) nPins = 256;
|
if (nPins > 256) nPins = 256;
|
||||||
_nPins = nPins;
|
_nPins = nPins;
|
||||||
_I2CAddress = i2cAddress;
|
_I2CAddress = i2cAddress;
|
||||||
|
_firstInput = nullptr;
|
||||||
addDevice(this);
|
addDevice(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +210,52 @@ private:
|
|||||||
DIAG(F("EX-IOExpander I2C:%s device not found"), _I2CAddress.toString());
|
DIAG(F("EX-IOExpander I2C:%s device not found"), _I2CAddress.toString());
|
||||||
_deviceState = DEVSTATE_FAILED;
|
_deviceState = DEVSTATE_FAILED;
|
||||||
}
|
}
|
||||||
|
if (status == I2C_STATUS_OK) {
|
||||||
|
if (_firstInput) {
|
||||||
|
for (ConfiguredInput *input = _firstInput; input; input = input->getNext()) {
|
||||||
|
switch (input->getInputType()) {
|
||||||
|
case ConfigTypeEnum::CONFIGURE_INPUT: {
|
||||||
|
int params[1] = {input->getPullup()};
|
||||||
|
_configure(input->getVpin(), input->getInputType(), 1, params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConfigTypeEnum::CONFIGURE_ANALOGINPUT: {
|
||||||
|
_configureAnalogIn(input->getVpin());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isConfigured(VPIN vpin) const {
|
||||||
|
ConfiguredInput *current = _firstInput;
|
||||||
|
while (current != nullptr) {
|
||||||
|
if (current->getVpin() == vpin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
current = current->getNext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addConfiguredInput(ConfiguredInput *input) {
|
||||||
|
VPIN vpin = input->getVpin();
|
||||||
|
if (isConfigured(vpin)) return; // Already have this captured, don't create it again
|
||||||
|
if (!_firstInput) {
|
||||||
|
_firstInput = input;
|
||||||
|
} else {
|
||||||
|
ConfiguredInput *current = _firstInput;
|
||||||
|
while (current->getNext() != nullptr) {
|
||||||
|
current = current->getNext();
|
||||||
|
}
|
||||||
|
current->setNext(input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Digital input pin configuration, used to enable on EX-IOExpander device and set pullups if requested.
|
// Digital input pin configuration, used to enable on EX-IOExpander device and set pullups if requested.
|
||||||
@@ -186,6 +272,7 @@ private:
|
|||||||
outBuffer, sizeof(outBuffer));
|
outBuffer, sizeof(outBuffer));
|
||||||
if (status == I2C_STATUS_OK) {
|
if (status == I2C_STATUS_OK) {
|
||||||
if (responseBuffer[0] == EXIORDY) {
|
if (responseBuffer[0] == EXIORDY) {
|
||||||
|
addConfiguredInput(new ConfiguredInput(vpin, configType, pullup));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
DIAG(F("EXIOVpin %u cannot be used as a digital input pin"), (int)vpin);
|
DIAG(F("EXIOVpin %u cannot be used as a digital input pin"), (int)vpin);
|
||||||
@@ -212,6 +299,7 @@ private:
|
|||||||
commandBuffer, sizeof(commandBuffer));
|
commandBuffer, sizeof(commandBuffer));
|
||||||
if (status == I2C_STATUS_OK) {
|
if (status == I2C_STATUS_OK) {
|
||||||
if (responseBuffer[0] == EXIORDY) {
|
if (responseBuffer[0] == EXIORDY) {
|
||||||
|
addConfiguredInput(new ConfiguredInput(vpin, ConfigTypeEnum::CONFIGURE_ANALOGINPUT, 0));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
DIAG(F("EX-IOExpander: Vpin %u cannot be used as an analogue input pin"), (int)vpin);
|
DIAG(F("EX-IOExpander: Vpin %u cannot be used as an analogue input pin"), (int)vpin);
|
||||||
@@ -398,6 +486,8 @@ private:
|
|||||||
const unsigned long _digitalRefresh = 10000UL; // Delay refreshing digital inputs for 10ms
|
const unsigned long _digitalRefresh = 10000UL; // Delay refreshing digital inputs for 10ms
|
||||||
const unsigned long _analogueRefresh = 50000UL; // Delay refreshing analogue inputs for 50ms
|
const unsigned long _analogueRefresh = 50000UL; // Delay refreshing analogue inputs for 50ms
|
||||||
|
|
||||||
|
ConfiguredInput *_firstInput;
|
||||||
|
|
||||||
// EX-IOExpander protocol flags
|
// EX-IOExpander protocol flags
|
||||||
enum {
|
enum {
|
||||||
EXIOINIT = 0xE0, // Flag to initialise setup procedure
|
EXIOINIT = 0xE0, // Flag to initialise setup procedure
|
||||||
|
Reference in New Issue
Block a user