Page 1 of 1

w5500 MAC triggering an unrecoverable error.

Posted: Wed Oct 09, 2024 12:57 pm
by fanmen1
In my application, I have initialised Ethernet in a standard mode with clock speed of 30MHZ. I also use the SPIRAM. Both the application share the same bus config and hosted using SPI_HOST 2. I was previously hosting a web server along side using PSRAM, which never had any problem. However, now I have disable the web server to use ethernet over MODBUS TCP/IP stack. I use the standard freemodbus library and create a continuous polling loop to monitor the incoming packets at the port. Here is the RTOS task created:
  1. void modbus_tcp_task(void* pvParameters)
  2. {
  3.     // Modbus TCP slave handler
  4.     memset(&mbc_slave_handler, 0, sizeof(mbc_slave_handler));
  5.  
  6.     // Initialize Modbus TCP stack
  7.     esp_err_t err = mbc_tcp_slave_create(&mbc_slave_handler);
  8.     if (err != ESP_OK) {
  9.         ESP_LOGE(TAG5, "Failed to initialize Modbus TCP stack: %d", err);
  10.         vTaskDelete(NULL);
  11.         return;
  12.     }
  13.  
  14.     // Set communication parameters
  15.     mb_communication_info_t comm_info = {
  16.         .ip_port = 502,  // Default Modbus TCP port
  17.         .ip_addr_type = MB_IPV4,
  18.         .ip_mode = MB_MODE_TCP,
  19.     };
  20.  
  21.     // Start Modbus TCP stack
  22.     err = mbc_tcp_slave_start();
  23.     if (err != ESP_OK) {
  24.         ESP_LOGE(TAG5, "Failed to start Modbus TCP stack: %d", err);
  25.         vTaskDelete(NULL);
  26.         return;
  27.     }
  28.     ESP_LOGI(TAG5, "Modbus TCP stack initialized and started");
  29.  
  30.     // Main loop for handling incoming Modbus TCP requests
  31.     while (1) {
  32.         // Check if the Modbus stack is active
  33.         if (eMBState == STATE_ENABLED) {
  34.             // Process requests from Modbus TCP client
  35.             eMBErrorCode status = eMBPoll();  // Check if a request has been received
  36.             if (status != MB_ENOERR) {
  37.                 ESP_LOGE(TAG5, "Error polling Modbus TCP: 0x%x", (int)status);
  38.             } else {
  39.                 ESP_LOGI(TAG5, "Modbus TCP request processed successfully");
  40.             }
  41.         }
  42.         vTaskDelay(pdMS_TO_TICKS(500));  // Poll every 100 ms
  43.     }
  44. }
The task mostly uses the standard library function and works as expected. However, it keeps triggering a unrecoverable error at random times (usually after 30 mins of runtime) as follows:
  1. E (4158012) w5500.mac: w5500_spi_read(163): spi transmit failed
  2. E (4158012) w5500.mac: w5500_read_buffer(276): read RX buffer failed
  3. E (4158012) w5500.mac: emac_w5500_receive(680): read payload failed, len=60, offset=65529
  4. E (4158022) w5500.mac: frame read from module failed
  5. I (4158062) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
  6. I (4158122) adc_api: Fan Speed: 6553/65535, 10.00%
  7. I (4159292) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
  8. I (4159352) adc_api: Fan Speed: 6553/65535, 10.00%
  9. E (4159552) w5500.mac: w5500_spi_write(139): spi transmit failed
  10. E (4159552) w5500.mac: w5500_write_buffer(253): write TX buffer failed
  11. E (4159552) w5500.mac: emac_w5500_transmit(582): write frame failed
  12. I (4160502) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
  13. I (4160562) adc_api: Fan Speed: 6553/65535, 10.00%
I have tried initialising different clock speed for the ethernet. A similar error was specified as bug in this issue https://github.com/espressif/esp-idf/issues/11845 and has been fixed for ESP-IDF 5.0v and above, but I'm still facing this issue. Any suggestions are welcome. Thanks.

Re: w5500 MAC triggering an unrecoverable error.

Posted: Fri Oct 11, 2024 5:59 am
by ESP_ondrej
Please share more information about your setup, e.g. IDF version, board you use (custom or modules connected via wires), etc. Are you able to reproduce the issue with Ethernet basic example?

Re: w5500 MAC triggering an unrecoverable error.

Posted: Fri Oct 11, 2024 8:02 am
by fanmen1
Hi,
Chipset: ESP32S3
IDF version: v5.1.4
Custom PCB with U12-W5500 module and ethernet port placed less than 2 cm away from the chip.
Ethernet initialisation is the basic initialisation example. I've been using the same ethernet port to host a local web server which works without any issue. Now I have disabled the web server and integrated a new feature i.e., MODBUS poll over TCP/IP stack for which I'm using the freemodbus library. Please have a look at the ethernet initialisation function.
  1. void init_ethernet(void)
  2. {
  3.     esp_netif_config_t netif_cfg_DHCP_client = ESP_NETIF_DEFAULT_ETH();
  4.     esp_netif_t *eth_netif = esp_netif_new(&netif_cfg_DHCP_client);
  5.  
  6.     spi_bus_config_t buscfg = {
  7.         .miso_io_num = SPI_MISO_GPIO,
  8.         .mosi_io_num = SPI_MOSI_GPIO,
  9.         .sclk_io_num = SPI_SCLK_GPIO,
  10.         .quadwp_io_num = -1,
  11.         .quadhd_io_num = -1,
  12.     };
  13.     ESP_ERROR_CHECK(spi_bus_initialize(ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
  14.     /* w5500 ethernet driver is based on spi driver */
  15.     spi_device_interface_config_t spi_devcfg = {
  16.         .mode = 0,
  17.         .clock_speed_hz = ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  18.         .spics_io_num = ETH_SPI_CS_GPIO,
  19.         .queue_size = 20,
  20.         .cs_ena_posttrans = 2,
  21.     };
  22.  
  23.     eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(ETH_SPI_HOST, &spi_devcfg);
  24.     w5500_config.int_gpio_num = ETH_SPI_INT_GPIO; // Set GPIO number for ethernet interrupt
  25.     eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  26.     mac_config.rx_task_stack_size = KILOBYTE * 16; // Set task size
  27.     esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  28.  
  29.     eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  30.     phy_config.reset_gpio_num = -1;
  31.     esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
  32.  
  33.     esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  34.     esp_err_t err = esp_eth_driver_install(&eth_config, &eth_handle);
  35.     if (err != ESP_OK)
  36.     {
  37.         ESP_LOGE(TAG, "Failed to install ethernet w5500 driver %u", err);
  38.     }
  39.     else
  40.     {
  41.         uint8_t mac_addr[6];
  42.         esp_read_mac(mac_addr, ESP_MAC_ETH);
  43.         mac->set_addr(mac, mac_addr); /* Set mac address */
  44.         ESP_LOGI(TAG, "--->> Set mac" MACSTR, MAC2STR(mac_addr));
  45.  
  46.         /* Attach Ethernet driver to TCP/IP stack */
  47.         ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
  48.         /* Register user defined event handers */
  49.         ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
  50.         ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
  51.  
  52.         /* Start Ethernet driver state machine */
  53.         ESP_ERROR_CHECK(esp_eth_start(eth_handle));
  54.     }
  55. }