w5500 MAC triggering an unrecoverable error.

fanmen1
Posts: 33
Joined: Thu Mar 21, 2024 1:30 pm

w5500 MAC triggering an unrecoverable error.

Postby fanmen1 » Wed Oct 09, 2024 12:57 pm

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:

Code: Untitled.c Select all


void modbus_tcp_task(void* pvParameters)
{
// Modbus TCP slave handler
memset(&mbc_slave_handler, 0, sizeof(mbc_slave_handler));

// Initialize Modbus TCP stack
esp_err_t err = mbc_tcp_slave_create(&mbc_slave_handler);
if (err != ESP_OK) {
ESP_LOGE(TAG5, "Failed to initialize Modbus TCP stack: %d", err);
vTaskDelete(NULL);
return;
}

// Set communication parameters
mb_communication_info_t comm_info = {
.ip_port = 502, // Default Modbus TCP port
.ip_addr_type = MB_IPV4,
.ip_mode = MB_MODE_TCP,
};

// Start Modbus TCP stack
err = mbc_tcp_slave_start();
if (err != ESP_OK) {
ESP_LOGE(TAG5, "Failed to start Modbus TCP stack: %d", err);
vTaskDelete(NULL);
return;
}
ESP_LOGI(TAG5, "Modbus TCP stack initialized and started");

// Main loop for handling incoming Modbus TCP requests
while (1) {
// Check if the Modbus stack is active
if (eMBState == STATE_ENABLED) {
// Process requests from Modbus TCP client
eMBErrorCode status = eMBPoll(); // Check if a request has been received
if (status != MB_ENOERR) {
ESP_LOGE(TAG5, "Error polling Modbus TCP: 0x%x", (int)status);
} else {
ESP_LOGI(TAG5, "Modbus TCP request processed successfully");
}
}
vTaskDelay(pdMS_TO_TICKS(500)); // Poll every 100 ms
}
}
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:

Code: Untitled.bsh Select all


E (4158012) w5500.mac: w5500_spi_read(163): spi transmit failed
E (4158012) w5500.mac: w5500_read_buffer(276): read RX buffer failed
E (4158012) w5500.mac: emac_w5500_receive(680): read payload failed, len=60, offset=65529
E (4158022) w5500.mac: frame read from module failed
I (4158062) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
I (4158122) adc_api: Fan Speed: 6553/65535, 10.00%
I (4159292) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
I (4159352) adc_api: Fan Speed: 6553/65535, 10.00%
E (4159552) w5500.mac: w5500_spi_write(139): spi transmit failed
E (4159552) w5500.mac: w5500_write_buffer(253): write TX buffer failed
E (4159552) w5500.mac: emac_w5500_transmit(582): write frame failed
I (4160502) adc_api: Multisource Control Mode. Fans are controlled via Modbus/BMS, Webserver, and 0-10V 1 : 0.000000
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.

ondrej
Espressif staff
Espressif staff
Posts: 227
Joined: Fri May 07, 2021 10:35 am

Re: w5500 MAC triggering an unrecoverable error.

Postby ondrej » Fri Oct 11, 2024 5:59 am

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?

fanmen1
Posts: 33
Joined: Thu Mar 21, 2024 1:30 pm

Re: w5500 MAC triggering an unrecoverable error.

Postby fanmen1 » Fri Oct 11, 2024 8:02 am

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.

Code: Untitled.c Select all

void init_ethernet(void)
{
esp_netif_config_t netif_cfg_DHCP_client = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg_DHCP_client);

spi_bus_config_t buscfg = {
.miso_io_num = SPI_MISO_GPIO,
.mosi_io_num = SPI_MOSI_GPIO,
.sclk_io_num = SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
/* w5500 ethernet driver is based on spi driver */
spi_device_interface_config_t spi_devcfg = {
.mode = 0,
.clock_speed_hz = ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = ETH_SPI_CS_GPIO,
.queue_size = 20,
.cs_ena_posttrans = 2,
};

eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(ETH_SPI_HOST, &spi_devcfg);
w5500_config.int_gpio_num = ETH_SPI_INT_GPIO; // Set GPIO number for ethernet interrupt
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
mac_config.rx_task_stack_size = KILOBYTE * 16; // Set task size
esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);

eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.reset_gpio_num = -1;
esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);

esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_err_t err = esp_eth_driver_install(&eth_config, &eth_handle);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to install ethernet w5500 driver %u", err);
}
else
{
uint8_t mac_addr[6];
esp_read_mac(mac_addr, ESP_MAC_ETH);
mac->set_addr(mac, mac_addr); /* Set mac address */
ESP_LOGI(TAG, "--->> Set mac" MACSTR, MAC2STR(mac_addr));

/* Attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
/* Register user defined event handers */
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));

/* Start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
}
}

Who is online

Users browsing this forum: Qwantbot and 8 guests