diff --git a/components/esp_driver_i2c/i2c_common.c b/components/esp_driver_i2c/i2c_common.c index b2590a7bae..87042b404a 100644 --- a/components/esp_driver_i2c/i2c_common.c +++ b/components/esp_driver_i2c/i2c_common.c @@ -312,29 +312,27 @@ static esp_err_t s_hp_i2c_pins_config(i2c_bus_handle_t handle) int port_id = handle->port_num; // SDA pin configurations - gpio_config_t sda_conf = { - .intr_type = GPIO_INTR_DISABLE, - .mode = GPIO_MODE_INPUT_OUTPUT_OD, - .pull_down_en = false, - .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, - .pin_bit_mask = 1ULL << handle->sda_num, - }; ESP_RETURN_ON_ERROR(gpio_set_level(handle->sda_num, 1), TAG, "i2c sda pin set level failed"); - ESP_RETURN_ON_ERROR(gpio_config(&sda_conf), TAG, "config GPIO failed"); + gpio_input_enable(handle->sda_num); + gpio_od_enable(handle->sda_num); + if (handle->pull_up_enable) { + gpio_pullup_en(handle->sda_num); + } else { + gpio_pullup_dis(handle->sda_num); + } gpio_func_sel(handle->sda_num, PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->sda_num, i2c_periph_signal[port_id].sda_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->sda_num, i2c_periph_signal[port_id].sda_in_sig, 0); // SCL pin configurations - gpio_config_t scl_conf = { - .intr_type = GPIO_INTR_DISABLE, - .mode = GPIO_MODE_INPUT_OUTPUT_OD, - .pull_down_en = false, - .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, - .pin_bit_mask = 1ULL << handle->scl_num, - }; ESP_RETURN_ON_ERROR(gpio_set_level(handle->scl_num, 1), TAG, "i2c scl pin set level failed"); - ESP_RETURN_ON_ERROR(gpio_config(&scl_conf), TAG, "config GPIO failed"); + gpio_input_enable(handle->scl_num); + gpio_od_enable(handle->scl_num); + if (handle->pull_up_enable) { + gpio_pullup_en(handle->scl_num); + } else { + gpio_pullup_dis(handle->scl_num); + } gpio_func_sel(handle->scl_num, PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->scl_num, i2c_periph_signal[port_id].scl_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->scl_num, i2c_periph_signal[port_id].scl_in_sig, 0); @@ -406,3 +404,28 @@ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle) return ret; } + +esp_err_t i2c_common_deinit_pins(i2c_bus_handle_t handle) +{ + int port_id = handle->port_num; + + if (handle->is_lp_i2c == false) { + ESP_RETURN_ON_ERROR(gpio_output_disable(handle->sda_num), TAG, "disable i2c pins failed"); + esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].sda_in_sig, 0); + + ESP_RETURN_ON_ERROR(gpio_output_disable(handle->scl_num), TAG, "disable i2c pins failed"); + esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].scl_in_sig, 0); + } +#if SOC_LP_I2C_SUPPORTED + else { + ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->sda_num), TAG, "deinit rtc gpio failed"); + ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->scl_num), TAG, "deinit rtc gpio failed"); +#if SOC_LP_GPIO_MATRIX_SUPPORTED + lp_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].scl_in_sig, 0); + lp_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].sda_in_sig, 0); +#endif + } +#endif + + return ESP_OK; +} diff --git a/components/esp_driver_i2c/i2c_master.c b/components/esp_driver_i2c/i2c_master.c index 838d0578d7..5b1ef7c723 100644 --- a/components/esp_driver_i2c/i2c_master.c +++ b/components/esp_driver_i2c/i2c_master.c @@ -784,6 +784,7 @@ static esp_err_t i2c_master_bus_destroy(i2c_master_bus_handle_t bus_handle) { ESP_RETURN_ON_FALSE(bus_handle, ESP_ERR_INVALID_ARG, TAG, "no memory for i2c master bus"); i2c_master_bus_handle_t i2c_master = bus_handle; + i2c_common_deinit_pins(i2c_master->base); if (i2c_release_bus_handle(i2c_master->base) == ESP_OK) { if (i2c_master) { if (i2c_master->bus_lock_mux) { diff --git a/components/esp_driver_i2c/i2c_private.h b/components/esp_driver_i2c/i2c_private.h index 9793876551..b5be2a800b 100644 --- a/components/esp_driver_i2c/i2c_private.h +++ b/components/esp_driver_i2c/i2c_private.h @@ -258,6 +258,17 @@ esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, soc_module_clk_t clk_ */ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle); +/** + * @brief Deinit I2C SCL/SDA pins + * + * @param handle I2C bus handle + * @return + * - ESP_OK: I2C set SCL/SDA pins successfully. + * - ESP_ERR_INVALID_ARG: Argument error. + * - Otherwise: Set SCL/SDA IOs error. + */ +esp_err_t i2c_common_deinit_pins(i2c_bus_handle_t handle); + /** * @brief Check whether bus is acquired * diff --git a/components/esp_driver_i2c/i2c_slave.c b/components/esp_driver_i2c/i2c_slave.c index 2cb3da2595..b5f16fb9fc 100644 --- a/components/esp_driver_i2c/i2c_slave.c +++ b/components/esp_driver_i2c/i2c_slave.c @@ -294,6 +294,7 @@ static esp_err_t i2c_slave_bus_destroy(i2c_slave_dev_handle_t i2c_slave) { if (i2c_slave) { i2c_ll_disable_intr_mask(i2c_slave->base->hal.dev, I2C_LL_SLAVE_EVENT_INTR); + i2c_common_deinit_pins(i2c_slave->base); if (i2c_slave->slv_rx_mux) { vSemaphoreDeleteWithCaps(i2c_slave->slv_rx_mux); i2c_slave->slv_rx_mux = NULL; diff --git a/components/esp_driver_i2c/include/driver/i2c_master.h b/components/esp_driver_i2c/include/driver/i2c_master.h index 92928b1441..8518a45d0c 100644 --- a/components/esp_driver_i2c/include/driver/i2c_master.h +++ b/components/esp_driver_i2c/include/driver/i2c_master.h @@ -260,6 +260,22 @@ esp_err_t i2c_master_bus_reset(i2c_master_bus_handle_t bus_handle); */ esp_err_t i2c_master_bus_wait_all_done(i2c_master_bus_handle_t bus_handle, int timeout_ms); +/** + * @brief Retrieves the I2C master bus handle for a specified I2C port number. + * + * This function retrieves the I2C master bus handle for the + * given I2C port number. Please make sure the handle has already been initialized, and this + * function would simply returns the existing handle. Note that the returned handle still can't be used concurrently + * + * @param port_num I2C port number for which the handle is to be retrieved. + * @param ret_handle Pointer to a variable where the retrieved handle will be stored. + * @return + * - ESP_OK: Success. The handle is retrieved successfully. + * - ESP_ERR_INVALID_ARG: Invalid argument, such as invalid port number + * - ESP_ERR_INVALID_STATE: Invalid state, such as the I2C port is not initialized. + */ +esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_i2c/include/esp_private/i2c_platform.h b/components/esp_driver_i2c/include/esp_private/i2c_platform.h index f18cf53c99..3b8bee7b25 100644 --- a/components/esp_driver_i2c/include/esp_private/i2c_platform.h +++ b/components/esp_driver_i2c/include/esp_private/i2c_platform.h @@ -15,21 +15,7 @@ extern "C" { #endif -/** - * @brief Retrieves the I2C master bus handle for a specified I2C port number. - * - * This function retrieves the I2C master bus handle for the - * given I2C port number. Please make sure the handle has already been initialized, and this - * function would simply returns the existing handle. Note that the returned handle still can't be used concurrently - * - * @param port_num I2C port number for which the handle is to be retrieved. - * @param ret_handle Pointer to a variable where the retrieved handle will be stored. - * @return - * - ESP_OK: Success. The handle is retrieved successfully. - * - ESP_ERR_INVALID_ARG: Invalid argument, such as invalid port number - * - ESP_ERR_INVALID_STATE: Invalid state, such as the I2C port is not initialized. - */ -esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle); +// Empty file in order not cause breaking change. Should be removed in next version. #ifdef __cplusplus } diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c index 91296a6eed..55d7064b86 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c @@ -19,7 +19,6 @@ #include "esp_private/periph_ctrl.h" #include "driver/gpio.h" #include "driver/i2c_master.h" -#include "esp_private/i2c_platform.h" #include "esp_rom_gpio.h" #include "esp_log.h" #include "test_utils.h" diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index 2fbbdfc4b7..7714f5e516 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -166,7 +166,6 @@ When the I2C master handle has been initialized in one module (e.g. the audio mo ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); // Source File 2 - #include "esp_private/i2c_platform.h" #include "driver/i2c_master.h" i2c_master_bus_handle_t handle; ESP_ERROR_CHECK(i2c_master_get_bus_handle(0, &handle)); diff --git a/docs/zh_CN/api-reference/peripherals/i2c.rst b/docs/zh_CN/api-reference/peripherals/i2c.rst index f00095fdd8..392f3a7575 100644 --- a/docs/zh_CN/api-reference/peripherals/i2c.rst +++ b/docs/zh_CN/api-reference/peripherals/i2c.rst @@ -167,7 +167,6 @@ I2C 主机设备需要 :cpp:type:`i2c_device_config_t` 指定的配置: ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); // 源文件 2 - #include "esp_private/i2c_platform.h" #include "driver/i2c_master.h" i2c_master_bus_handle_t handle; ESP_ERROR_CHECK(i2c_master_get_bus_handle(0, &handle));