mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-23 08:06:13 +01:00
Update I2CManager.cpp
Report address 0x3d as (probably) OLED Display. If an I2C probe for a device times out, assume that there's a bus problem on the MUX sub-bus, and skip the rest of the devices on that bus. This reduces the impact of the long timeout on some Wire implementations.
This commit is contained in:
parent
f1f1be8ad9
commit
3292c93192
|
@ -52,7 +52,7 @@ static const FSH * guessI2CDeviceType(uint8_t address) {
|
||||||
return F("GPIO Expander or LCD Display");
|
return F("GPIO Expander or LCD Display");
|
||||||
else if (address == 0x29)
|
else if (address == 0x29)
|
||||||
return F("Time-of-flight sensor");
|
return F("Time-of-flight sensor");
|
||||||
else if (address >= 0x3c && address <= 0x3c)
|
else if (address >= 0x3c && address <= 0x3d)
|
||||||
return F("OLED Display");
|
return F("OLED Display");
|
||||||
else if (address >= 0x48 && address <= 0x4f)
|
else if (address >= 0x48 && address <= 0x4f)
|
||||||
return F("Analogue Inputs or PWM");
|
return F("Analogue Inputs or PWM");
|
||||||
|
@ -110,6 +110,8 @@ void I2CManagerClass::begin(void) {
|
||||||
// Enumerate all I2C devices that are connected via multiplexer,
|
// Enumerate all I2C devices that are connected via multiplexer,
|
||||||
// i.e. that respond when only one multiplexer has one subBus enabled
|
// i.e. that respond when only one multiplexer has one subBus enabled
|
||||||
// and the device doesn't respond when the mux subBus is disabled.
|
// and the device doesn't respond when the mux subBus is disabled.
|
||||||
|
// If any probes time out, then assume that the subbus is dead and
|
||||||
|
// don't do any more on that subbus.
|
||||||
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
||||||
uint8_t muxAddr = I2C_MUX_BASE_ADDRESS + muxNo;
|
uint8_t muxAddr = I2C_MUX_BASE_ADDRESS + muxNo;
|
||||||
if (exists(muxAddr)) {
|
if (exists(muxAddr)) {
|
||||||
|
@ -117,7 +119,8 @@ void I2CManagerClass::begin(void) {
|
||||||
for (uint8_t subBus=0; subBus<=SubBus_No; subBus++) {
|
for (uint8_t subBus=0; subBus<=SubBus_No; subBus++) {
|
||||||
muxSelectSubBus({(I2CMux)muxNo, (I2CSubBus)subBus});
|
muxSelectSubBus({(I2CMux)muxNo, (I2CSubBus)subBus});
|
||||||
for (uint8_t addr=0x08; addr<0x78; addr++) {
|
for (uint8_t addr=0x08; addr<0x78; addr++) {
|
||||||
if (exists(addr)) {
|
uint8_t status = checkAddress(addr);
|
||||||
|
if (status == I2C_STATUS_OK) {
|
||||||
// De-select subbus
|
// De-select subbus
|
||||||
muxSelectSubBus({(I2CMux)muxNo, SubBus_None});
|
muxSelectSubBus({(I2CMux)muxNo, SubBus_None});
|
||||||
if (!exists(addr)) {
|
if (!exists(addr)) {
|
||||||
|
@ -129,11 +132,13 @@ void I2CManagerClass::begin(void) {
|
||||||
}
|
}
|
||||||
// Re-select subbus
|
// Re-select subbus
|
||||||
muxSelectSubBus({(I2CMux)muxNo, (I2CSubBus)subBus});
|
muxSelectSubBus({(I2CMux)muxNo, (I2CSubBus)subBus});
|
||||||
|
} else if (status == I2C_STATUS_TIMEOUT) {
|
||||||
|
// Bus stuck, skip to next one.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Probe mux address again with SubBus_None to deselect all
|
// Deselect all subBuses for this mux. Otherwise its devices will continue to
|
||||||
// subBuses for that mux. Otherwise its devices will continue to
|
|
||||||
// respond when other muxes are being probed.
|
// respond when other muxes are being probed.
|
||||||
I2CManager.muxSelectSubBus({(I2CMux)muxNo, SubBus_None}); // Deselect Mux
|
I2CManager.muxSelectSubBus({(I2CMux)muxNo, SubBus_None}); // Deselect Mux
|
||||||
}
|
}
|
||||||
|
@ -251,7 +256,7 @@ const FSH *I2CManagerClass::getErrorMessage(uint8_t status) {
|
||||||
case I2C_STATUS_NEGATIVE_ACKNOWLEDGE: return F("No response from device (address NAK)");
|
case I2C_STATUS_NEGATIVE_ACKNOWLEDGE: return F("No response from device (address NAK)");
|
||||||
case I2C_STATUS_TRANSMIT_ERROR: return F("Transmit error (data NAK)");
|
case I2C_STATUS_TRANSMIT_ERROR: return F("Transmit error (data NAK)");
|
||||||
case I2C_STATUS_OTHER_TWI_ERROR: return F("Other Wire/TWI error");
|
case I2C_STATUS_OTHER_TWI_ERROR: return F("Other Wire/TWI error");
|
||||||
case I2C_STATUS_TIMEOUT: return F("Timeout");
|
case I2C_STATUS_TIMEOUT: return F("I2C bus timeout");
|
||||||
case I2C_STATUS_ARBITRATION_LOST: return F("Arbitration lost");
|
case I2C_STATUS_ARBITRATION_LOST: return F("Arbitration lost");
|
||||||
case I2C_STATUS_BUS_ERROR: return F("I2C bus error");
|
case I2C_STATUS_BUS_ERROR: return F("I2C bus error");
|
||||||
case I2C_STATUS_UNEXPECTED_ERROR: return F("Unexpected error");
|
case I2C_STATUS_UNEXPECTED_ERROR: return F("Unexpected error");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user