The W5500 + SPI_Slave driver does not work stably.

Yuriy.Vasylenko
Posts: 2
Joined: Mon Oct 23, 2023 10:59 am

The W5500 + SPI_Slave driver does not work stably.

Postby Yuriy.Vasylenko » Sat Oct 28, 2023 12:24 pm

Sorry for my bad English.

MCU - ESP32 Wroom 32
IDE VSCODE
IDE ESP-IDF 5.1

My device needs to receive data via SPI every 1ms and send it via Eth W5500. Using WiFi instead of W5500, the project works stably.
I have already tested the operation of the W5500 + SPIslave(DMA) for two weeks, so I am providing a short code to find bugs, and not a real project.

Description of the problem: When the SPI_slave (DMA) and the W5500 chip (only the Eth driver, the LWIP library is not used) work simultaneously and transmit packets (any) to the IP address of my ESP32 device, after a certain time a failure occurs:
  1. E (992450) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 3
  2. Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception).
  3. Debug exception reason: Stack canary watchpoint triggered (w5500_tsk)
  4. Core  1 register dump:
  5. PC      : 0x4008847f  PS      : 0x00060736  A0      : 0x8008d350  A1      : 0x3ffb8ec0  
  6. 0x4008847f: esp_cpu_compare_and_set at C:/Users/yuriy/esp/esp-idf/components/esp_hw_support/cpu.c:410
  7.  
  8. A2      : 0x3ffb0084  A3      : 0xb33fffff  A4      : 0x0000abab  A5      : 0x00000058  
  9. A6      : 0x0000000a  A7      : 0xff000000  A8      : 0x3ffb22e4  A9      : 0x5a97e5cc  
  10. A10     : 0x3ffb0234  A11     : 0x3ffb22e4  A12     : 0x3ffb93f4  A13     : 0x00000005  
  11. A14     : 0x3ffb93bc  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
  12. EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffff9  
  13. 0x400014fd: strlen in ROM
  14.  
  15. 0x4000150d: strlen in ROM
  16.  
  17.  
  18.  
  19. Backtrace: 0x4008847c:0x3ffb8ec0 0x4008d34d:0x3ffb8ef0 0x4008c760:0x3ffb8f30 0x40089f3e:0x3ffb8f60 0x4008a4bd:0x3ffb8f90 0x4008a68a:0x3ffb8fd0 0x400843af:0x3ffb9000 0x40084599:0x3ffb9030 0x400d8214:0x3ffb9060 0x400d6c9d:0x3ffb9090 0x400d6699:0x3ffb90c0 0x4000bd83:0x3ffb90f0 0x4000117d:0x3ffb9110 0x400592fe:0x3ffb9130 0x4005937a:0x3ffb9150 0x400e9d93:0x3ffb9170 0x400f1c1b:0x3ffb91a0 0x400ed816:0x3ffb91c0 0x400ed981:0x3ffb94e0 0x400f76c1:0x3ffb9510 0x400917bd:0x3ffb9550 0x400e533d:0x3ffb95a0 0x400e5656:0x3ffb95e0 0x4008d182:0x3ffb9620
  20. 0x4008847c: esp_cpu_compare_and_set at C:/Users/yuriy/esp/esp-idf/components/esp_hw_support/cpu.c:410
  21.  
  22. 0x4008d34d: spinlock_acquire at C:/Users/yuriy/esp/esp-idf/components/esp_hw_support/include/spinlock.h:103
  23.  (inlined by) xPortEnterCriticalTimeout at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501
  24.  
  25. 0x4008c760: vPortEnterCritical at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h:575
  26.  (inlined by) xTaskPriorityDisinherit at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:5184
  27.  
  28. 0x40089f3e: prvCopyDataToQueue at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:2414
  29.  
  30. 0x4008a4bd: xQueueGenericSend at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:906
  31.  
  32. 0x4008a68a: xQueueGiveMutexRecursive at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:737
  33.  
  34. 0x400843af: lock_release_generic at C:/Users/yuriy/esp/esp-idf/components/newlib/locks.c:190
  35.  
  36. 0x40084599: _lock_release_recursive at C:/Users/yuriy/esp/esp-idf/components/newlib/locks.c:202
  37.  
  38. 0x400d8214: uart_write at C:/Users/yuriy/esp/esp-idf/components/vfs/vfs_uart.c:219
  39.  
  40. 0x400d6c9d: console_write at C:/Users/yuriy/esp/esp-idf/components/vfs/vfs_console.c:73
  41.  
  42. 0x400d6699: esp_vfs_write at C:/Users/yuriy/esp/esp-idf/components/vfs/vfs.c:445 (discriminator 4)
  43.  
  44. 0x4000bd83: _write_r in ROM
  45.  
  46. 0x4000117d: __swrite in ROM
  47.  
  48. 0x400592fe: __sflush_r in ROM
  49.  
  50. 0x4005937a: _fflush_r in ROM
  51.  
  52. 0x400e9d93: __sfvwrite_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/fvwrite.c:251
  53.  
  54. 0x400f1c1b: __sprint_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vfprintf.c:429
  55.  (inlined by) __sprint_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vfprintf.c:399
  56.  
  57. 0x400ed816: _vfprintf_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vfprintf.c:1777 (discriminator 1)
  58.  
  59. 0x400ed981: vprintf at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vprintf.c:34 (discriminator 5)
  60.  
  61. 0x400f76c1: esp_log_writev at C:/Users/yuriy/esp/esp-idf/components/log/log.c:200
  62.  
  63. 0x400917bd: esp_log_write at C:/Users/yuriy/esp/esp-idf/components/log/log.c:210
  64.  
  65. 0x400e533d: emac_w5500_alloc_recv_buf at C:/Users/yuriy/esp/esp-idf/components/esp_eth/src/esp_eth_mac_w5500.c:535 (discriminator 5)
  66.  
  67. 0x400e5656: emac_w5500_task at C:/Users/yuriy/esp/esp-idf/components/esp_eth/src/esp_eth_mac_w5500.c:670
  68.  
  69. 0x4008d182: vPortTaskWrapper at C:/Users/yuriy/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162
  70.  
  71.  
  72.  
  73.  
  74.  
  75. ELF file SHA256: 0928843e63d183e2
  76.  
  77. Rebooting...


