Skip to content

Commit 1a6fa98

Browse files
committed
Wire: implement STOP sequence to recover I2C bus.
Usefull in case of bus stuck after a reset for example Fixes stm32duino#1661 Signed-off-by: Alexandre Bourdiol <[email protected]>
1 parent 443b609 commit 1a6fa98

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

libraries/Wire/src/Wire.cpp

+23
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,27 @@ inline void TwoWire::resetTxBuffer(void)
501503
}
502504
}
503505

506+
// Send STOP sequence to recover bus.
507+
// Usefull in case of bus stuck after a reset for example
508+
void TwoWire::recoverBus(void)
509+
{
510+
pinMode(pinNametoDigitalPin(_i2c.sda), OUTPUT);
511+
pinMode(pinNametoDigitalPin(_i2c.scl), OUTPUT);
512+
513+
for (int i = 0; i < 10; i++) {
514+
digitalWrite(pinNametoDigitalPin(_i2c.sda), LOW);
515+
delay(3);
516+
digitalWrite(pinNametoDigitalPin(_i2c.scl), HIGH);
517+
delay(3);
518+
digitalWrite(pinNametoDigitalPin(_i2c.sda), HIGH);
519+
delay(3);
520+
digitalWrite(pinNametoDigitalPin(_i2c.scl), LOW);
521+
delay(3);
522+
}
523+
pinMode(pinNametoDigitalPin(_i2c.sda), INPUT);
524+
pinMode(pinNametoDigitalPin(_i2c.scl), INPUT);
525+
}
526+
504527
// Preinstantiate Objects //////////////////////////////////////////////////////
505528

506529
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)