espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.28k stars 7.2k forks source link

Spi Slave bad performances at 40Mhz (IDFGH-6899) #8519

Open tbultel opened 2 years ago

tbultel commented 2 years ago

Environment

Problem Description

ESP32S3 Slave Spi performances issue

The SPI Slave is documented as capable to operate at 60Mhz The CPU freq is set to 240 Mhz

I use it at 40Mhz, signals shown below (there are 24 squares, incoming data is 3 bytes long):

timing_500k

The issue is that I do not get as many packets as expected; using a counter and checking with the time, my estimate is a rate of 47,9 kHz, less than a tenth of what is expected.

Is there a way to increase the slave Spi performances ?

Expected Behavior

The data should come at 500 kHz

Actual Behavior

Data comes at 47.9kHz

ginkgm commented 2 years ago

Hi @tbultel ,

Is the second row the CLK or data? Please provide all 4 wires so that we can see what's the response of ESP32-S3 SPI Slave.

And another question, what's the sample rate of your logic analyzer when capturing this?

Michael

tbultel commented 2 years ago

Hi, The first line is CS, the second is CLK. Both are generated by the RMT. The analyser is a Saleae Logic 9, I assume that the malformed square wave is due to its sampling limitations, so just a display effect. But since the Slave SPI interrupt is only triggered by CS change, a malformed CLK signal does not have an impact on performances.

After longer analysis I conclude that the SPI Slave it missing polling routines that could let the user application to get rid of internal message queues and huge interrupt latency.

ginkgm commented 2 years ago

Till now, Espressif's SPI Slave full duplex mode requires a out-of-band synchronization - only when the slave is ready to receive data, the master can start a transmission. You can see this in the example:

https://github.com/espressif/esp-idf/blob/master/examples%2Fperipherals%2Fspi_slave%2Fsender%2Fmain%2Fapp_main.c#L179

https://github.com/espressif/esp-idf/blob/master/examples%2Fperipherals%2Fspi_slave%2Freceiver%2Fmain%2Fapp_main.c#L72

The interval is determined by the SW - how long the driver requires to handle the previous data. The typical value is about 20~30us, but there's no guarantee for the time - this is why a reliable synchronization method is still needed.

For the half duplex mode, the non-DMA part can respond to master's requests quickly, but for the data transfer, SW response is still required. The main difference is that the synchronization can be done via SPI.

ginkgm commented 2 years ago

And btw, the 60MHz in the spec is not a clue for the interval of CS.

tbultel commented 2 years ago

I was finally able to reach the performances I wanted, by locking interrupts and polling on the interrupt bit in my RT task. Maybe such a mode should be available as a standard option in the driver? The message queues overhead is far to big to fit the rate I wanted, because as the datagram shows it, I only have 2 microseconds to get the data.