AnsweredAssumed Answered

Kinetis L SPI DMA Priority

Question asked by Ryan Powers on Oct 5, 2015
Latest reply on Oct 14, 2015 by Ryan Powers

For starters, I am doing all this work on a KL27.


I've found a problem using both the KSDK 1.2 SPI driver in DMA mode, and the problem also exists in a custom SPI/DMA driver I wrote myself. It appears to be the exact same issue, and I believe it may be internal bus saturation.


Here's the setup:


I have two SPI devices connected to the KL27. It is master on both SPI instances. I can access either instance with high reliability at reasonable SPI clock speeds using either interrupt driven (for small transfers) or DMA (for bulk transfers). I've run SPI1 up to 5 MHz (I am limited here by the device's capability), and I've run SPI0 up to 8 MHz. At those speeds, I don't encounter any issues.


I've recently added double-buffering to a routine to copy from one device to the other. I will fill a buffer with a read from Device A, then start filling the second buffer with another read from Device A, followed by writing out the first buffer to Device B, etc, etc. When I use this configuration, at high clock speeds (I've only had reliable success at 1 MHz on each SPI instance) I will occasionally lose data on the receive side. When this happens, the transmit DMA channel has completed and is marked done, but the receive DMA channel is still some number of bytes shy of the end, and with no more data transmitting, it never completes. This isn't predictable at certain SPI clock speeds, and it doesn't always fail in the same spot.


The Freescale driver uses a lot of abstraction and indirection and I found it hard to follow, so that's why I implemented my own driver, but I found the same issue. I've setup the SPI receive for both to be on channels 0 & 1 (which should have the highest priority), with transmit on 2 & 3. It seems like somehow the transmit DMA is getting priority over the receive DMA.


I have tried setting the AXBS into round robin mode for arbitration, and that didn't seem to help at all. I guess I'm just confused as to why the transmit DMA is getting through, but the receive DMA isn't.


I could get rid of one DMA channel, as I don't need to have receive data on the destination SPI port, but that would complicate the driver substantially, as like Freescale's KSDK driver, mine uses the RX DMA complete to signal that the transfer is complete. I would have to change the code to select whether to use the transmit or receive DMA to signal end of transfer.


I am willing to try suggestions. Unfortunately, I am not able to share the driver code at all.