When increasing rx_task_stack_size = 2048 to rx_task_stack_size = 8192 errors:
  1. E (120665) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 3
  2. E (120665) w5500.mac: no mem for receive buffer
  3. E (122156) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 3
  4. E (122156) w5500.mac: no mem for receive buffer
  5. E (122966) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 3
  6. E (122966) w5500.mac: no mem for receive buffer
  7. E (123003) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 0
  8. E (123004) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 0
  9. E (123008) w5500.mac: emac_w5500_alloc_recv_buf(535): invalid frame length 0
and so on ad infinitum, the work is very unstable.


I ask for help to solve the problem of unstable operation of the W5500 together with SPI_Slave.
Thank you.


My task SPI code:
  1. #define GPIO_MOSI 13
  2. #define GPIO_MISO 12
  3. #define GPIO_SCLK 14
  4. #define GPIO_CS 21//15
  5. #define RCV_HOST    HSPI_HOST
  6.  
  7. spi_slave_transaction_t t;
  8. spi_slave_transaction_t *loopbuf;
  9.  
  10.  uint8_t *sendbuf;
  11.  uint8_t *recvbuf;
  12.  
  13.  
  14.  
  15. int n=0;
  16. //Called after a transaction is queued and ready for pickup by master.
  17. void IRAM_ATTR my_post_setup_cb(spi_slave_transaction_t *trans) {
  18. }
  19.  
  20. //Called after transaction is sent/received. We use this to set the handshake line low.
  21. void IRAM_ATTR my_post_trans_cb(spi_slave_transaction_t *trans) {
  22.  }
  23.  
  24. //Main application
  25. static void IRAM_ATTR  My_SPI_Slave_task(void *pvParameters){
  26.  
  27.      sendbuf = heap_caps_calloc(1,1500, MALLOC_CAP_DMA);
  28.      recvbuf = heap_caps_calloc(1,1500, MALLOC_CAP_DMA);
  29.       if (!sendbuf) {
  30.             ESP_LOGI("Create pool:", "No enough memory");
  31.             //return ESP_ERR_NO_MEM;
  32.         }
  33.      if (!recvbuf) {
  34.             ESP_LOGI("Create pool:", "No enough memory");
  35.             //return ESP_ERR_NO_MEM;
  36.         }
  37.    
  38.     esp_err_t ret;
  39.  
  40.     //Configuration for the SPI bus
  41.     spi_bus_config_t buscfg={
  42.         .mosi_io_num=GPIO_MOSI,
  43.         .miso_io_num=GPIO_MISO,
  44.         .sclk_io_num=GPIO_SCLK,
  45.         .quadwp_io_num = -1,
  46.         .quadhd_io_num = -1,
  47.         .isr_cpu_id = INTR_CPU_ID_AUTO,
  48.     };
  49.  
  50.     //Configuration for the SPI slave interface
  51.     spi_slave_interface_config_t slvcfg={
  52.         .mode=0,
  53.         .spics_io_num=GPIO_CS,
  54.         .queue_size=3,
  55.         .flags=0,
  56.          .post_setup_cb=my_post_setup_cb,
  57.         .post_trans_cb=my_post_trans_cb
  58.     };
  59.  
  60.    
  61.     gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
  62.     gpio_set_pull_mode(GPIO_SCLK, GPIO_PULLUP_ONLY);
  63.     gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);
  64.  
  65.     ret=spi_slave_initialize(RCV_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO );
  66.     assert(ret==ESP_OK);
  67.  
  68.     loopbuf = (spi_slave_transaction_t *) malloc (sizeof(spi_slave_transaction_t));
  69.    
  70.    
  71.    t.length=1500*8;
  72.    t.tx_buffer=sendbuf;
  73.    t.rx_buffer=recvbuf;
  74.  
  75.   size_t item_size;
  76.  
  77.    while(1) {
  78.     ret = spi_slave_transmit(RCV_HOST, &t, 1000);
  79. }
  80.  
  81. }


