Skip to content

Commit b164919

Browse files
committed
fix(i2c): Add gpio reserve check on i2c driver,
Closes #15995
1 parent 0631340 commit b164919

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

components/esp_driver_i2c/i2c_common.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "esp_clk_tree.h"
2929
#include "clk_ctrl_os.h"
3030
#include "esp_private/gpio.h"
31+
#include "esp_private/esp_gpio_reserve.h"
3132
#if SOC_LP_I2C_SUPPORTED
3233
#include "hal/rtc_io_ll.h"
3334
#include "driver/rtc_io.h"
@@ -319,6 +320,17 @@ static esp_err_t s_hp_i2c_pins_config(i2c_bus_handle_t handle)
319320
{
320321
int port_id = handle->port_num;
321322

323+
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
324+
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(handle->sda_num) | BIT64(handle->scl_num));
325+
// check if the GPIO is already used by others
326+
if (old_gpio_rsv_mask & BIT64(handle->sda_num)) {
327+
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", handle->sda_num);
328+
}
329+
// check if the GPIO is already used by others
330+
if (old_gpio_rsv_mask & BIT64(handle->scl_num)) {
331+
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", handle->scl_num);
332+
}
333+
322334
// SDA pin configurations
323335
ESP_RETURN_ON_ERROR(gpio_set_level(handle->sda_num, 1), TAG, "i2c sda pin set level failed");
324336
gpio_input_enable(handle->sda_num);
@@ -357,6 +369,17 @@ static esp_err_t s_lp_i2c_pins_config(i2c_bus_handle_t handle)
357369
ESP_RETURN_ON_ERROR(!rtc_gpio_is_valid_gpio(handle->sda_num), TAG, "LP I2C SDA GPIO invalid");
358370
ESP_RETURN_ON_ERROR(!rtc_gpio_is_valid_gpio(handle->scl_num), TAG, "LP I2C SCL GPIO invalid");
359371

372+
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
373+
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(handle->sda_num) | BIT64(handle->scl_num));
374+
// check if the GPIO is already used by others
375+
if (old_gpio_rsv_mask & BIT64(handle->sda_num)) {
376+
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", handle->sda_num);
377+
}
378+
// check if the GPIO is already used by others
379+
if (old_gpio_rsv_mask & BIT64(handle->scl_num)) {
380+
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", handle->scl_num);
381+
}
382+
360383
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
361384
/* Verify that the SDA and SCL line belong to the LP IO Mux I2C function group */
362385
ESP_RETURN_ON_FALSE((handle->sda_num == LP_I2C_SDA_IOMUX_PAD), ESP_ERR_INVALID_ARG, TAG, LP_I2C_SDA_PIN_ERR_LOG);
@@ -419,6 +442,9 @@ esp_err_t i2c_common_deinit_pins(i2c_bus_handle_t handle)
419442
{
420443
int port_id = handle->port_num;
421444

445+
esp_gpio_revoke(BIT64(handle->sda_num));
446+
esp_gpio_revoke(BIT64(handle->scl_num));
447+
422448
if (handle->is_lp_i2c == false) {
423449
ESP_RETURN_ON_ERROR(gpio_output_disable(handle->sda_num), TAG, "disable i2c pins failed");
424450
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].sda_in_sig, 0);

0 commit comments

Comments
 (0)