diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 620b87eacd..c2bdc6d652 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -497,6 +497,14 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) { i2c_obj_t *p_i2c = (i2c_obj_t *) arg; int i2c_num = p_i2c->i2c_num; + // Interrupt protection. + // On C3 and S3 targets, the I2C may trigger a spurious interrupt, + // in order to detect these false positive, check the I2C's hardware interrupt mask + uint32_t int_mask; + i2c_hal_get_intsts_mask(&(i2c_context[i2c_num].hal), &int_mask); + if (int_mask == 0) { + return; + } i2c_intr_event_t evt_type = I2C_INTR_EVENT_ERR; portBASE_TYPE HPTaskAwoken = pdFALSE; if (p_i2c->mode == I2C_MODE_MASTER) { @@ -520,6 +528,9 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) { i2c_master_cmd_begin_static(i2c_num); } + } else { + // Do nothing if there is no proper event. + return; } i2c_cmd_evt_t evt = { .type = I2C_CMD_EVT_ALIVE @@ -620,6 +631,8 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num) **/ static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num) { +// A workaround for avoiding cause timeout issue when using +// hardware reset. #if !SOC_I2C_SUPPORT_HW_FSM_RST int scl_low_period, scl_high_period; int scl_start_hold, scl_rstart_setup; diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 87350f552e..eefcdf9f97 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -211,10 +211,6 @@ config SOC_I2C_FIFO_LEN int default 32 -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - config SOC_I2C_SUPPORT_HW_CLR_BUS bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 9d644c92bf..bf82c8a005 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -118,7 +118,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) #define SOC_I2C_SUPPORT_XTAL (1) diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 4305b5cb4a..4bea723a65 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -291,10 +291,6 @@ config SOC_I2C_SUPPORT_SLAVE bool default y -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - config SOC_I2C_SUPPORT_HW_CLR_BUS bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index cf72b8ef60..e4cb2e819a 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -155,7 +155,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ #define SOC_I2C_SUPPORT_SLAVE (1) -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) #define SOC_I2C_SUPPORT_XTAL (1) diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index cdc218cb03..3c799ad69e 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -283,10 +283,6 @@ config SOC_I2C_SUPPORT_SLAVE bool default y -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - config SOC_I2C_SUPPORT_HW_CLR_BUS bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index d2a705471d..7b2f9f6d0d 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -166,7 +166,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ #define SOC_I2C_SUPPORT_SLAVE (1) -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) #define SOC_I2C_SUPPORT_XTAL (1) diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 24bd84157e..ac450ab975 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -271,10 +271,6 @@ config SOC_I2C_SUPPORT_SLAVE bool default y -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - config SOC_I2C_SUPPORT_HW_CLR_BUS bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index aa5bf0be76..242e025180 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -147,8 +147,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ #define SOC_I2C_SUPPORT_SLAVE (1) -//ESP32-S2 support hardware FSM reset -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. //ESP32-S2 support hardware clear bus #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 01078f8bd8..8c557f3ba8 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -351,10 +351,6 @@ config SOC_I2C_SUPPORT_SLAVE bool default y -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - config SOC_I2C_SUPPORT_HW_CLR_BUS bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index c1f40c899d..1970b50034 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -150,8 +150,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ #define SOC_I2C_SUPPORT_SLAVE (1) -//ESP32-S3 support hardware FSM reset -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. //ESP32-S3 support hardware clear bus #define SOC_I2C_SUPPORT_HW_CLR_BUS (1)