diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2019-10-18 10:39:11 +0200 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2019-10-18 10:39:11 +0200 |
commit | a14d519212747a8a58dc48ddc4ffffb1cd88896f (patch) | |
tree | 8d72e020c39c42c9cf815891431a04e4356a3cdd | |
parent | e391c1bc244838bb050ade946e709f671cd9cf94 (diff) |
softi2c: handle SCL BUSY timeouts
-rw-r--r-- | src/driver/soft_i2c.cc | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/driver/soft_i2c.cc b/src/driver/soft_i2c.cc index 89f038b..285caef 100644 --- a/src/driver/soft_i2c.cc +++ b/src/driver/soft_i2c.cc @@ -127,7 +127,15 @@ bool SoftI2C::tx(unsigned char byte) i2c_wait(); SCL_HIGH; i2c_wait(); - while (!gpio.read(scl)) ; + + // Avoid hanging indefinitely if the bus / device is stuck + for (unsigned char i = 0; i < 200 && !gpio.read(scl); i++) { + i2c_wait(); + } + if (!gpio.read(scl)) { + return false; + } + if (i == 8) { if (!gpio.read(sda)) { got_ack = 1; @@ -146,7 +154,15 @@ unsigned char SoftI2C::rx(bool send_ack) i2c_wait(); SCL_HIGH; i2c_wait(); - while (!gpio.read(scl)) ; + + // Avoid hanging indefinitely if the bus / device is stuck + for (unsigned char i = 0; i < 200 && !gpio.read(scl); i++) { + i2c_wait(); + } + if (!gpio.read(scl)) { + return false; + } + if ((i < 8) && gpio.read(sda)) { byte |= 1 << (7 - i); } |