LPC1769 UART0 DMA Rx

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1769 UART0 DMA Rx

564 Views
jameslittlefiel
Contributor I

I'm working w/ an LPC1769 based developing using MCUXpresso 11.6.1.     My application uses UART0 with DMA driven reception and transmit.      The transmit works fine but I'm running into some unusual problems w/ the reception.     

Here's the way that reception is setup.   I allocate a 512 byte buffer where the RXdma places the incoming characters.     The dma channel for UART0 rx is configured to use a LLI item which references itself.

volatile uint8_t UART0Buffer[512];
volatile uint8_t *UART0RxRdPtr = UART0Buffer;

const dmaLinkedListNode dmaUART0Rx = {
(int)&(LPC_UART0->RBR), // dmaUART0Rx.sourceAddr = (int)&(LPC_UART0->RBR);
(int)UART0Buffer, // dmaUART0Rx.destAddr = (int)UART0Buffer;
(int)&dmaUART0Rx, // dmaUART0Rx.nextNode = (int)&dmaUART0Rx;
(sizeof(UART0Buffer) | (0x00 <<18) | (0x00<<21) | (1<<27) | (1<<31))};

Basically the dma channel will continuously fill UART0Buffer with incoming characters and automatically reload the dma channel to recycle the buffer when it fills.     

A background task reads data from UART0Buffer via UART0RxRdPtr.     When UART0RxRdPtr == GPDMA->CH[2].DESTADDR  the background task knows that all characters have been read.

This approach works well if I run the code with either Release or Debug builds however once I disconnect/terminate the debug session things fail such that the GPDMA->CH[2].SRCADDR, DESTADDR, LLI fields of the dma channel are all 0x000000.   

Below is a printout from a debug serial port.... 

DMACEnbldChns = 0x00000005      <---- CH0,CH2 are enabled.   CH2 is the UART0 RX dma
DMACRawIntErrStat = 0x00000000  <---- No errors posted in the raw int error status reg.
DMACRawIntTCStat = 0x0000000c  <----  Two channels have Terminal counts. 
CH[2].SRCADDR =0x00000000        <----  Wrong!!!  This was initialized to point at LPC_UART0->RBR
CH[2].CONFIG =0x00001013           <----- Correct
CH[2].CONTROL =0x00000000        <----- NO ...was initialized to 0x88000009 
CH[2].LLI =0x00000000                     <----- NO ..should point at 0x00012a98  (ie &dmaUART0Rx )

CmdSize = 45,0x10000dea,0x00000000

NOTE that I have my Release/Debug launches setup to continue run on disconnect,   NOT set a breakpoint at main() on connect,  NOT download flash,  ATTACH only to the running session.

So .. It appears that the DMA CH[2] registers are set back to 0,  even though they were correctly set before the debugger was disconnected.

Btw ... I'm using LPC-LINK2 CMSIS DAP v5.361 for the debug interface.     

Any pointers on how to trace what the LPC-LINK2 is doing on disconnect would be helpful.    I'm not seeing anything useful in the console window during the disconnect.

Thanks

Jim

ps ... I've attached the files for the dma setup.

0 Kudos
3 Replies

543 Views
jameslittlefiel
Contributor I

Hi Alice,

I do the following ...

1.   Download, run project (Debug version)

2.   Verify that the GPDMA registers are set correctly

3.   Terminate the debug session.      Even though I have the launch configuration set to run_cont on disconnect,  it seems like terminate the session does something to the target.    If I terminate debug by clicking on the  "Clean up Debug" button instead then things continue to work correctly.

I will prepare a minimum sized project to demonstrate the issue.

 

Jim

 

0 Kudos

554 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello @jameslittlefiel 

"CH[2].SRCADDR =0x00000000        <----  Wrong!!!  This was initialized to point at LPC_UART0->RBR"

->> Do you mean on debug mode, this register is not 0, while program and download image without debug, this register is 0? If yes, send your project to me, or just one simple project that can reproduce the issue.

 

BR

Alice

0 Kudos

439 Views
jameslittlefiel
Contributor I

Hi Alice,

I've made a few more steps in understanding this issue.     My demo program uses FreeRTOS with a single task to simply read data from the serial port dma rxbuffer and echo commands back on the same serial port.     The demo task  cycles every 10ms.     

FreeRTOS support an idletask which runs whenever all other tasks are blocked.    FreeRTOS also provides for an IdleTaskHook() function which is called repetitively while all higher priority tasks are blocked.      Our particular implementation of the IdleTaskHook()  uses the __WFI() instruction to put the processor into a lower power mode  while waiting for the next 1ms tick of the scheduler timebase.   

My testing shows that there is some interaction between use of the __WFI() instruction and the operation of UART0 Rx dma channel which causes incoming characters to not trigger a dma transfer and/or to corrupt the dma channel configuration registers.

I should add that my LCP1769 is configured to enter (Sleep Mode ...not deepsleep) when the __WFI() instruction executes.

Since the LPC1700 UM claims that GPDMA (and UARTs) continue to operate in sleep mode,   I think this may be a hardware issue.   

Thanks

Jim

 

 

0 Kudos