Просмотр исходного кода

Merge branch 'bugfix/i2c_timeout_issue' into 'master'

I2C: Patch for solving watchdog timeout issue

Closes IDFGH-6923, IDFGH-6463, and IDFGH-5558

See merge request espressif/esp-idf!17956
Simon 3 лет назад
Родитель
Сommit
0b00831703

+ 13 - 0
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;

+ 0 - 4
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

+ 1 - 1
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)

+ 0 - 4
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

+ 1 - 1
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)

+ 0 - 4
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

+ 1 - 1
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)

+ 0 - 4
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

+ 1 - 2
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)
 

+ 0 - 4
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

+ 1 - 2
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)