ESP32 SPI Master <--- ESP32 SPI Slave occasional data corruption

danjulio
Posts: 15
Joined: Tue Feb 25, 2020 9:00 pm

ESP32 SPI Master <--- ESP32 SPI Slave occasional data corruption

Postby danjulio » Thu Jun 03, 2021 4:02 am

I have an application split across two ESP32 devices. With adequate handshaking I am using a one-way SPI interface (CSN, SCK, MISO) to move blocks of approximately 51 kBytes of data from one ESP32 (configured as a SPI Slave) to a second ESP32 (configured as a SPI Master). I perform a transfer about every 115 mSec using an ~6.15 MHz SPI Clock (request 6 MHz). Each ESP32 is also busy with other activities and both ESP32 chips are using their second SPI interface as a Master to communicate with other devices (The Master ESP32 communicates with a LCD display updating an image for every transfer and the Slave ESP32 communicates with a sensor generating a lot of data). About 5-10% of the blocks of data experience corruption. Signal quality is very good as verified using an oscilloscope with good ground connections (minimal ground loop paths) with plenty of setup and hold.

I looked at the drivers (IDF v4.0.1) a little and it appears that my large data block must be handled as smaller chunks by the DMA engines (4092 byte maximum?) although I'm not entirely sure what the driver's are doing. I wonder if the ESP32's DMA engine in the slave device isn't being (re)triggered quickly enough in an ISR for one or more of the chunks.

I have tried to increase the FreeRTOS priority for the tasks handling the SPI transactions with little effect. My questions are if anyone has experience and advice for using the SPI Slave with large data blocks. Are there things I should be doing to ensure that the Slave can keep up with the Master?

My slave is setup as follows (Mode is 0)

Code: Select all

spi_slave_interface_config_t spi_slvcfg={
	.mode=HOST_SPI_MODE,
	.spics_io_num=HOST_CSN_IO,
	.queue_size=1,
	.flags=0,
	.post_setup_cb=_sys_spi_slave_post_setup_cb,
	.post_trans_cb=_sys_spi_slave_post_trans_cb
};
and triggered

Code: Select all

spi_slave_t.length=len*8;
spi_slave_t.tx_buffer=buf;
spi_slave_t.rx_buffer=NULL;
    
if (spi_slave_queue_trans(HOST_SPI_HOST, &spi_slave_t, portMAX_DELAY) == ESP_OK) {
    return true;
}
I wait until the post_setup_cb is called before informing the Master ESP32 to initiate a SPI transaction and I call spi_slave_get_trans_result after the post_trans_cb is called. The len variable is set to a 4-byte boundary length and the SPI master transfers are always 4-byte aligned and of that length. Buffers are in DMA capable memory (looks like the drivers check this and more - and I get no errors from the drivers).

Who is online

Users browsing this forum: No registered users and 223 guests