LPC1769 UART selective DMA operation(between RX and TX)

Showing results for 
Search instead for 
Did you mean: 

LPC1769 UART selective DMA operation(between RX and TX)

NXP Employee
NXP Employee
Content originally posted in LPCWare by gnxp on Mon Aug 10 09:17:36 MST 2015
Hello All,
I wish to use GPDMA for asynchronous UART communication from a ring-buffer.

UART TX DMA is straightforward.

Now, UART RX DMA needs to know size of bytes to be received. To receive variable sized transfers, I plan to use a timer with duration of say 16 bytes. On each timer expire interrupt, I will check the transferSize value(control register of DMA channel used for UART DMA Rx). If the value is changing, just reload the timer to check again. If the value is unchanging call a RxCallback function.

What I wish to do is selectively enable and disable UART RX DMA.
- So UART Rx interrupt(non DMA) will be enabled to begin with.
- If any byte received, in the receive interrupt  set up a DMA desc of maximum expected size, disable UART Rcv interrupt and enable timer.
-When transferSize stops changing, stop DMA, disable timer, reenable UART Rcv and call RxCallback function.

User manual UM10360 is incomplete in describing GPDMA operations. I have used PL080 as reference. Now
UM10360  says in section ' DMA Operation' (pg 314, Rev. 3.1 2/4/14)

The user can optionally operate the UART transmit and/or receive using DMA. The DMA
mode is determined by the DMA Mode Select bit in the FCR register. This bit only has an
affect when the FIFOs are enabled via the FIFO Enable bit in the FCR register.

But there is only one bit to select FIFO and DMA modes. They affect both UART RX and TX. I cannot find any reference to how to selectively enable/disable UART RX dma. Does anyone have other ideas?

In absence of selectively controlling RX UART DMA, one option is to reserve a DMA ch for it, keep timer running always and use above logic for callback. I would prefer to not have timer interrupts all the time. If anyone has implemented a similar scheme, please elaborate.


Labels (1)
0 Kudos
2 Replies

NXP Employee
NXP Employee
Content originally posted in LPCWare by gnxp on Wed Aug 12 02:02:53 MST 2015
Thanks Mike,
That is what I did ended up doing. Setting up  a DMA descriptor for UART RX from beginning of ringbuff to the end. On transfer completion, interrupt triggered which repeats the process, effectively wrapping the ringbuff. I use a timer to look out for 'quiet time' which I do by comparing new and old 'TransferSize' in DMA channel control register. Of course, all this is still being tested. What I was actually looking for was how to selectively enable disable between UART RX/TX DMA. That is what the user manual claims is possible, but doesn't explain anywhere how to do it.

0 Kudos

NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Aug 12 00:48:54 MST 2015
As an overview, I setup the rx dma with a fixed dma buffer chain that links back to itself.
This creates an infinite buffer that will overwrite the beginning on buffer wrap.
I.e reception is handled in hardware with no interrupts being involved.

Another way to look at this is that the dma buffer is just a big FIFO.

My application code polls for characters (by reading both the dma channel registers and program variables)
and removes characters from the dma buffer to an application buffer.
No characters are lost providing the poll rate is fast enough. This is satisfied in my case simply by checking
for messages in the main loop.

In other words, the dma (hardware) buffer is used as a reservoir for characters only.

In my case, the size of data 'packets' is variable; there must be some sort of protocol to separate
one message from another.

We use start and end framing characters, but other posibilities are
[count] data ...
or [quiet time] data [quiet time]
or you may have a fixed length structure.

The point to take away is that we separate the actual data reception from the interpretation and use of the message packets.
Note that the handling of messages (once a complete packet has been extracted  -- with the poll routines) is orders of magnitude
faster than the data transfer rate. In my case a buffer of 512 bytes is more than sufficient at 115200 baud.

I am sorry that I cannot share any code; (a) I write 'driver' code in M3 assembler and (b) this is a commercial project anyway.


0 Kudos