FreeRTOS USART DMA not sending

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

FreeRTOS USART DMA not sending

1,607 Views
haakoneh
Contributor I

Edit:

The error seems to be that I used the USART, not the UART. 

Hello,

I am using the LPCXpresso4337 Development Board and have connected the USART0 to one of the USB ports on my PC by using a TTL UART serial converter. 

I am trying to communicate with the termite terminal by using some of the code from the periph_uart example provided with the board, while running FreeRTOS. I have been able to communicate using the interrupt code from the example, but not DMA. All of the code related to the USART is run through a task, called vUARTTask . When running the program, it seems like the Chip_GPDMA_Transfer does not send anything, since the interrupt is never triggered, the program does not exit the while loop after it. The dmaChannelNumTx is always 0, which might signal an error, DMA channel assignment: no error code? 

I have run the periph_uart example project and it worked as expected. 

This is the relevant code for the DMA USART:

#include "board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "sysSetup.h"
#include "CRC16.h"
#include "usbd.h"

#define LPC_UART LPC_USART0
#define UARTx_IRQn USART0_IRQn
#define UARTx_IRQHandler UART0_IRQHandler
#define _GPDMA_CONN_UART_Tx GPDMA_CONN_UART0_Tx
#define _GPDMA_CONN_UART_Rx GPDMA_CONN_UART0_Rx

#define DMA_TIMEOUT 0xA000000

static uint8_t dmaChannelNumTx, dmaChannelNumRx;
static volatile uint32_t channelTC; /* Terminal Counter flag for Channel */
static volatile uint32_t channelTCErr;
static FunctionalState isDMATx = ENABLE;

void App_DMA_Init(void) {


/* Initialize GPDMA controller */
Chip_GPDMA_Init(LPC_GPDMA);
/* Setting GPDMA interrupt */
NVIC_DisableIRQ(DMA_IRQn);
NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01));
NVIC_EnableIRQ(DMA_IRQn);

}

void DMA_IRQHandler(void)
{


uint8_t dmaChannelNum;
if (isDMATx) {


dmaChannelNum = dmaChannelNumTx;

} else {


dmaChannelNum = dmaChannelNumRx;


}
if (Chip_GPDMA_Interrupt(LPC_GPDMA, dmaChannelNum) == SUCCESS) {

channelTC++;


} else {
channelTCErr++;
}


}

void vUARTTask(void *pvParameters) {


int tickCnt = 0;

uint8_t uartTestString[] = "Ticking\n";

App_DMA_Init();

while (1) {

dmaChannelNumTx = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, _GPDMA_CONN_UART_Tx);

isDMATx = ENABLE;
channelTC = channelTCErr = 0;
Chip_GPDMA_Transfer(LPC_GPDMA, dmaChannelNumTx,
(uint32_t) &uartTestString[0],
_GPDMA_CONN_UART_Tx,
GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA,
sizeof(uartTestString));

while (!channelTC) { }

/* About a 1s delay here */
vTaskDelay(configTICK_RATE_HZ);


}


}

This it the relevant code for the interrupted triggered UART, that works. 

#include "board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "sysSetup.h"
#include "CRC16.h"
#include "usbd.h"

/* Transmit and receive ring buffers */
STATIC RINGBUFF_T txring, rxring;

/* Ring buffer size */
#define UART_RB_SIZE 256

/* Transmit and receive buffers */
static uint8_t rxbuff[UART_RB_SIZE], txbuff[UART_RB_SIZE];

#define LPC_UART LPC_USART0
#define UARTx_IRQn USART0_IRQn
#define UARTx_IRQHandler UART0_IRQHandler
#define _GPDMA_CONN_UART_Tx GPDMA_CONN_UART0_Tx
#define _GPDMA_CONN_UART_Rx GPDMA_CONN_UART0_Rx

/* Initialize Interrupt for UART */
void App_Interrupt_Init(void) {


Chip_UART_IntEnable(LPC_UART, (UART_IER_RBRINT | UART_IER_RLSINT));

RingBuffer_Init(&rxring, rxbuff, 1, UART_RB_SIZE);
RingBuffer_Init(&txring, txbuff, 1, UART_RB_SIZE);

NVIC_SetPriority(UARTx_IRQn, 1);
/* Enable Interrupt for UART channel */
NVIC_EnableIRQ(UARTx_IRQn);

}

void UARTx_IRQHandler(void) {


Chip_UART_IRQRBHandler(LPC_UART, &rxring, &txring);

}

void vUARTTask(void *pvParameters) {


int tickCnt = 0;

uint8_t uartTestString[] = "Ticking\n";

App_Interrupt_Init();

while (1) {


Chip_UART_SendRB(LPC_UART, &txring, (uint8_t *) &uartTestString[0], sizeof(uartTestString));

vTaskDelay(configTICK_RATE_HZ);

}

}

I will add the actual c file as well, see uart_driver.c

Any help is greatly appreciated. 

Thank you in advance. 

Labels (2)
0 Kudos
1 Reply

1,005 Views
jeremyzhou
NXP Employee
NXP Employee

Hi  Håkon Hanssen ,

Thank you for your interest in NXP Semiconductor products and 
the opportunity to serve you.
I'd highly recommend you start a DMA demo prior to implement with FreeRTOS.
Yes, DMA channel assignment: no error code? may expose potential cause, but it need more testing to confirm.
I've attached demo code which describes how to use UART in DMA mode, please refer to it for details.
Have a great day,
TIC
 
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos