spi_device_polling_transmit(...) in DMA mode muzz support 5-, 9-, etc-bytes I/O sessions with 1-byte Tx and Rx (IDFGH-13038)
Answers checklist.
- [X] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- [X] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- [X] I have searched the issue tracker for a similar issue and not found a similar issue.
IDF version.
ESP-IDF v5.2.1-dirty
Espressif SoC revision.
ESP32 chip revision: v3.1
Operating System used.
Windows
How did you build your project?
Eclipse IDE
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32 WROOM
Power Supply used.
USB
What is the expected behavior?
spi_device_polling_transmit(handle, &t) populates ALL t.length (== 72) bits of t.rx_buffer with received data, not only first 64 bits.
What is the actual behavior?
t.length = 8 * 9;
t.tx_buffer = (unsigned char*){ 0xF7 };
t.rxLength = 8 * 8;
t.rx_buffer = (unsigned char*){ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
spi_device_polling_transmit(spiDevice, &t);
SPI I/O flows successfully and results in following activity on CLK / MISO lines:
note 72 total CLK pulses and '00 0x80 00 00 0x80 00 00 0x80 00' stream on MISO line. so, exactly MISO data is expected in t.rx_buffer after all. but it has '00 0x80 00 00 0x80 00 00 0x80 9' instead - last byte is dropped.
bus activity indicates: all 9 bytes processed by SPI hardware.
Steps to reproduce.
Implement described SPI IO with multiple of 32-bits(of 4-bytes) + 1 byte total I/O length: 1-byte Tx and 4, 8, 12, ... Rx. enjoy only multiple-of-32 bits(multiple-of-4 bytes) of received data is transferred into t.rx_buffer and last byte is dropped.
@powerbroker Hello, As you see, it not a bug, it driver design as this,,,
- If you only set
t.length = 8 * 9;, tx and rx will be same length - If you set
t.length = 8 * 9;andt.rxLength = 8 * 8;, it will trans 8 * 9 in hardware but write only 8 * 8 of rx buffer t.rxLength > t.lengthis not allowed
@powerbroker A bit different,
You can understand as rx buffer is align to start, so if rx length one smaller then tx length, it still not you want.
you can consider configure devices as devcfg.command_bits = 8 then using spi_transaction_t::cmd to send you command, this length don't belong to t.length, then simply using t.length as your rx length.
@powerbroker
devcfg.command_bits is originally the feature for this condition, it not any kind of workaround,,
In idf there is devcfg.command_bits support 0-16 bits, and devcfg.address_bits support 0-64 bits, which handle many kind of devices not only 1+6
and btw, actually your case is ony half-duplex transaction, any other chips if you using full-duplex mode you need also handle tail-align by yourselves. anyway, there is many way to archive this with little difference, you can freely select one as your workaround.
@powerbroker Hello, If no problem, please close this issue, thanks
You can manual control CS or use flags==SPI_TRANS_CS_KEEP_ACTIVE and do multiple SPI transactions to form one with exactly what you need.