Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
I'm using a DMA002 app and would like to set up "ping pong" buffers, where the DMA002 would point to alternating buffers for DMA transfers.

I'm using the DMA002_GetChannelTransferParams() and DMA002_SetChannelTransferParams() to adjust the DstAddress during runtime but it doesn't seem to be affecting the destination address. DMA002_SetChannelTransferParams() always returns DMA_EBUSY, doing a spin-loop waiting on the status to -not- be DMA_EBUSY seems to indicate that this flag never goes off, and there doesn't seem to be a way to stop the DMA002 app via API (i.e. no DMA002_StopTransfer()). The DMA002 app continues filling "buffer A" like it always has, while "buffer B" is never used.

To clarify, the DMA002 app has been working very well so far with a single buffer. The issue isn't with getting the DMA002 app running, it's with changing any of the parameters during runtime. The comments in DMA002.h seem to indicate that "runtime" configuration is possible.

Thanks in advance,
Joe Shidle
Delta Mobile Systems
4 Replies
First solution authored Welcome! 500 replies posted
Hi JoeShide, I am looking into your case and will update this thread if there is some findings.
lock attach
Attachments are accessible only for community members.
10 sign-ins 5 sign-ins First like received
Hi JoeShidle,

It is not possible to change the DMA channel parameters when the channel is enabled.
In your case the solution would be to use linked lists. Two linked list items, LLI, need to be defined in system memory. The LLIs are linked to one another using the LLP field of the LLI structure. A circular reference is created.
The destination address of LLI(1) is bufferA and the destination address of LLI(2) is bufferB.
If the block size is configured as 1024, the DMA will start transfering 1024 data items to bufferA, and then switch to bufferB. Once finished with the second transaction the whole process starts again using buffer A.


Attached you find a project showing this concept.

Let me know if need more assistance.

Best regards,
Not applicable
Thanks for the responses. I'll look into the attached project and give it a try.
Not applicable

I also just created a circular linked list to transfer a buffer to the DAC in an endless loop (DMA).
This works fine as long as I set both SRC and DST size for a single transaction to 32 bits.
When I set the SRC transaction size to 16 bits and leave the DST at 32 bits the block will be transferred as expected but at the end of this block the DMA (CH0) does not reload.
I use Row 10 of Table 5-5 for all blocks (to avoid the possibility of suspend after block, although I don't hae any INT enabled).
Since the DMA updates the status in the LLI one can see that all blocks witth SRC 32bit have been completed (DONE set).
The block with SRC 16 Bit has been transferred, the SAR register in the DMA reflects that. The CTLL in the DMA also is reloaded to the block size, but the DONE bit of that block ist not set in the LLI. The DMA has stopped at the end of that block, although it should reload - I changed only the SRC transfer size.

Is there a limitation that reloading works only if SRC size of a memory transfer is set to 32 bits?
I didn't find such a limitation in the manual.

On a related note: The manual says that the DONE bits in the LLI blocks should be cleared before starting the channel. With a circular list running the status updates will have set all DONE bits after the first circle (if I don't clean up "manually". However, since it works I assume the only negative effect is that I can't tell when a particular block has been completed again?

Best regards,