I'm using three DMA channels with SPI1 on a K64:
Channel A: Transfer 8-bit data from the client buffer to a fixed 32-bit "staging" location in memory. The upper bits set the command (CTAR, CS, CONT etc). Minor Loop: 1 byte. Major Iterations: Whatever the client requests though limited of course by the size of CITER. Minor and major link to channel B.
Channel B: Transfer the 32-bit staging value to PUSHR. Minor Loop: 4 bytes. Major Iterations: 1.
Channel C: Transfer POPR to the client RX buffer. Minor Loop: 1 byte. Major Iterations: Requested by client.
I attempt to send 0x01, 0x02, 0x04, 0x08. The scope shows 0x01, 0x02, 0x08 and the number of transfers on the SPI side shows 3 so this part jibes. It seems as if 0x08 overwrites 0x04 before it gets transferred to the shift register.
The SPI shows an RX FIFO overflow (I have the FIFO disabled so I assume this is just the POPR buffer). What's strange to me is that the DMA RX interrupt completes with a CITER of 4 but how can that be if the SPI counted 3 frame transfers? I cleared the TX/RX FIFOs for good measure before enabling the DMA requests and the RX FIFO drain flag is clear.
If this approach is flawed can someone point out the error of my thinking?
I messed with the DMA priorities but couldn't form a mental model to set these appropriately and it didn't seem to help.
I took a look at the SDK 2.4.2 EDMA/SPI driver and there is a note in there about handling things differently if the DMA requests numbers are the same for RX/TX. It also mentions the use of scatter/gather which seems like overkill to me. This is the case for SPI1 and SPI2 on the K64. SPI0 has different request IDs for RX/TX via DMAMUX.
My peripherals all require a constant chip select so CONT will always be selected except conditionally on the last byte (my driver interface allows the chip select to be left assert if needed).