summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-10-18 10:39:11 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-10-18 10:39:11 +0200
commita14d519212747a8a58dc48ddc4ffffb1cd88896f (patch)
tree8d72e020c39c42c9cf815891431a04e4356a3cdd
parente391c1bc244838bb050ade946e709f671cd9cf94 (diff)
softi2c: handle SCL BUSY timeouts
-rw-r--r--src/driver/soft_i2c.cc20
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);
}