An ESP32 application using the ESP-IDF (ESP32 SDK) communicates with two slave SPIs on the same SPI bus (ILI9341 TFT driver, NRF24L01 + RF transceiver). All in all, it works great. However, some data received from the radio transceiver is truncated, that is, only the first few bytes are correct, and the rest is garbage.
The problem is more or less reproducible and arises only when there is an SPI connection with another slave (TFT driver) immediately before receiving truncated data.
The problematic SPI transaction is a full duplex transaction that sends command bytes and 10 dummy bytes when receiving 10 bytes. It uses the VSPI bus and DMA channel 1. If a problem occurs, only the first few bytes are correct, while the last 2-6 bytes are invalid (0 or dummy bytes).
I dug up the SDK code ( spi_master.c ), added the debug code, and noticed an amazing value in the lldesc_t DMA lldesc_t :
When a transaction starts, it is initialized with length = 0x0c and size = 0x0c . 0x0c is 12 bytes, i.e. 10 bytes rounded to the next word.
At the end of the transaction, the values length = 0x07 and size = 0x0c (the length may vary slightly). Thus, the transaction reads only 7 bytes, and then somehow ends. Rather, DMA operations are completed.
- Do you agree that the data indicates early completion?
- What could be the reason for early termination?
- Are there any registers that could indicate the cause of the problem?
The code is pretty simple:
uint8_t* buffer = heap_caps_malloc(32, MALLOC_CAP_DMA); ... memset(buffer, CMD_NOP, len); spi_transaction_t trx; memset(&trx, 0, sizeof(spi_transaction_t)); trx.cmd = 0x61; trx.tx_buffer = buffer; trx.length = 8 * 10; trx.rx_buffer = buffer; trx.rxlength = 8 * 10; esp_err_t ret = spi_device_transmit(spi_device, &trx);