Page 1 of 1

ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 10:15 am
by FrankJensen
Hi there.

I have some code, that is working with WIFI flawlessly. But due to a special application, I need to run it wired, and having used the W5500 before (on arduino framework), I was happy to learn that there are direct support for W5500 in the ESP32.

And basically, the sample codes that I found, are working. I use a esp_http_client, and the esp_http_server.

And its working - sort of......
I have the webinterface, and communication with http_client. But the responsetime is really, really slow.

EG, a simple submit from my webpage, with only 63 bytes of data, takes around 60ms using WIFI, but using LAN and the W5500 the responsetime is 1.32 seconds.... It is simply just pending. Setting my timeout for the http_client as 2 seconds to prevent timeout, is actually works, and received aroung 10k of data. Again, it just seems to be pending for a long time, before action.

I have tried various stuff, but nothing seems to help. It does not seem, that its the newwork traffic as such, that is slow. its more, why is it pending for more than a second for no reason...

Any help would be apreciated...

My initialiazation code:
  1. void MyLAN::ethernet_init(void)
  2. {
  3.     gpio_reset_pin(GPIO_NUM_43); // free uart0
  4.     gpio_reset_pin(GPIO_NUM_44); // free uart0
  5.    
  6.     ESP_ERROR_CHECK(esp_netif_init());
  7.  
  8.     // Create default event loop that running in background
  9.     ESP_ERROR_CHECK(esp_event_loop_create_default()); // ****
  10.    
  11.     // Register user defined event handers
  12.     ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &EthernetHardwareEventHandler, NULL));
  13.     ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &EthernetIpEventHandler, NULL));
  14.  
  15.     //  Create instance(s) of esp-netif for SPI Ethernet(s)
  16.     esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
  17.     esp_netif_config_t cfg_spi = { };
  18.         cfg_spi.base = &esp_netif_config;
  19.         cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
  20.  
  21.     esp_netif_t* eth_netif_spi = NULL;
  22.     char if_key_str[10];
  23.     char if_desc_str[10];
  24.     char num_str[3];
  25.     itoa(0, num_str, 10);
  26.     strcat(strcpy(if_key_str, "ETH_SPI_"), num_str);
  27.     strcat(strcpy(if_desc_str, "eth"), num_str);
  28.     esp_netif_config.if_key = if_key_str;
  29.     esp_netif_config.if_desc = if_desc_str;
  30.     esp_netif_config.route_prio = 30;
  31.     eth_netif_spi = esp_netif_new(&cfg_spi);
  32.  
  33. if (eth_netif_spi == NULL) printf("Jo, den er nul 1\n");
  34. else printf("Den er i det mindste ikke nul 1\n");
  35.  
  36.     // Init MAC and PHY configs to default
  37.     eth_mac_config_t mac_config_spi = ETH_MAC_DEFAULT_CONFIG();
  38.  
  39.     eth_phy_config_t phy_config_spi = ETH_PHY_DEFAULT_CONFIG();
  40.     phy_config_spi.autonego_timeout_ms = 0;
  41.     phy_config_spi.reset_gpio_num = -1;
  42.  
  43.     ESP_LOGD(TAG, "Installing isr service");
  44.     gpio_install_isr_service(0);
  45.  
  46.     // Init SPI bus
  47.     spi_bus_config_t buscfg = { };
  48.         buscfg.miso_io_num = GVs->Board->io_sdi0.MISO; // ETHERNET_SPI_MOSI_GPIO;
  49.         buscfg.mosi_io_num = GVs->Board->io_sdi0.MOSI; // ETHERNET_SPI_MISO_GPIO;
  50.         buscfg.sclk_io_num = GVs->Board->io_sdi0.CLK;  // ETHERNET_SPI_CLK_GPIO;
  51.         buscfg.quadwp_io_num = -1;
  52.         buscfg.quadhd_io_num = -1;
  53.     ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
  54.  
  55.     // Configure SPI interface and Ethernet driver for specific SPI module
  56.     esp_eth_mac_t* mac_spi;
  57.     esp_eth_phy_t* phy_spi;
  58.     esp_eth_handle_t eth_handle_spi = NULL;
  59.     spi_device_interface_config_t spi_devcfg = { };
  60.         spi_devcfg.command_bits = 16; // Actually it's the address phase in W5500 SPI frame
  61.         spi_devcfg.address_bits = 8;  // Actually it's the control phase in W5500 SPI frame
  62.         spi_devcfg.spics_io_num = GVs->Board->io_sdi0.SS; // ETHERNET_SPI_CS_GPIO;
  63.         spi_devcfg.mode = 0;
  64.         spi_devcfg.clock_speed_hz = 33 * 1000 * 1000; // org. 33
  65.         spi_devcfg.queue_size = 20;
  66.  
  67.     // Set remaining GPIO numbers and configuration used by the SPI module
  68.     phy_config_spi.phy_addr = 1;
  69.  
  70.     eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(SPI2_HOST, &spi_devcfg);
  71.     w5500_config.int_gpio_num = GVs->Board->io_sdi0.INT; // ETHERNET_SPI_INT_GPIO;
  72.     mac_spi = esp_eth_mac_new_w5500(&w5500_config, &mac_config_spi);
  73.     phy_spi = esp_eth_phy_new_w5500(&phy_config_spi);
  74.  
  75. vTaskDelay(pdMS_TO_TICKS(10)); // wait for w5500 to startup
  76.  
  77.     esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac_spi, phy_spi);
  78.     ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config_spi, &eth_handle_spi));
  79.  
  80.     uint8_t mac_addr[6];
  81.     esp_read_mac(mac_addr, ESP_MAC_ETH);
  82.     ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle_spi, ETH_CMD_S_MAC_ADDR, mac_addr));
  83.  
  84. if (eth_netif_spi == NULL) printf("Jo, den er nul 2\n");
  85. else printf("Den er i det mindste ikke nul 2\n");
  86. if (eth_handle_spi == NULL) printf("Jo, den er nul 3\n");
  87. else printf("Den er i det mindste ikke nul 3\n");
  88.  
  89.  vTaskDelay(1000/portTICK_PERIOD_MS);
  90.  
  91.     // attach Ethernet driver to TCP/IP stack
  92.     ESP_ERROR_CHECK(esp_netif_attach(eth_netif_spi, esp_eth_new_netif_glue(eth_handle_spi)));
  93.  
  94.     /* start Ethernet driver state machine */
  95.     ESP_ERROR_CHECK(esp_eth_start(eth_handle_spi));
  96. }

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 11:18 am
by FrankJensen
Additional info.

