mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
Additional support for Extended I2C Addresses
This commit is contained in:
parent
a0f0b860eb
commit
dd0ee8b50a
|
@ -95,7 +95,7 @@ void I2CManagerClass::begin(void) {
|
||||||
for (uint8_t addr=0x08; addr<0x78; addr++) {
|
for (uint8_t addr=0x08; addr<0x78; addr++) {
|
||||||
if (exists(addr)) {
|
if (exists(addr)) {
|
||||||
found = true;
|
found = true;
|
||||||
DIAG(F("I2C Device found at x%x, %S?"), addr, guessI2CDeviceType(addr));
|
DIAG(F("I2C Device found at 0x%x, %S?"), addr, guessI2CDeviceType(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void I2CManagerClass::begin(void) {
|
||||||
// Device responds when subbus selected but not when
|
// Device responds when subbus selected but not when
|
||||||
// subbus disabled - ergo it must be on subbus!
|
// subbus disabled - ergo it must be on subbus!
|
||||||
found = true;
|
found = true;
|
||||||
DIAG(F("I2C Device found at {I2CMux_%d,SubBus_%d,x%x}, %S?"),
|
DIAG(F("I2C Device found at {I2CMux_%d,SubBus_%d,0x%x}, %S?"),
|
||||||
muxNo, subBus, addr, guessI2CDeviceType(addr));
|
muxNo, subBus, addr, guessI2CDeviceType(addr));
|
||||||
}
|
}
|
||||||
// Re-select subbus
|
// Re-select subbus
|
||||||
|
@ -266,6 +266,9 @@ I2CManagerClass I2CManager = I2CManagerClass();
|
||||||
// try, and failure from timeout does not get retried.
|
// try, and failure from timeout does not get retried.
|
||||||
unsigned long I2CManagerClass::timeout = 100000UL;
|
unsigned long I2CManagerClass::timeout = 100000UL;
|
||||||
|
|
||||||
|
// Buffer for conversion of I2CAddress to char*.
|
||||||
|
/* static */ char I2CAddress::addressBuffer[30];
|
||||||
|
|
||||||
#if defined(I2C_EXTENDED_ADDRESS)
|
#if defined(I2C_EXTENDED_ADDRESS)
|
||||||
// Count of I2C multiplexers found when initialising. If there is only one
|
// Count of I2C multiplexers found when initialising. If there is only one
|
||||||
// MUX then the subbus does not de-selecting after use; however, if there
|
// MUX then the subbus does not de-selecting after use; however, if there
|
||||||
|
|
80
I2CManager.h
80
I2CManager.h
|
@ -192,6 +192,7 @@ private:
|
||||||
I2CMux _muxNumber;
|
I2CMux _muxNumber;
|
||||||
I2CSubBus _subBus;
|
I2CSubBus _subBus;
|
||||||
uint8_t _deviceAddress;
|
uint8_t _deviceAddress;
|
||||||
|
static char addressBuffer[];
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
// For I2CAddress "{Mux_0, SubBus_0, 0x23}" syntax.
|
// For I2CAddress "{Mux_0, SubBus_0, 0x23}" syntax.
|
||||||
|
@ -228,6 +229,41 @@ public:
|
||||||
// (device assumed to be on the main I2C bus or on a currently selected subbus.
|
// (device assumed to be on the main I2C bus or on a currently selected subbus.
|
||||||
operator uint8_t () const { return _deviceAddress; }
|
operator uint8_t () const { return _deviceAddress; }
|
||||||
|
|
||||||
|
// Conversion from I2CAddress to char* (uses static storage so only
|
||||||
|
// one conversion can be done at a time). So don't call it twice in a
|
||||||
|
// single DIAG statement for example.
|
||||||
|
const char* toString() {
|
||||||
|
char *ptr = addressBuffer;
|
||||||
|
if (_muxNumber != I2CMux_None) {
|
||||||
|
strcpy_P(ptr, (const char*)F("{I2CMux_"));
|
||||||
|
ptr += 8;
|
||||||
|
*ptr++ = '0' + _muxNumber;
|
||||||
|
strcpy_P(ptr, (const char*)F(",Subbus_"));
|
||||||
|
ptr += 8;
|
||||||
|
if (_subBus == SubBus_None) {
|
||||||
|
strcpy_P(ptr, (const char*)F("None"));
|
||||||
|
ptr += 4;
|
||||||
|
} else if (_subBus == SubBus_All) {
|
||||||
|
strcpy_P(ptr, (const char*)F("All"));
|
||||||
|
ptr += 3;
|
||||||
|
} else
|
||||||
|
*ptr++ = '0' + _subBus;
|
||||||
|
*ptr++ = ',';
|
||||||
|
}
|
||||||
|
uint8_t temp = _deviceAddress;
|
||||||
|
*ptr++ = '0';
|
||||||
|
*ptr++ = 'x';
|
||||||
|
for (uint8_t index = 0; index<2; index++) {
|
||||||
|
uint8_t bits = (temp >> 4) & 0x0f;
|
||||||
|
*ptr++ = bits > 9 ? bits-10+'A' : bits+'0';
|
||||||
|
temp <<= 4;
|
||||||
|
}
|
||||||
|
if (_muxNumber != I2CMux_None)
|
||||||
|
*ptr++ = '}';
|
||||||
|
*ptr = 0; // terminate string
|
||||||
|
return addressBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
// Comparison operator
|
// Comparison operator
|
||||||
int operator == (I2CAddress &a) const {
|
int operator == (I2CAddress &a) const {
|
||||||
if (_deviceAddress != a._deviceAddress)
|
if (_deviceAddress != a._deviceAddress)
|
||||||
|
@ -249,8 +285,50 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
struct I2CAddress {
|
||||||
|
private:
|
||||||
|
uint8_t _deviceAddress;
|
||||||
|
static char addressBuffer[];
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
I2CAddress(const uint8_t deviceAddress) {
|
||||||
|
_deviceAddress = deviceAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic constructor
|
||||||
|
I2CAddress() : I2CAddress(0) {}
|
||||||
|
|
||||||
|
// Conversion operator from I2CAddress to uint8_t
|
||||||
|
// For "uint8_t address = i2cAddress;" syntax
|
||||||
|
operator uint8_t () const { return _deviceAddress; }
|
||||||
|
|
||||||
|
// Conversion from I2CAddress to char* (uses static storage so only
|
||||||
|
// one conversion can be done at a time). So don't call it twice in a
|
||||||
|
// single DIAG statement for example.
|
||||||
|
const char* toString () {
|
||||||
|
char *ptr = addressBuffer;
|
||||||
|
// Just display hex value, two digits.
|
||||||
|
uint8_t temp = _deviceAddress;
|
||||||
|
*ptr++ = '0';
|
||||||
|
*ptr++ = 'x';
|
||||||
|
for (uint8_t index = 0; index<2; index++) {
|
||||||
|
uint8_t bits = (temp >> 4) & 0xf;
|
||||||
|
*ptr++ = bits > 9 ? bits-10+'a' : bits+'0';
|
||||||
|
temp <<= 4;
|
||||||
|
}
|
||||||
|
*ptr = 0; // terminate string
|
||||||
|
return addressBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison operator
|
||||||
|
int operator == (I2CAddress &a) const {
|
||||||
|
if (_deviceAddress != a._deviceAddress)
|
||||||
|
return false; // Different device address so no match
|
||||||
|
return true; // Same address on same mux and same subbus
|
||||||
|
}
|
||||||
|
};
|
||||||
// Legacy single-byte I2C address type for compact code and smooth changeover.
|
// Legacy single-byte I2C address type for compact code and smooth changeover.
|
||||||
typedef uint8_t I2CAddress;
|
//typedef uint8_t I2CAddress;
|
||||||
#endif // I2C_EXTENDED_ADDRESS
|
#endif // I2C_EXTENDED_ADDRESS
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ void I2CManagerClass::checkForTimeout() {
|
||||||
unsigned long elapsed = micros() - startTime;
|
unsigned long elapsed = micros() - startTime;
|
||||||
if (elapsed > timeout) {
|
if (elapsed > timeout) {
|
||||||
#ifdef DIAG_IO
|
#ifdef DIAG_IO
|
||||||
//DIAG(F("I2CManager Timeout on x%x, I2CRB=x%x"), (int)t->i2cAddress, currentRequest);
|
//DIAG(F("I2CManager Timeout on %s, I2CRB=%s"), t->i2cAddress.toString(), currentRequest);
|
||||||
#endif
|
#endif
|
||||||
// Excessive time. Dequeue request
|
// Excessive time. Dequeue request
|
||||||
queueHead = t->nextRequest;
|
queueHead = t->nextRequest;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user