volkeroth

Chaining DMA channels on LPC824

Discussion created by volkeroth on Sep 4, 2017
Latest reply on Sep 6, 2017 by volkeroth

I'm struggling to implement DMA chaining on the LPC824 and beginning to wonder if what I'm trying to do is possible at all on the LPC824.

For a start, I already have a working DMA based UART implementation that writes received bytes to a ring buffer using a ping-pong transfer descriptor approach (USART0 -> DMA channel 0).

Now what I'm trying to do is to implement a timeout if no byte was received for a certain time (let's say 300µs). So only after the timeout happened after the last byte received I get an interrupt which wakes the CPU from sleep to check received bytes.

 

My idea was to write a new value to the MRT0 interval register (with the force load flag set) each time a byte is received by a 2nd DMA channel chained to the UART receive DMA transfer. As chaining only seems to work when the transfer descriptor is exhausted, I swapped the channels, I.e. I'm using channel 0 (the UART RX dma channel) to write the new MRT0.INTVAL value and then chain to another channel (channel 9 in my current prototype) that is used to handle the UART receive ring buffer which was done by channel 0 before.

To make a long story short, I got this working to some degree but each time the chained channel (9) is triggered, it doesn't write a single byte as expected, but instead copies the same byte to the whole ring buffer until the transfer descriptor is exhausted.

 

I'm starting to wonder if it's actually possible to create a single transfer request by chaining.

I set up the channels as described in the manual (i.e. HWTRIGEN=1, TRIGPOL=0, TRIGTYPE=0) but as far as I can tell, the TRIG flag in CTLSTAT9 stays high and causes a permanent transfer from the UART RX register until the descriptor is exhausted. So while the manual warns about that this can happen for level triggering, the edge triggering used here doesn't seem to make any difference at all.

Actually, the whole concept of TRIG flags and HW triggers vs. DMA requests seems somewhat weird and is not properly described in the manual. As is the concept of having to clear the TRIG flags at RELOAD.

It's a bit frustrating that something as simple as linking two DMA channels seems to be a minefield of vaguely described flags and requires such a complex setup which isn't even working as expected in the end.

 

In a nutshell: is there a way to link ("chain") from a DMA channel triggered by peripheral DMA request (UART receive) to a 2nd channel in a way that each end of transfer on the 1st channel actually only triggers a single transfer on the chained channel instead of causing permanent transfers until the descriptor of the chained channel is exhausted?

Outcomes