8

使用 ESP-IDF (ESP32 SDK) 的 ESP32 应用程序与同一 SPI 总线上的两个 SPI 从机(ILI9341 TFT 驱动器,NRF24L01+ RF 收发器)进行通信。总的来说,它工作得很好。然而,从射频收发器接收到的一些数据被截断,即只有前几个字节是正确的,其余的都是垃圾。

该问题或多或少是可重现的,并且仅在接收截断数据之前立即与其他从机(TFT 驱动程序)进行 SPI 通信时才会发生。

有问题的 SPI 事务是一个全双工事务,它在接收 10 个字节的同时发送一个命令字节和 10 个虚拟字节。它使用 VSPI 总线和 DMA 通道 1。如果出现问题,只有前几个字节是正确的,而后 2 到 6 个字节是无效的(0 或虚拟字节的值)。

我深入研究了 SDK 代码 ( ),添加了调试代码,并在 DMA 的结构spi_master.c中观察到了一个令人惊讶的值:lldesc_t

在事务开始时,它用length = 0x0c和初始化size = 0x0c。0x0c 是 12 个字节,即四舍五入到下一个字的 10 个字节。

在事务结束时,值为length = 0x07size = 0x0c(长度可能略有不同)。所以事务只读取 7 个字节然后以某种方式终止。或者更确切地说,DMA 操作终止。

  • 您是否同意数据表明提前终止?
  • 提前终止的原因可能是什么?
  • 是否有一些寄存器可以指示问题的原因?

代码非常简单:

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);
4

1 回答 1

2

似乎以下警告——在SPI Slave 驱动程序文档中找到——也适用于从从机接收数据的 SPI 主机:]

警告:由于 ESP32 的设计特殊性,如果主机发送的字节数或从机驱动程序中的传输队列长度(以字节为单位)不大于 8 且不能被 4 整除,则 SPI 硬件可以未能将最后一到七个字节写入接收缓冲区。

我现在将发送方更改为发送至少 12 个字节和 4 的倍数,问题就消失了。

如果您认为它只是因为运气而起作用并且我的假设是错误的,那么现在让我说。

于 2018-03-25T11:52:26.563 回答