From efdf2bf611907ed2acf79e4334602ab549b78fb5 Mon Sep 17 00:00:00 2001 From: Almir Kadric Date: Thu, 23 Oct 2025 20:24:52 +0900 Subject: [PATCH 1/3] added support for enabling I2C HAL locks even when system wide HAL locks are disabled --- Kconfig.projbuild | 6 +++++ cores/esp32/esp32-hal-i2c-ng.c | 32 +++++++++++----------- cores/esp32/esp32-hal-i2c-slave.c | 16 ++++++----- cores/esp32/esp32-hal-i2c.c | 32 +++++++++++----------- libraries/Wire/src/Wire.cpp | 44 ++++++++++++++++--------------- libraries/Wire/src/Wire.h | 6 +++-- 6 files changed, 76 insertions(+), 60 deletions(-) diff --git a/Kconfig.projbuild b/Kconfig.projbuild index 705d0e66d5a..ced93fcd4fa 100644 --- a/Kconfig.projbuild +++ b/Kconfig.projbuild @@ -167,6 +167,12 @@ config DISABLE_HAL_LOCKS or interrupt at the same time. Option is best used with Arduino enabled and code implemented only in setup/loop and Arduino callbacks +config FORCE_I2C_HAL_LOCKS + bool "Enable mutex locks for I2C HAL even if HAL locks are disbled" + default "n" + help + Enabling this option will run I2C hardware abstraction with locks. + menu "Debug Log Configuration" choice ARDUHAL_LOG_DEFAULT_LEVEL bool "Default log level" diff --git a/cores/esp32/esp32-hal-i2c-ng.c b/cores/esp32/esp32-hal-i2c-ng.c index a3b2307b8a8..756cb82cc00 100644 --- a/cores/esp32/esp32-hal-i2c-ng.c +++ b/cores/esp32/esp32-hal-i2c-ng.c @@ -14,11 +14,13 @@ #include "esp32-hal-i2c.h" +#define I2C_HAL_LOCKS_ENABLED (!CONFIG_DISABLE_HAL_LOCKS || CONFIG_FORCE_I2C_HAL_LOCKS) + #if SOC_I2C_SUPPORTED #include "esp_idf_version.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) #include "esp32-hal.h" -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -32,7 +34,7 @@ typedef volatile struct { bool initialized; uint32_t frequency; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED SemaphoreHandle_t lock; #endif int8_t scl; @@ -75,7 +77,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (bus[i2c_num].lock == NULL) { bus[i2c_num].lock = xSemaphoreCreateMutex(); if (bus[i2c_num].lock == NULL) { @@ -147,7 +149,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { } if (!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER_SDA, (void *)(i2c_num + 1), i2c_num, -1) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER_SCL, (void *)(i2c_num + 1), i2c_num, -1)) { -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock so that i2cDetachBus can execute i2cDeinit xSemaphoreGive(bus[i2c_num].lock); #endif @@ -157,7 +159,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { } init_fail: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -169,7 +171,7 @@ esp_err_t i2cDeinit(uint8_t i2c_num) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -201,7 +203,7 @@ esp_err_t i2cDeinit(uint8_t i2c_num) { bus[i2c_num].bus_handle = NULL; } } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -241,7 +243,7 @@ esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_ log_e("Only 7bit I2C addresses are supported"); return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -282,7 +284,7 @@ esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_ } end: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -295,7 +297,7 @@ esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -328,7 +330,7 @@ esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, *readCount = size; end: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -343,7 +345,7 @@ esp_err_t i2cWriteReadNonStop( if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -376,7 +378,7 @@ esp_err_t i2cWriteReadNonStop( *readCount = rsize; end: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -388,7 +390,7 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -429,7 +431,7 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) { } end: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif diff --git a/cores/esp32/esp32-hal-i2c-slave.c b/cores/esp32/esp32-hal-i2c-slave.c index 1f23b7832f7..015ca518cc4 100644 --- a/cores/esp32/esp32-hal-i2c-slave.c +++ b/cores/esp32/esp32-hal-i2c-slave.c @@ -14,6 +14,8 @@ #include "soc/soc_caps.h" +#define I2C_HAL_LOCKS_ENABLED (!CONFIG_DISABLE_HAL_LOCKS || CONFIG_FORCE_I2C_HAL_LOCKS) + #if SOC_I2C_SUPPORT_SLAVE #include #include @@ -107,7 +109,7 @@ typedef struct i2c_slave_struct_t { #endif QueueHandle_t tx_queue; uint32_t rx_data_count; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED SemaphoreHandle_t lock; #endif } i2c_slave_struct_t; @@ -123,14 +125,14 @@ typedef union { static i2c_slave_struct_t _i2c_bus_array[SOC_HP_I2C_NUM] = { {&I2C0, 0, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED , NULL #endif }, #if SOC_HP_I2C_NUM > 1 {&I2C1, 1, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED , NULL #endif @@ -138,7 +140,7 @@ static i2c_slave_struct_t _i2c_bus_array[SOC_HP_I2C_NUM] = { #endif }; -#if CONFIG_DISABLE_HAL_LOCKS +#if !I2C_HAL_LOCKS_ENABLED #define I2C_SLAVE_MUTEX_LOCK() #define I2C_SLAVE_MUTEX_UNLOCK() #else @@ -274,7 +276,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t i2c_slave_struct_t *i2c = &_i2c_bus_array[num]; esp_err_t ret = ESP_OK; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (!i2c->lock) { i2c->lock = xSemaphoreCreateMutex(); if (i2c->lock == NULL) { @@ -427,7 +429,7 @@ esp_err_t i2cSlaveDeinit(uint8_t num) { } i2c_slave_struct_t *i2c = &_i2c_bus_array[num]; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (!i2c->lock) { log_e("Lock is not initialized! Did you call i2c_slave_init()?"); return ESP_ERR_NO_MEM; @@ -450,7 +452,7 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim } uint32_t to_queue = 0, to_fifo = 0; i2c_slave_struct_t *i2c = &_i2c_bus_array[num]; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (!i2c->lock) { log_e("Lock is not initialized! Did you call i2c_slave_init()?"); return ESP_ERR_NO_MEM; diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 71c8ae1c428..fb48b3683ab 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -14,11 +14,13 @@ #include "esp32-hal-i2c.h" +#define I2C_HAL_LOCKS_ENABLED (!CONFIG_DISABLE_HAL_LOCKS || CONFIG_FORCE_I2C_HAL_LOCKS) + #if SOC_I2C_SUPPORTED #include "esp_idf_version.h" #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0) #include "esp32-hal.h" -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -55,7 +57,7 @@ typedef volatile struct { bool initialized; uint32_t frequency; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED SemaphoreHandle_t lock; #endif int8_t scl; @@ -90,7 +92,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (bus[i2c_num].lock == NULL) { bus[i2c_num].lock = xSemaphoreCreateMutex(); if (bus[i2c_num].lock == NULL) { @@ -151,7 +153,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT); if (!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER_SDA, (void *)(i2c_num + 1), i2c_num, -1) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER_SCL, (void *)(i2c_num + 1), i2c_num, -1)) { -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock so that i2cDetachBus can execute i2cDeinit xSemaphoreGive(bus[i2c_num].lock); #endif @@ -161,7 +163,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { } } init_fail: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -173,7 +175,7 @@ esp_err_t i2cDeinit(uint8_t i2c_num) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -192,7 +194,7 @@ esp_err_t i2cDeinit(uint8_t i2c_num) { bus[i2c_num].sda = -1; } } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -205,7 +207,7 @@ esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_ if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -247,7 +249,7 @@ esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_ if (cmd != NULL) { i2c_cmd_link_delete_static(cmd); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -259,7 +261,7 @@ esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -276,7 +278,7 @@ esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, *readCount = 0; } } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -290,7 +292,7 @@ esp_err_t i2cWriteReadNonStop( if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -307,7 +309,7 @@ esp_err_t i2cWriteReadNonStop( *readCount = 0; } } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif @@ -319,7 +321,7 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) { if (i2c_num >= SOC_I2C_NUM) { return ESP_ERR_INVALID_ARG; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -412,7 +414,7 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) { } end: -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(bus[i2c_num].lock); #endif diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index cda098d2d5b..4f085518a1b 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -25,6 +25,8 @@ #include "soc/soc_caps.h" #if SOC_I2C_SUPPORTED +#define I2C_HAL_LOCKS_ENABLED (!CONFIG_DISABLE_HAL_LOCKS || CONFIG_FORCE_I2C_HAL_LOCKS) + extern "C" { #include #include @@ -42,7 +44,7 @@ TwoWire::TwoWire(uint8_t bus_num) : num(bus_num), sda(-1), scl(-1), bufferSize(I2C_BUFFER_LENGTH) // default Wire Buffer Size , rxBuffer(NULL), rxIndex(0), rxLength(0), txBuffer(NULL), txLength(0), txAddress(0), _timeOutMillis(50), nonStop(false) -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED , currentTaskHandle(NULL), lock(NULL) #endif @@ -55,7 +57,7 @@ TwoWire::TwoWire(uint8_t bus_num) TwoWire::~TwoWire() { end(); -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock != NULL) { vSemaphoreDelete(lock); } @@ -115,7 +117,7 @@ bool TwoWire::initPins(int sdaPin, int sclPin) { } bool TwoWire::setPins(int sdaPin, int sclPin) { -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock == NULL) { lock = xSemaphoreCreateMutex(); if (lock == NULL) { @@ -134,7 +136,7 @@ bool TwoWire::setPins(int sdaPin, int sclPin) { } else { log_e("bus already initialized. change pins only when not."); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); #endif @@ -180,7 +182,7 @@ size_t TwoWire::setBufferSize(size_t bSize) { return 0; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock == NULL) { lock = xSemaphoreCreateMutex(); if (lock == NULL) { @@ -211,7 +213,7 @@ size_t TwoWire::setBufferSize(size_t bSize) { // no memory allocated yet, just change the size value - allocation in begin() bufferSize = bSize; } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); @@ -223,7 +225,7 @@ size_t TwoWire::setBufferSize(size_t bSize) { // Slave Begin bool TwoWire::begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency) { bool started = false; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock == NULL) { lock = xSemaphoreCreateMutex(); if (lock == NULL) { @@ -264,7 +266,7 @@ bool TwoWire::begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency) { if (!started) { freeWireBuffer(); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); #endif @@ -276,7 +278,7 @@ bool TwoWire::begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency) { bool TwoWire::begin(int sdaPin, int sclPin, uint32_t frequency) { bool started = false; esp_err_t err = ESP_OK; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock == NULL) { lock = xSemaphoreCreateMutex(); if (lock == NULL) { @@ -315,7 +317,7 @@ bool TwoWire::begin(int sdaPin, int sclPin, uint32_t frequency) { if (!started) { freeWireBuffer(); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); #endif @@ -324,7 +326,7 @@ bool TwoWire::begin(int sdaPin, int sclPin, uint32_t frequency) { bool TwoWire::end() { esp_err_t err = ESP_OK; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED if (lock != NULL) { //acquire lock if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { @@ -344,7 +346,7 @@ bool TwoWire::end() { err = i2cDeinit(num); } freeWireBuffer(); -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); } @@ -354,7 +356,7 @@ bool TwoWire::end() { uint32_t TwoWire::getClock() { uint32_t frequency = 0; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -368,7 +370,7 @@ uint32_t TwoWire::getClock() { { i2cGetClock(num, &frequency); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); } @@ -378,7 +380,7 @@ uint32_t TwoWire::getClock() { bool TwoWire::setClock(uint32_t frequency) { esp_err_t err = ESP_OK; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //acquire lock if (lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { log_e("could not acquire lock"); @@ -394,7 +396,7 @@ bool TwoWire::setClock(uint32_t frequency) { { err = i2cSetClock(num, frequency); } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED //release lock xSemaphoreGive(lock); #endif @@ -416,7 +418,7 @@ void TwoWire::beginTransmission(uint8_t address) { return; } #endif /* SOC_I2C_SUPPORT_SLAVE */ -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED TaskHandle_t task = xTaskGetCurrentTaskHandle(); if (currentTaskHandle != task) { //acquire lock @@ -456,7 +458,7 @@ uint8_t TwoWire::endTransmission(bool sendStop) { esp_err_t err = ESP_OK; if (sendStop) { err = i2cWrite(num, txAddress, txBuffer, txLength, _timeOutMillis); -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED currentTaskHandle = NULL; //release lock xSemaphoreGive(lock); @@ -491,7 +493,7 @@ size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop) { return 0; } esp_err_t err = ESP_OK; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED TaskHandle_t task = xTaskGetCurrentTaskHandle(); if (currentTaskHandle != task) { //acquire lock @@ -505,7 +507,7 @@ size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop) { if (nonStop) { if (address != txAddress) { log_e("Unfinished Repeated Start transaction! Expected address do not match! %u != %u", address, txAddress); -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED currentTaskHandle = NULL; //release lock xSemaphoreGive(lock); @@ -527,7 +529,7 @@ size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop) { log_e("i2cRead returned Error %d", err); } } -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED currentTaskHandle = NULL; //release lock xSemaphoreGive(lock); diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 91a9ddc44bb..e1fbb943292 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -26,13 +26,15 @@ #ifndef TwoWire_h #define TwoWire_h +#define I2C_HAL_LOCKS_ENABLED (!CONFIG_DISABLE_HAL_LOCKS || CONFIG_FORCE_I2C_HAL_LOCKS) + #include "soc/soc_caps.h" #if SOC_I2C_SUPPORTED #include "esp_idf_version.h" #include #include -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -66,7 +68,7 @@ class TwoWire : public HardwareI2C { uint32_t _timeOutMillis; bool nonStop; -#if !CONFIG_DISABLE_HAL_LOCKS +#if I2C_HAL_LOCKS_ENABLED TaskHandle_t currentTaskHandle; SemaphoreHandle_t lock; #endif From 3cf979ab37734ca996c281bfb4d55beddb2deaeb Mon Sep 17 00:00:00 2001 From: Almir Kadric Date: Sat, 25 Oct 2025 06:42:55 +0900 Subject: [PATCH 2/3] fixed issue with missing fat fs dependency --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9b295dfa70..29d08595ca3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -372,7 +372,7 @@ endforeach() set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS}) set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS}) set(priv_includes cores/esp32/libb64) -set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver esp_http_client esp_https_ota) +set(requires spi_flash esp_partition wear_levelling mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver esp_http_client esp_https_ota) set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid usb esp_psram ${ARDUINO_LIBRARIES_REQUIRES}) if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThread) From 1fc283da4cc801d7cc284fa424aab2ebcbee00f9 Mon Sep 17 00:00:00 2001 From: Almir Kadric Date: Sat, 25 Oct 2025 13:31:03 +0900 Subject: [PATCH 3/3] fixed bug where gpio pin was not properly reset when calling pinMode --- cores/esp32/esp32-hal-gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 197f789d94d..490483110c4 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -145,6 +145,10 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) { conf.pull_down_en = GPIO_PULLDOWN_ENABLE; } } + if (gpio_reset_pin(pin) != ESP_OK) { + log_e("IO %i reset failed", pin); + return; + } if (gpio_config(&conf) != ESP_OK) { log_e("IO %i config failed", pin); return;