使用ESP-IDF(ESP32 SDK)的ESP32应用程序与同一SPI总线上的两个SPI从站(ILI9341 TFT驱动程序,NRF24L01 + RF收发器)进行通信。总的来说,它很棒。但是,从RF收发器接收的一些数据被截断,即只有前几个字节是正确的,其余的都是垃圾。
问题或多或少是可重现的,只有在接收截断数据之前与其他从设备(TFT驱动程序)进行SPI通信时才会出现问题。
有问题的SPI事务是一个全双工事务,它在接收10个字节时发送一个命令字节和10个哑字节。它使用VSPI总线和DMA通道1.如果出现问题,只有前几个字节正确,而最后2到6个字节无效(0或虚拟字节的值)。
我挖掘了SDK代码(spi_master.c
),添加了调试代码并在DMA的lldesc_t
结构中观察到了一个令人惊讶的值:
在交易开始时,它会使用length = 0x0c
和size = 0x0c
进行初始化。 0x0c是12个字节,即10个字节四舍五入到下一个字。
在交易结束时,值为length = 0x07
和size = 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);
答案 0 :(得分:0)
似乎以下警告 - 在SPI Slave driver documentation中找到 - 也适用于从主站接收数据的SPI主站:]
警告:由于ESP32的设计特点,如果量 主机发送的字节数或传输队列的长度 从驱动程序(以字节为单位)不大于8和 可分为四个,SPI硬件可能无法写入最后一个 七个字节到接收缓冲区。
我现在已经将发送方改为发送至少12个字节和4的倍数,问题就消失了。
如果你认为它只是因为运气而且我的假设是错误的,那就现在让我吧。