mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-26 17:46: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++) {
|
||||
if (exists(addr)) {
|
||||
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
|
||||
// subbus disabled - ergo it must be on subbus!
|
||||
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));
|
||||
}
|
||||
// Re-select subbus
|
||||
|
@ -266,6 +266,9 @@ I2CManagerClass I2CManager = I2CManagerClass();
|
|||
// try, and failure from timeout does not get retried.
|
||||
unsigned long I2CManagerClass::timeout = 100000UL;
|
||||
|
||||
// Buffer for conversion of I2CAddress to char*.
|
||||
/* static */ char I2CAddress::addressBuffer[30];
|
||||
|
||||
#if defined(I2C_EXTENDED_ADDRESS)
|
||||
// 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
|
||||
|
|
80
I2CManager.h
80
I2CManager.h
|
@ -192,6 +192,7 @@ private:
|
|||
I2CMux _muxNumber;
|
||||
I2CSubBus _subBus;
|
||||
uint8_t _deviceAddress;
|
||||
static char addressBuffer[];
|
||||
public:
|
||||
// Constructors
|
||||
// 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.
|
||||
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
|
||||
int operator == (I2CAddress &a) const {
|
||||
if (_deviceAddress != a._deviceAddress)
|
||||
|
@ -249,8 +285,50 @@ public:
|
|||
};
|
||||
|
||||
#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.
|
||||
typedef uint8_t I2CAddress;
|
||||
//typedef uint8_t I2CAddress;
|
||||
#endif // I2C_EXTENDED_ADDRESS
|
||||
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ void I2CManagerClass::checkForTimeout() {
|
|||
unsigned long elapsed = micros() - startTime;
|
||||
if (elapsed > timeout) {
|
||||
#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
|
||||
// Excessive time. Dequeue request
|
||||
queueHead = t->nextRequest;
|
||||
|
|
Loading…
Reference in New Issue
Block a user