File tree Expand file tree Collapse file tree 1 file changed +27
-0
lines changed
Expand file tree Collapse file tree 1 file changed +27
-0
lines changed Original file line number Diff line number Diff line change @@ -366,6 +366,33 @@ void TwoWire::_handleTimeout(bool reset) {
366366 } else {
367367 int prev_clkHz = _clkHz;
368368 end ();
369+
370+ // Attempt bus recovery if SDA is held LOW by another device
371+ // See RP2040 datasheet "Bus clear feature" (not implemented in HW)
372+ int delay = 5 ; // 5us LOW/HIGH -> 10us period -> 100kHz freq
373+ pinMode (_sda, INPUT_PULLUP);
374+ pinMode (_scl, INPUT_PULLUP);
375+ gpio_set_function (_scl, GPIO_FUNC_SIO);
376+ gpio_set_function (_sda, GPIO_FUNC_SIO);
377+
378+ if (digitalRead (_sda) == LOW) {
379+ int sclPulseCount = 0 ;
380+ while (sclPulseCount < 9 && digitalRead (_sda) == LOW) {
381+ sclPulseCount++;
382+ digitalWrite (_scl, LOW);
383+ sleep_us (delay);
384+ digitalWrite (_scl, HIGH);
385+ sleep_us (delay);
386+ }
387+
388+ if (digitalRead (_sda) == HIGH) {
389+ // Bus recovered : send a STOP
390+ digitalWrite (_sda, LOW);
391+ sleep_us (delay);
392+ digitalWrite (_sda, HIGH);
393+ }
394+ }
395+
369396 setClock (prev_clkHz);
370397 begin ();
371398 }
You can’t perform that action at this time.
0 commit comments