Răsfoiți Sursa

Merge branch 'bugfix/eth_w5500_io_intr_missed_v4.3' into 'release/v4.3'

esp_eth: w5500: Improve GPIO interrupt processing (v4.3)

See merge request espressif/esp-idf!13863
David Čermák 4 ani în urmă
părinte
comite
6ff1d8c828

+ 11 - 4
components/esp_eth/src/esp_eth_mac_w5500.c

@@ -267,9 +267,12 @@ static esp_err_t w5500_setup_default(emac_w5500_t *emac)
     /* Enable MAC RAW mode for SOCK0, enable MAC filter, no blocking broadcast and multicast */
     reg_value = W5500_SMR_MAC_RAW | W5500_SMR_MAC_FILTER;
     MAC_CHECK(w5500_write(emac, W5500_REG_SOCK_MR(0), &reg_value, sizeof(reg_value)) == ESP_OK, "write SMR failed", err, ESP_FAIL);
-    /* Enable receive and send event for SOCK0 */
-    reg_value = W5500_SIR_RECV | W5500_SIR_SEND;
+    /* Enable receive event for SOCK0 */
+    reg_value = W5500_SIR_RECV;
     MAC_CHECK(w5500_write(emac, W5500_REG_SOCK_IMR(0), &reg_value, sizeof(reg_value)) == ESP_OK, "write SOCK0 IMR failed", err, ESP_FAIL);
+    /* Set the interrupt re-assert level to maximum (~1.5ms) to lower the chances of missing it */
+    uint16_t int_level = __builtin_bswap16(0xFFFF);
+    MAC_CHECK(w5500_write(emac, W5500_REG_INTLEVEL, &int_level, sizeof(int_level)) == ESP_OK, "write INTLEVEL failed", err, ESP_FAIL);
 
 err:
     return ret;
@@ -322,8 +325,12 @@ static void emac_w5500_task(void *arg)
     uint8_t *buffer = NULL;
     uint32_t length = 0;
     while (1) {
-        // block indefinitely until some task notifies me
-        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
+        // check if the task receives any notification
+        if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 &&    // if no notification ...
+            gpio_get_level(emac->int_gpio_num) != 0) {               // ...and no interrupt asserted
+            continue;                                                // -> just continue to check again
+        }
+
         /* read interrupt status */
         w5500_read(emac, W5500_REG_SOCK_IR(0), &status, sizeof(status));
         /* packet received */

+ 1 - 0
components/esp_eth/src/w5500.h

@@ -33,6 +33,7 @@
 
 #define W5500_REG_MR        W5500_MAKE_MAP(0x0000, W5500_BSB_COM_REG) // Mode
 #define W5500_REG_MAC       W5500_MAKE_MAP(0x0009, W5500_BSB_COM_REG) // MAC Address
+#define W5500_REG_INTLEVEL  W5500_MAKE_MAP(0x0013, W5500_BSB_COM_REG) // Interrupt Level Timeout
 #define W5500_REG_IR        W5500_MAKE_MAP(0x0015, W5500_BSB_COM_REG) // Interrupt
 #define W5500_REG_IMR       W5500_MAKE_MAP(0x0016, W5500_BSB_COM_REG) // Interrupt Mask
 #define W5500_REG_SIR       W5500_MAKE_MAP(0x0017, W5500_BSB_COM_REG) // Socket Interrupt