The W5500 is alone on the SPI buss, so no other data.

The breakdown of the request is like this, where the total response using WIFI is less than 60ms.

Chrome:
Request/Response DURATION
Request sent 0.19 ms
Waiting for server response 263.53 ms
Content Download 959.23 ms
1.22 s

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 12:23 pm
by DrMickeyLauer
Do you have the HW INT PIN connected?

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 12:27 pm
by FrankJensen
Hi Mickey.

Yes. It should be. Will it work without?

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 12:34 pm
by DrMickeyLauer
Yes, it _can_ work without, but you will get bad latencies, since the driver will resort to polling.
In some designs, I have seen this missing, and upon latency complaints this is always the first question I'm asking.

BTW., why are you initialising this on your own? I'd use the EthernetInit component from ESP-IDF.

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 12:40 pm
by FrankJensen
I have enabled W5500 in menuconfig, and I use the config as posted here. Thats it. I will put my scope on INT, and check if there is activity.

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 12:59 pm
by FrankJensen
Thank you, Mickey :-)

I did not look into interupt, cause I thought it would not work without.

i could see activity with my scope.

So I added this in my code, and now latency is gone. Aparently the input is not automatically setup correctly, when setting up the parameters.

gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_NEGEDGE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = 1ULL<<GPIO_NUM_43;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Fri May 10, 2024 1:38 pm
by DrMickeyLauer
Glad you got it sorted out!

Re: ESP32-S3 with W5500 reeeealy slow performance

Posted: Mon May 13, 2024 8:09 am
by ESP_ondrej
Hi FrankJensen, could you please double check that you initialized the Ethernet driver correctly? The thing is that basically exactly the same interrupt initialization as yours is performed by the driver:

Code: Select all

        esp_rom_gpio_pad_select_gpio(emac->int_gpio_num);
        gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT);
        gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLUP_ONLY);
        gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_NEGEDGE); // active low
        gpio_intr_enable(emac->int_gpio_num);