oh, the SPI controller of the iMX7 is really tricky, now I understand whats going on internally …
Check out this:
“Since the shift register always loads 32-bit
data from transmit FIFO, only the n least-significant (n = BURST LENGTH + 1) will be shifted out. The remaining BITS will be ignored.”
Ok, the data buffer size must be greater than the actual data, if the lenght isn’t mod 4. The FIFO needs this and the OS may be angry if we don’t respect that.
The table above is counting BITS. There is the possibility to transfer only 1 BIT, which is totally unusual (for me).
If I read this table correct, this means:
BURST_LENGHT = 0x7 … 1 byte transfer
BURST_LENGHT = 0x0f … 2 byte transfer
BURST_LENGHT = 0x17 … 3 byte transfer
BURST_LENGHT = 0x1f … 4 byte Transfer
BURST_LENGHT = 0x27 … 5 Byte transfer, LSB of first word and all 4 bytes of second word, wow.
BURST_LENGHT = 0x2f … 6 byte transfer
Proof: BURST_LENGTH = 0x2f ==> 47 ==> n = 47 + 1 ==> 48 / 8 = 6 (bytes) qed.
WOW, really ‘cool’ method to calculate the burst length for a byte-oriented interface.
A quick and dirty idea how I will solve that:
I get a pointer to a buffer (bytes) and a length.
The longest burst possible is 2^7 words, if the buffer we got is longer than 2^7 * 4 Bytes we have to split the transfer. This means not to bring ~CS high, this only means that we have to use DMA to prepare the next chunk of data in time.
I do not know, if this machine is big endian or little endian. So dependent of that fact, we have to adust the buffer to be able to do transfers with length mod 4 != 0.
Maybe using a own buffer and copying the data there is a safe method to do that. The user didn#t have to check for buffer length mod 4.
Calculate the BURST_LENGTH field according to the upper formular.
if transfer_length > 512, write 0xfff to the BURST_LENGTH field.
Adjust pointer, adjust counter of bytes left.
Write bytes_to_send * 8 -1 to the BURST_LENGHT field and we were done.
For my application for instance:
630 > 512, yes, write 0xfff to the BURST_LENGHT field, 630 - 512 = 118 bytes left.
118 > 512, no, 118 * 8 - 1 = 943, write 0x3AF to BURST_LENGHT.
I am save for now, only using transfers of length mod 4, but for the future, 1 Byte transfers or multiple of one byte should be possible as this is SPI interface standard.
With best regards