diff --git a/components/esp_driver_i2c/i2c_slave.c b/components/esp_driver_i2c/i2c_slave.c index 85c56f4f14..a0ed0996c7 100644 --- a/components/esp_driver_i2c/i2c_slave.c +++ b/components/esp_driver_i2c/i2c_slave.c @@ -336,6 +336,14 @@ esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *da ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_FIFO), ESP_ERR_NOT_SUPPORTED, TAG, "non-fifo mode is not supported in this API, please set access_ram_en to false"); esp_err_t ret = ESP_OK; i2c_hal_context_t *hal = &i2c_slave->base->hal; +#if CONFIG_IDF_TARGET_ESP32C5 + // Workaround for c5 digital bug. Please note that following code has no + // functionality. It's just use for workaround the potential issue for avoiding + // secondary transaction. + i2c_ll_slave_enable_auto_start(hal->dev, true); + i2c_ll_start_trans(hal->dev); + i2c_ll_slave_enable_auto_start(hal->dev, false); +#endif TickType_t wait_ticks = (xfer_timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(xfer_timeout_ms); ESP_RETURN_ON_FALSE(xSemaphoreTake(i2c_slave->slv_tx_mux, wait_ticks) == pdTRUE, ESP_ERR_TIMEOUT, TAG, "transmit timeout"); @@ -358,6 +366,14 @@ esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, siz ESP_RETURN_ON_FALSE(esp_ptr_internal(data), ESP_ERR_INVALID_ARG, TAG, "buffer must locate in internal RAM if IRAM_SAFE is enabled"); #endif i2c_hal_context_t *hal = &i2c_slave->base->hal; +#if CONFIG_IDF_TARGET_ESP32C5 + // Workaround for c5 digital bug. Please note that following code has no + // functionality. It's just use for workaround the potential issue for avoiding + // secondary transaction. + i2c_ll_slave_enable_auto_start(hal->dev, true); + i2c_ll_start_trans(hal->dev); + i2c_ll_slave_enable_auto_start(hal->dev, false); +#endif xSemaphoreTake(i2c_slave->slv_rx_mux, portMAX_DELAY); i2c_slave_receive_t *t = &i2c_slave->receive_desc; diff --git a/components/esp_driver_i2c/i2c_slave_v2.c b/components/esp_driver_i2c/i2c_slave_v2.c index dc851d1254..017a2454d7 100644 --- a/components/esp_driver_i2c/i2c_slave_v2.c +++ b/components/esp_driver_i2c/i2c_slave_v2.c @@ -188,6 +188,14 @@ IRAM_ATTR static void i2c_slave_isr_handler(void *arg) } #endif } +#if CONFIG_IDF_TARGET_ESP32C5 + // Workaround for c5 digital bug. Please note that following code has no + // functionality. It's just use for workaround the potential issue for avoiding + // secondary transaction. + i2c_ll_slave_enable_auto_start(hal->dev, true); + i2c_ll_start_trans(hal->dev); + i2c_ll_slave_enable_auto_start(hal->dev, false); +#endif } #if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h index f6080cfa62..14503d15f7 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h @@ -29,6 +29,9 @@ extern "C" { #if CONFIG_IDF_TARGET_ESP32P4 #define LP_I2C_SCL_IO 4 #define LP_I2C_SDA_IO 5 +#elif CONFIG_IDF_TARGET_ESP32C5 +#define LP_I2C_SCL_IO 3 +#define LP_I2C_SDA_IO 2 #else #define LP_I2C_SCL_IO 7 #define LP_I2C_SDA_IO 6 diff --git a/components/hal/esp32c5/include/hal/i2c_ll.h b/components/hal/esp32c5/include/hal/i2c_ll.h index 3553b98847..2d95cf3272 100644 --- a/components/hal/esp32c5/include/hal/i2c_ll.h +++ b/components/hal/esp32c5/include/hal/i2c_ll.h @@ -925,6 +925,7 @@ static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi) * @param hw Beginning address of the peripheral registers * @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0. */ +__attribute__((always_inline)) static inline void i2c_ll_slave_enable_auto_start(i2c_dev_t *hw, bool slv_ex_auto_en) { hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;