The MAX32660 microcontroller includes a DMA engine that allows transferring data automatically from/to different peripherals to a specified memory location. Below is a limitation and workarounds for the limitation.
- A DMA transfer is set up using the DMAn_SRC source address register, the DMAn_CNT register to set the total length of the DMA transfer, and the DMAn_CFG.brst field to set the burst length.
- When a device like an SPI controller receives data, it places it into its FIFO until the data in the FIFO reaches the number of bytes specified in the DMAn_CFG.brst field, at which time it transfers the number of bytes in the burst to the destination (e.g. memory).
- The problem occurs at the end of the transfer when the DMAn_CNT number of bytes have been received by the SPI channel controller but the number of bytes in the FIFO are less than the number specified for the burst size. At that point, an interrupt is generated indicating that the transfer is complete, but there are still bytes in the FIFO that have not been transferred to the destination.
When the amount of data received from the peripheral is not a multiple of the burst size, this could translate into missing bytes at the end of the data burst.
There are three identified work arounds:
- Set DMAn_CFG.brst = 1, which insures that all bytes are transferred, but is inefficient in that it never uses the full width of the 32 bit bus.
- Put code in the interrupt service routine on transfer complete to check the byte count in the FIFO and programmatically transfer those bytes to the proper destination — not an elegant way to solve the problem.
- Always configure the DMA so that DMAn_CFG.brst is an integer divisor of DMAn_CNT — This is the recommended way of configuring the DMA, but it is not always possible depending on the peripheral device or data format.
All the above workarounds have been tested in a customer application that is using the DMA to move data from the SPI interface to the local memory.