Other Parts Discussed in Thread: EK-TM4C1294XL
Hi,
I need to enable uDMA for UART using the interrupt method. I am able to establish communication using the polling method, but when I move to the interrupt method, it doesn't enter the callback. I am attaching my code below for reference.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "main.h"
#include "drivers/pinout.h"
#include "drivers/UART.h"
// TivaWare includes
#include "driverlib/sysctl.h"
#include "driverlib/debug.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "inc/hw_memmap.h"
#include "inc/hw_uart.h"
#include "inc/hw_ints.h"
#include "driverlib/udma.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
// FreeRTOS includes
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#define TABLE_SIZE 1024
// Allocate space for the uDMA control table
//uint8_t udmaControlTable[TABLE_SIZE];
//#pragma DATA_ALIGN(udmaControlTable, TABLE_SIZE)
// Your data array
char data[] = "Hello, this is a test message through UART using DMA and FreeRTOS.\n\r";
void vTaskfun(void *pvParameter)
{
uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *)data,
(void *)(UART0_BASE + UART_O_DR), strlen(data));
uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
while (1)
{
uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *)data,
(void *)(UART0_BASE + UART_O_DR), strlen(data));
uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
vTaskDelay(1000);
}
}
void UART_DMA_IRQHandler(void)
{
// Clear the interrupt status
uDMAIntClear(UDMA_CHANNEL_UART0TX);
}
void ConfigureUART(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTConfigSetExpClk(UART0_BASE, SYSTEM_CLOCK, 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);
}
void ConfigureDMA(void)
{
// Allocate space for the uDMA control table
static uint8_t udmaControlTable[TABLE_SIZE];
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
// Initialize the uDMA controller
uDMAControlBaseSet(udmaControlTable);
uDMAEnable();
// Enable the UART TX DMA channel
uDMAChannelAssign(UDMA_CHANNEL_UART0TX);
uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4);
// Configure the UART TX DMA transfer
uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *)data,
(void *)(UART0_BASE + UART_O_DR), strlen(data));
// Enable the UART TX DMA interrupt
IntEnable(UDMA_CHANNEL_UART0TX);
// Enable the UART DMA module for TX
UARTDMAEnable(UART0_BASE, UART_DMA_TX);
// Enable the UART TX DMA interrupt in the UART module
UARTIntEnable(UART0_BASE, UART_INT_DMATX);
// Enable the uDMA interrupt
IntEnable(INT_UDMA);
// Register the UART interrupt handler
IntRegister(INT_UDMA, UART_DMA_IRQHandler);
}
int main(void)
{
BaseType_t xReturn = pdPASS;
// Set the clock to 120 MHz
uint32_t output_clock_rate_hz = SysCtlClockFreqSet(
(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480),
SYSTEM_CLOCK);
ASSERT(output_clock_rate_hz == SYSTEM_CLOCK);
// Initialize peripherals, DMA, and UART
ConfigureUART();
ConfigureDMA();
// Enable global interrupts
IntMasterEnable();
// Create the task
xReturn = xTaskCreate(vTaskfun, "UART Task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
if (xReturn == pdPASS)
{
// Start the scheduler
vTaskStartScheduler();
}
// Code should never reach this point
while (1)
{
}
}
In the above code, the program does not reach the handler function UART_DMA_IRQHandler(void). Are there any corrections needed in the configuration?