Strugling with Ethernet + time critical SPI+MCPWM

rob_bits
Posts: 16
Joined: Wed Jun 13, 2018 5:15 am

Strugling with Ethernet + time critical SPI+MCPWM

Postby rob_bits » Thu Jan 05, 2023 12:35 pm

I have a problem that I cannot figure out and I runs out ideas...

I am using a unique hardware with ESP32Wrover module. I am using Platformio with arduino and idf framework, platformio 5.3.0 release (Arduino v2.0.6 and ESP-IDF to v4.4.3).

The following functionalities needs to be implemented:
1. Ethernet with webserver functionality
2. time critical SPI measurement with 20MHz SPI clock, x4 burst measurement, chip select stretching, 18us period. Reading must be continuous.
3. Two channel PWM signal ~8kHz frequency which is enabled for 100ms and disabled for 900ms (implemented with MCPWM)

All of the functions are implemented and working well, separately.. To have a deterministic operation I assigned all measurement related stuffs to Core 1 as it is described in this thread:
https://esp32.com/viewtopic.php?f=2&t=1 ... 51#p107851

The interrupts on Core1 are disabled, watchdog on core1 disabled, delay() function never called, all functions and variables are in RAM (DMA_ATTR and IRAM_ATTR attributes are used).

The core0 doing ethernet stuff and core1 doing measurement. Core1 has additional algorithms for filtering the measurement data. However if the SPI measurement is running or the PWM signal is active on the output the ethernet becomes broken (the device does not get IP address and it connects / disconnects repeatedly). If the SPI measurement and MCPWM are disabled the ethernet work perfectly.

If I use the following code on core1, and call it periodically:

Code: Select all

  SPI2->data_buf[0] = *txBuf;
	// Start transfer
  spi_ll_master_user_start(SPI2);

  while (SPI2->cmd.usr); // Wait for SPI bus ready
  *rxBuf = (uint16_t) SPI2->data_buf[0];
the ethernet got broken. Or if I just call the spi_ll_master_user_start() funciton and waiting for the SPI2->cmd.usr, periodically, without bothering the data_buf[] still I got corrupted ethernet operation... If I remove this code from core1 the ethernet works.

What can be the problem?

Does the SPI share any resource with the Ethernet mac? Do the core 1 reserves any internal bus with causes failure?

rob_bits
Posts: 16
Joined: Wed Jun 13, 2018 5:15 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby rob_bits » Fri Jan 06, 2023 8:04 am

The second thing that I havent described, if the SPI is not used at all on CORE1, however if I enable the MCPWM on GPIO the ethernet also got broken.

Especially if I call this line of code during initialization:

Code: Select all

esp_rom_gpio_connect_out_signal((gpio_num_t)20, mcpwm_periph_signals.groups[MCPWM_UNIT_0].operators[0].generators[0].pwm_sig, 0, 0);
If I uncomment this line of code, the ethernet work perfectly. Why?

What is the code behind esp_rom_gpio_connect_out_signal() ?

I created an issue about this problem:
https://github.com/espressif/arduino-esp32/issues/7670

I could reproduce it with a basic example (not messing with CORE0/CORE1 stuff).

Any comment would be appreciated.

ESP_ondrej
Posts: 207
Joined: Fri May 07, 2021 10:35 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby ESP_ondrej » Fri Jan 06, 2023 5:15 pm

SPI and EMAC share the DMA Controller. You can try to play with `dma_burst_len` configuration of `eth_esp32_emac_config_t`. However, I am not sure if it helps you. It seems you use the SPI quite extensively based on your description.

You could also try to not use DMA for your SPI transactions to see if it helps to make Ethernet working. However, again, I am not sure if such solution would pass your timing requirements...

Code: Select all

ret=spi_bus_initialize(VSPI_HOST, &buscfg, 0);
Regarding that PWM issue, I'll try to have a look at it in more details and let you know.

rob_bits
Posts: 16
Joined: Wed Jun 13, 2018 5:15 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby rob_bits » Mon Jan 09, 2023 1:51 pm

Hey @ESP_ondrej, thanks for the comment

You mentioned:
you use the SPI quite extensively
What do you think, What is the bottleneck of my problem?

So when SPI is reading/writing RAM with ~4.5us period (x4 transfer during 18us period), does it blocks the internal memory bus for too long and that causes issues with Ethernet?

The CPU at 180MHz has a clock period of ~6ns. So theoretically for 750 clock (4.5us / 0.006us) I have one memory read/write. The core still has plenty of resource to do other stuffs. And CORE 1 is doing all the SPI related stuff while CORE0 could do any other stuff.

ESP_ondrej
Posts: 207
Joined: Fri May 07, 2021 10:35 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby ESP_ondrej » Mon Jan 09, 2023 3:36 pm

Frankly speaking I didn't perform any detailed analysis since I don't know your code and I'm not SPI expert. I based it on assumption that Polling Transaction via DMA takes 10 µs as per https://docs.espressif.com/projects/esp ... n-duration.
Therefore accessing the SPI every 18 us seems quite extensive to me from this point of view.

rob_bits
Posts: 16
Joined: Wed Jun 13, 2018 5:15 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby rob_bits » Fri Jan 13, 2023 3:15 pm

ESP_ondrej wrote:
Mon Jan 09, 2023 3:36 pm
Frankly speaking I didn't perform any detailed analysis since I don't know your code and I'm not SPI expert. I based it on assumption that Polling Transaction via DMA takes 10 µs as per https://docs.espressif.com/projects/esp ... n-duration.
Therefore accessing the SPI every 18 us seems quite extensive to me from this point of view.
Hey, I did a couple of experiments this week. And I fixed a lot of issues but still the Ethernet + SPI does not work properly. So First I implemented WiFi + SPI + MCPWM and it is working like a charm. First I had to add more buffer capacitor (100uF instead of 20uF) to the supply line of the ESP32 then I need to play with the RAM usage. There was a dummy unused 30kB RAM allocation which lead to small free heap memory and causes issues. After fixing these the Wifi works perfecly. No disconnections, the data can be read without any issues with SPI at a high rate that I discussed.

However for Etherenet, if Ethernet + SPI are configured (so WiFi is disabled) I do not get IP address. The Ethernet gets to the Connected phase but no IP. Strange... I have 69kB heap memory when the Ethernet Connected event triggers.

rob_bits
Posts: 16
Joined: Wed Jun 13, 2018 5:15 am

Re: Strugling with Ethernet + time critical SPI+MCPWM

Postby rob_bits » Mon Jan 16, 2023 1:11 pm

I created an issue on github with an example code:
https://github.com/espressif/arduino-esp32/issues/7719

Hopefully someone will have any idea to debug the issue.

Who is online

Users browsing this forum: No registered users and 79 guests