diff --git a/src/lgfx/v1/platforms/esp32/common.inl b/src/lgfx/v1/platforms/esp32/common.inl index 595e2328..d1ed1dcf 100644 --- a/src/lgfx/v1/platforms/esp32/common.inl +++ b/src/lgfx/v1/platforms/esp32/common.inl @@ -1240,6 +1240,23 @@ namespace lgfx #include #endif +// TwoWire::end() exists from core 2.0.1 (0x44c11981 is 2.0.0). Some board packages lack +// core_version.h; they are judged by esp_arduino_version.h, which 2.0.1 and 2.0.2 still +// report as 2.0.0, hence the git version first. +#if defined ( ARDUINO ) && __has_include () && defined ( ESP_IDF_VERSION_VAL ) + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + #if defined ( ARDUINO_ESP32_GIT_VER ) + #if ARDUINO_ESP32_GIT_VER != 0x44c11981 + #define LGFX_TWOWIRE_HAS_END + #endif + #elif defined ( ESP_ARDUINO_VERSION_VAL ) + #if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 1) + #define LGFX_TWOWIRE_HAS_END + #endif + #endif + #endif +#endif + // Register layout of the I2C block. Only the older chips are named; anything not // listed is taken to carry the current layout, so a new target lands there rather // than on the ESP32 one. @@ -1591,35 +1608,6 @@ namespace lgfx updateDev(dev); } - void setPins(i2c_dev_t* dev, gpio_num_t scl, gpio_num_t sda) - { - pin_sda = sda; - pin_scl = scl; -#if defined ( ARDUINO ) && __has_include () - #if defined ( ESP_IDF_VERSION_VAL ) - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) - #if defined ARDUINO_ESP32_GIT_VER - #if ARDUINO_ESP32_GIT_VER != 0x44c11981 - #define USE_TWOWIRE_SETPINS - #endif - #endif - #endif - #endif - -#if LGFX_HP_I2C_NUM == 1 - auto twowire = &Wire; -#else - auto twowire = ((dev == &I2C0) ? &Wire : &Wire1); -#endif - - #if defined ( USE_TWOWIRE_SETPINS ) - twowire->setPins(sda, scl); - #else - twowire->begin((int)sda, (int)scl); - #endif -#endif - } - // A low power port is opened through the ESP-IDF driver even in an Arduino build, where // the normal ports go through TwoWire, so the handle is needed in both cases. #if __has_include() \ @@ -1979,17 +1967,13 @@ namespace lgfx #endif { #if defined ( ARDUINO ) && __has_include () && defined ( ESP_IDF_VERSION_VAL ) - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) - #if defined ARDUINO_ESP32_GIT_VER - #if ARDUINO_ESP32_GIT_VER != 0x44c11981 - #if LGFX_HP_I2C_NUM == 1 + #if defined ( LGFX_TWOWIRE_HAS_END ) + #if LGFX_HP_I2C_NUM == 1 auto twowire = &Wire; - #else + #else auto twowire = ((i2c_port == 0) ? &Wire : &Wire1); - #endif - twowire->end(); - #endif #endif + twowire->end(); #endif #elif __has_include() auto bus_handle = i2c_context[i2c_port].i2c_bus_handle; @@ -2404,6 +2388,16 @@ namespace lgfx } i2c_context[i2c_port].save_reg(dev); + // Still busy although no transfer of ours is running: a slave glitch can leave the + // controller waiting for a STOP forever (ESP32 has no FSM reset bit). Recover the bus + // and the controller as the ESP-IDF driver does before it starts a command (the C2 and + // C3 skip the peripheral reset there and rely on fsm_rst below). + if (getBusBusy(dev)) + { + ESP_LOGV("LGFX", "i2c::beginTransaction : bus busy, recover"); + i2c_stop(i2c_port); + } + // A low power port reaches its pads through the low power IO domain, which set_pin() // knows nothing about: routing them through the normal GPIO matrix here would // disconnect the port from its own pins on every transaction. A shared port keeps @@ -2746,18 +2740,12 @@ namespace lgfx #if defined ( ARDUINO ) && __has_include () _twowire = nullptr; if (search_sda >=0 && search_scl >= 0) { -#if defined ( ARDUINO ) && __has_include () && defined ( ESP_IDF_VERSION_VAL ) - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) - #if defined ARDUINO_ESP32_GIT_VER - #if ARDUINO_ESP32_GIT_VER != 0x44c11981 +#if defined ( LGFX_TWOWIRE_HAS_END ) _twowire = &Wire; #if defined (I2CEXT1_SDA_IN_IDX) if (i2c_port != 0) { _twowire = &Wire1; } #endif _twowire->end(); - #endif - #endif - #endif #endif } #endif