From c7740b4c2b73f7dc9857a5698b4c7a1ec3d26829 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 5 Sep 2023 12:27:18 +0800 Subject: [PATCH] fix(i2c_master): Fix I2C new master cannot continously probe --- components/driver/i2c/i2c_master.c | 11 ++++++++++- .../driver/test_apps/i2c_test_apps/main/test_i2c.c | 5 ++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/components/driver/i2c/i2c_master.c b/components/driver/i2c/i2c_master.c index c18f9a00a9..929c7b45d9 100644 --- a/components/driver/i2c/i2c_master.c +++ b/components/driver/i2c/i2c_master.c @@ -1049,13 +1049,20 @@ esp_err_t i2c_master_receive(i2c_master_dev_handle_t i2c_dev, uint8_t *read_buff esp_err_t i2c_master_probe(i2c_master_bus_handle_t i2c_master, uint16_t address, int xfer_timeout_ms) { ESP_RETURN_ON_FALSE(i2c_master != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized"); + TickType_t ticks_to_wait = (xfer_timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(xfer_timeout_ms); + if (xSemaphoreTake(i2c_master->bus_lock_mux, ticks_to_wait) != pdTRUE) { + return ESP_ERR_TIMEOUT; + } + + i2c_master->cmd_idx = 0; + i2c_master->trans_idx = 0; + i2c_master->trans_done = false; i2c_hal_context_t *hal = &i2c_master->base->hal; i2c_operation_t i2c_ops[] = { {.hw_cmd = I2C_TRANS_START_COMMAND}, {.hw_cmd = I2C_TRANS_STOP_COMMAND}, }; - TickType_t ticks_to_wait = (xfer_timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(xfer_timeout_ms); i2c_master->i2c_trans = (i2c_transaction_t) { .device_address = address, .ops = i2c_ops, @@ -1072,8 +1079,10 @@ esp_err_t i2c_master_probe(i2c_master_bus_handle_t i2c_master, uint16_t address, if (i2c_master->status == I2C_STATUS_ACK_ERROR) { // Reset the status to done, in order not influence next time transaction. i2c_master->status = I2C_STATUS_DONE; + xSemaphoreGive(i2c_master->bus_lock_mux); return ESP_ERR_NOT_FOUND; } + xSemaphoreGive(i2c_master->bus_lock_mux); return ESP_OK; } diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c.c index 5871c0d9a7..17152f67c5 100644 --- a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c.c @@ -132,7 +132,7 @@ TEST_CASE("I2C device add & remove check", "[i2c]") TEST_CASE("I2C master probe device test", "[i2c]") { - // 0x22 does not exist on the I2C bus, so it's expected to return `not found` error + // 0x22,33,44,55 does not exist on the I2C bus, so it's expected to return `not found` error // TODO: Add exist slave for testing probe success after i2c slave is merged. i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, @@ -145,5 +145,8 @@ TEST_CASE("I2C master probe device test", "[i2c]") TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config_1, &bus_handle)); TEST_ESP_ERR(i2c_master_probe(bus_handle, 0x22, -1), ESP_ERR_NOT_FOUND); + TEST_ESP_ERR(i2c_master_probe(bus_handle, 0x33, -1), ESP_ERR_NOT_FOUND); + TEST_ESP_ERR(i2c_master_probe(bus_handle, 0x44, -1), ESP_ERR_NOT_FOUND); + TEST_ESP_ERR(i2c_master_probe(bus_handle, 0x55, -1), ESP_ERR_NOT_FOUND); TEST_ESP_OK(i2c_del_master_bus(bus_handle)); }