1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-23 08:06:13 +01:00

I2CManager - support slower I2C speeds.

Previously the driver allowed speeds down to 32kHz but lower speeds were not implemented correctly.
This commit is contained in:
Neil McKechnie 2021-10-08 13:28:43 +01:00
parent 6dde811279
commit 80472a76dc
2 changed files with 15 additions and 4 deletions

View File

@ -179,7 +179,7 @@ I2CManagerClass I2CManager = I2CManagerClass();
/*************************************************************************** /***************************************************************************
* Block waiting for request block to complete, and return completion status. * Block waiting for request block to complete, and return completion status.
* Since such a loop could potentially last for ever if the RB status doesn't * Since such a loop could potentially last for ever if the RB status doesn't
* change, we set a high limit (0.1sec, 100ms) on the wait time and, if it * change, we set a high limit (1sec, 1000ms) on the wait time and, if it
* hasn't changed by that time we assume it's not going to, and just return * hasn't changed by that time we assume it's not going to, and just return
* a timeout status. This means that CS will not lock up. * a timeout status. This means that CS will not lock up.
***************************************************************************/ ***************************************************************************/
@ -187,8 +187,8 @@ uint8_t I2CRB::wait() {
unsigned long waitStart = millis(); unsigned long waitStart = millis();
do { do {
I2CManager.loop(); I2CManager.loop();
// Rather than looping indefinitely, let's set a very high timeout (100ms). // Rather than looping indefinitely, let's set a very high timeout (1s).
if ((millis() - waitStart) > 100UL) { if ((millis() - waitStart) > 1000UL) {
DIAG(F("I2C TIMEOUT I2C:x%x I2CRB:x%x"), i2cAddress, this); DIAG(F("I2C TIMEOUT I2C:x%x I2CRB:x%x"), i2cAddress, this);
status = I2C_STATUS_TIMEOUT; status = I2C_STATUS_TIMEOUT;
// Note that, although the timeout is posted, the request may yet complete. // Note that, although the timeout is posted, the request may yet complete.

View File

@ -62,7 +62,18 @@
* Set I2C clock speed register. * Set I2C clock speed register.
***************************************************************************/ ***************************************************************************/
void I2CManagerClass::I2C_setClock(unsigned long i2cClockSpeed) { void I2CManagerClass::I2C_setClock(unsigned long i2cClockSpeed) {
TWBR = ((F_CPU / i2cClockSpeed) - 16) / 2; unsigned long temp = ((F_CPU / i2cClockSpeed) - 16) / 2;
for (uint8_t preScaler = 0; preScaler<=3; preScaler++) {
if (temp <= 255) {
TWBR = temp;
TWSR = (TWSR & 0xfc) | preScaler;
return;
} else
temp /= 4;
}
// Set slowest speed ~= 500 bits/sec
TWBR = 255;
TWSR |= 0x03;
} }
/*************************************************************************** /***************************************************************************