Eth_W5500 driver initialization code:
  1. #define CONFIG_ETH_PHY_ADDR 1
  2. #define CONFIG_ETH_PHY_RST_GPIO -1
  3. #define CONFIG_ETH_SPI_MISO_GPIO 19
  4. #define CONFIG_ETH_SPI_MOSI_GPIO 23
  5. #define CONFIG_ETH_SPI_SCLK_GPIO 18
  6. #define CONFIG_ETH_SPI_CLOCK_MHZ 32
  7. #define CONFIG_ETH_SPI_CS_GPIO 5
  8. #define CONFIG_ETH_SPI_HOST VSPI_HOST
  9. #define CONFIG_ETH_SPI_INT_GPIO 4
  10.  
  11. static const char *TAG2 = "LOG";
  12.  
  13.  
  14. ////////////////////////////
  15. /** Event handler for Ethernet events */
  16. static void IRAM_ATTR eth_event_handler(void *arg, esp_event_base_t event_base,
  17.                               int32_t event_id, void *event_data)
  18. {
  19.     uint8_t mac_addr[6] = {};
  20.     /* we can get the ethernet driver handle from event data */
  21.     esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
  22.     switch (event_id) {
  23.     case ETHERNET_EVENT_CONNECTED:
  24.         esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
  25.         ESP_LOGI(TAG2, "Ethernet Link Up");
  26.         ESP_LOGI(TAG2, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
  27.                     mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  28.         break;
  29.     case ETHERNET_EVENT_DISCONNECTED:
  30.         ESP_LOGI(TAG2, "Ethernet Link Down");
  31.         break;
  32.     case ETHERNET_EVENT_START:
  33.         ESP_LOGI(TAG2, "Ethernet Started");
  34.         break;
  35.     case ETHERNET_EVENT_STOP:
  36.         ESP_LOGI(TAG2, "Ethernet Stopped");
  37.         break;
  38.     default:
  39.         break;
  40.     }
  41. }
  42.  
  43. esp_eth_handle_t MyInitEth(){
  44. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();      // apply default common MAC configuration
  45. mac_config.rx_task_stack_size = 2048;
  46. mac_config.rx_task_prio = 15;  
  47. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();      // apply default PHY configuration
  48. phy_config.phy_addr = CONFIG_ETH_PHY_ADDR;           // alter the PHY address according to your board design
  49. phy_config.reset_gpio_num = CONFIG_ETH_PHY_RST_GPIO; // alter the GPIO used for PHY reset
  50. // Install GPIO interrupt service (as the SPI-Ethernet module is interrupt-driven)
  51. gpio_install_isr_service(0);
  52. // SPI bus configuration
  53. spi_device_handle_t spi_handle = NULL;
  54. spi_bus_config_t buscfg = {
  55.     .miso_io_num = CONFIG_ETH_SPI_MISO_GPIO,
  56.     .mosi_io_num = CONFIG_ETH_SPI_MOSI_GPIO,
  57.     .sclk_io_num = CONFIG_ETH_SPI_SCLK_GPIO,
  58.     .quadwp_io_num = -1,
  59.     .quadhd_io_num = -1,
  60. };
  61. ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
  62. // Configure SPI device
  63. spi_device_interface_config_t spi_devcfg = {
  64.     .mode = 0,
  65.     .clock_speed_hz = CONFIG_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  66.     .spics_io_num = CONFIG_ETH_SPI_CS_GPIO,
  67.     .queue_size = 20
  68. };
  69. /* w5500 ethernet driver is based on spi driver */
  70. eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_ETH_SPI_HOST, &spi_devcfg);
  71. w5500_config.int_gpio_num = CONFIG_ETH_SPI_INT_GPIO;
  72. esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  73. esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
  74.  
  75.  
  76. /////////////////////////////
  77. bool flow_ctrl_enable = true;/**/
  78.  
  79. esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
  80. esp_eth_handle_t eth_handle = NULL; // after the driver is installed, we will get the handle of the driver
  81.  
  82. esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable);/**/
  83.  
  84. esp_eth_driver_install(&config, &eth_handle); // install driver
  85.  
  86.  
  87.  
  88. esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable);/**/
  89.  
  90. uint8_t mac_addr[6] = {06,30,00,79,67,80};
  91. esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr);
  92.  
  93.  
  94.  
  95. ESP_ERROR_CHECK(esp_event_loop_create_default());
  96. esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL); // register Ethernet event handler (to deal with user-specific stuff when events like link up/down happened)
  97.    
  98.  
  99.     return eth_handle;
  100. }
  101.  
  102. /** Event handler for IP_EVENT_ETH_GOT_IP */
  103. static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
  104.                                  int32_t event_id, void *event_data)
  105. {
  106.     ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
  107.     const esp_netif_ip_info_t *ip_info = &event->ip_info;
  108.  
  109.     ESP_LOGI(TAG2, "Ethernet Got IP Address");
  110.     ESP_LOGI(TAG2, "~~~~~~~~~~~");
  111.     ESP_LOGI(TAG2, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
  112.     ESP_LOGI(TAG2, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
  113.     ESP_LOGI(TAG2, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
  114.     ESP_LOGI(TAG2, "~~~~~~~~~~~");
  115. }
  116.  
  117.  
  118. void nnetif(esp_eth_handle_t www){
  119.  
  120. esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); // apply default network interface configuration for Ethernet
  121. esp_netif_t *eth_netif = esp_netif_new(&cfg); // create network interface for Ethernet driver
  122.  
  123. esp_netif_attach(eth_netif, esp_eth_new_netif_glue(www)); // attach Ethernet driver to TCP/IP stack
  124. esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL); // register user defined IP event handlers
  125. esp_eth_start(www); // start Ethernet driver state machine
  126. }


My main code:
  1. void app_main(void)
  2. {
  3.     esp_eth_handle_t myEth = MyInitEth();
  4.    
  5.     esp_netif_init(); // Initialize TCP/IP network interface (should be called only once in application)
  6.      
  7.     nnetif(myEth);
  8.    
  9.     vTaskDelay(7000);
  10.    
  11.     xTaskCreate(My_SPI_Slave_task, "My_SPI_Slave", 4096, NULL, 5, NULL);
  12.  
  13.     //xTaskCreate(My_udp_server_task, "My_udp_server", 4096,NULL, 5, NULL);
  14. }

username
Posts: 538
Joined: Thu May 03, 2018 1:18 pm

Re: The W5500 + SPI_Slave driver does not work stably.

Postby username » Sun Oct 29, 2023 5:23 am

Just for curiosity, have your tried the ethernet basic example? IDF, takes care of inialising W5500.
I used it and never had a problem with it.
https://github.com/espressif/esp-idf/tr ... rnet/basic

Yuriy.Vasylenko
Posts: 2
Joined: Mon Oct 23, 2023 10:59 am

Re: The W5500 + SPI_Slave driver does not work stably.

Postby Yuriy.Vasylenko » Sun Oct 29, 2023 6:25 am

"Example Ethernet" also does not work with the SPIslave driver.
From the very beginning, my project was built on "Example Ethernet", and in it I saw that the SPIslave driver and the W5500 driver conflict together.

Who is online

Users browsing this forum: No registered users and 19 guests