mirror of
https://github.com/esphome/esphome.git
synced 2024-12-25 15:04:54 +01:00
I2c scan recovery reset fix (#4724)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
4a177e3931
commit
7abdb5d046
2 changed files with 16 additions and 6 deletions
|
@ -3,6 +3,7 @@
|
|||
#include "i2c_bus_arduino.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include <Arduino.h>
|
||||
#include <cstring>
|
||||
|
||||
|
@ -227,10 +228,14 @@ void ArduinoI2CBus::recover_() {
|
|||
// When SCL is kept LOW at this point, we might be looking at a device
|
||||
// that applies clock stretching. Wait for the release of the SCL line,
|
||||
// but not forever. There is no specification for the maximum allowed
|
||||
// time. We'll stick to 500ms here.
|
||||
auto wait = 20;
|
||||
// time. We yield and reset the WDT, so as to avoid triggering reset.
|
||||
// No point in trying to recover the bus by forcing a uC reset. Bus
|
||||
// should recover in a few ms or less else not likely to recovery at
|
||||
// all.
|
||||
auto wait = 250;
|
||||
while (wait-- && digitalRead(scl_pin_) == LOW) { // NOLINT
|
||||
delay(25);
|
||||
App.feed_wdt();
|
||||
delayMicroseconds(half_period_usec * 2);
|
||||
}
|
||||
if (digitalRead(scl_pin_) == LOW) { // NOLINT
|
||||
ESP_LOGE(TAG, "Recovery failed: SCL is held LOW during clock pulse cycle");
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include <cstring>
|
||||
#include <cinttypes>
|
||||
|
||||
|
@ -273,10 +274,14 @@ void IDFI2CBus::recover_() {
|
|||
// When SCL is kept LOW at this point, we might be looking at a device
|
||||
// that applies clock stretching. Wait for the release of the SCL line,
|
||||
// but not forever. There is no specification for the maximum allowed
|
||||
// time. We'll stick to 500ms here.
|
||||
auto wait = 20;
|
||||
// time. We yield and reset the WDT, so as to avoid triggering reset.
|
||||
// No point in trying to recover the bus by forcing a uC reset. Bus
|
||||
// should recover in a few ms or less else not likely to recovery at
|
||||
// all.
|
||||
auto wait = 250;
|
||||
while (wait-- && gpio_get_level(scl_pin) == 0) {
|
||||
delay(25);
|
||||
App.feed_wdt();
|
||||
delayMicroseconds(half_period_usec * 2);
|
||||
}
|
||||
if (gpio_get_level(scl_pin) == 0) {
|
||||
ESP_LOGE(TAG, "Recovery failed: SCL is held LOW during clock pulse cycle");
|
||||
|
|
Loading…
Reference in a new issue