Skip to content

Commit 51fc604

Browse files
ABOSTMfpistm
authored andcommitted
Wire: implement Clear Bus sequence to recover I2C bus.
Source: https://www.nxp.com/docs/en/user-guide/UM10204.pdf https://bits4device.wordpress.com/2017/07/28/i2c-bus-recovery/ Useful in case of bus stuck after a reset for example Fixes #1661 Signed-off-by: Alexandre Bourdiol <[email protected]>
1 parent 443b609 commit 51fc604

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

libraries/Wire/src/Wire.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ void TwoWire::begin(uint8_t address, bool generalCall)
8383

8484
_i2c.generalCall = (generalCall == true) ? 1 : 0;
8585

86+
recoverBus(); // in case I2C bus (device) is stuck after a reset for example
87+
8688
i2c_custom_init(&_i2c, 100000, I2C_ADDRESSINGMODE_7BIT, ownAddress);
8789

8890
if (_i2c.isMaster == 0) {
@@ -501,6 +503,28 @@ inline void TwoWire::resetTxBuffer(void)
501503
}
502504
}
503505

506+
// Send clear bus (clock pulse) sequence to recover bus.
507+
// Useful in case of bus stuck after a reset for example
508+
// a mix implementation of Clear Bus from
509+
// https://www.nxp.com/docs/en/user-guide/UM10204.pdf
510+
// https://bits4device.wordpress.com/2017/07/28/i2c-bus-recovery/
511+
void TwoWire::recoverBus(void)
512+
{
513+
pinMode(pinNametoDigitalPin(_i2c.sda), INPUT);
514+
515+
if (digitalReadFast(_i2c.sda) == LOW) {
516+
pinMode(pinNametoDigitalPin(_i2c.scl), OUTPUT);
517+
518+
for (int i = 0; i < 20; i++) {
519+
digitalWriteFast(_i2c.scl, LOW);
520+
delayMicroseconds(10);
521+
digitalWriteFast(_i2c.scl, HIGH);
522+
delayMicroseconds(10);
523+
}
524+
pinMode(pinNametoDigitalPin(_i2c.scl), INPUT);
525+
}
526+
}
527+
504528
// Preinstantiate Objects //////////////////////////////////////////////////////
505529

506530
TwoWire Wire = TwoWire(); //D14-D15

libraries/Wire/src/Wire.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class TwoWire : public Stream {
6666

6767
void resetRxBuffer(void);
6868
void resetTxBuffer(void);
69+
void recoverBus(void);
6970

7071
public:
7172
TwoWire();

0 commit comments

Comments
 (0)