Hello,
I am exploring how to send data over the UART interface (EUSCI_A0_MODULE) of the MSP432 launchpad using DMA. To this end, I have successfully tested the data transfer from the uC to the host PC using the 'UDMA_MODE_BASIC' mode. Then I programmed the transfer using the 'UDMA_MODE_PINGPONG'. Despite all my efforts I could not make the DMA work in this particular mode. Here is the source code that I am running on the launchpad:
#include "rom_map.h" #include "driverlib.h" #include <stdint.h> #include <stdbool.h> #include <string.h> #define zCHAN_DMA_UART_TX DMA_CHANNEL_0 //***************************************************************************** // DMA Control Table //***************************************************************************** #ifdef ewarm #pragma data_alignment=1024 #else #pragma DATA_ALIGN(controlTable, 1024) #endif uint8_t controlTable[1024]; //***************************************************************************** // UART Parameters //***************************************************************************** #define zUART_BAUD_RATE 4000000 /* UART Configuration Parameter. 'zUART_BAUD_RATE' baud rate. * Rf. online calculator provided by TI at: * software-dl.ti.com/.../index.html */ const eUSCI_UART_Config uartConfig = { EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 12, // BRDIV = 12 0, // UCxBRF = 0 0, // UCxBRS = 0 EUSCI_A_UART_NO_PARITY, // No Parity EUSCI_A_UART_LSB_FIRST, // LSB First EUSCI_A_UART_ONE_STOP_BIT, // One stop bit EUSCI_A_UART_MODE, // UART mode EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION // NO Oversampling }; //***************************************************************************** // Ping-pong Data buffers //***************************************************************************** #define SIZE_BUFF_A_TX 512 #define SIZE_BUFF_B_TX 512 static uint8_t zUI8_BUFF_A_TX[SIZE_BUFF_A_TX]; static uint8_t zUI8_BUFF_B_TX[SIZE_BUFF_B_TX]; //***************************************************************************** // Function //***************************************************************************** void ConfigSysClk(void) { /* Enabling FPU for DCO Frequency calculation */ MAP_FPU_enableModule(); /* Setting DCO to 48MHz (upping Vcore) */ MAP_PCM_setCoreVoltageLevel(PCM_VCORE1); MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48); /* wait for the module to initialize */ uint32_t indConfgClk; for(indConfgClk=0;indConfgClk<1000;indConfgClk++); } void ConfigLED_Pins(void) { /* LED1: RED */ MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); /* LED RGB: P2.0: RED, P2.1: GREEN, P2.2: BLUE */ MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN2); } void ConfigUart(void) { /* Selecting P1.2 and P1.3 in UART mode */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); /* Configuring UART Module */ MAP_UART_initModule(EUSCI_A0_MODULE, &uartConfig); /* Enable UART module */ MAP_UART_enableModule(EUSCI_A0_MODULE); MAP_Interrupt_enableInterrupt(INT_EUSCIA0); } void ConfigDma4Uart(void) { /* Configuring DMA module */ MAP_DMA_enableModule(); MAP_DMA_setControlBase(controlTable); /* Assigning Channel 0 to EUSCIA0TX*/ MAP_DMA_assignChannel(DMA_CH0_EUSCIA0TX); /* Disabling channel attributes of alternate DMA channel which will not be used in the basic DMA mode */ MAP_DMA_disableChannelAttribute(DMA_CH0_EUSCIA0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); /* Setting control parameters: 'UDMA_SIZE_8' and 'UDMA_SRC_INC_8' are selected coz UART TX/RX data buffer size limited to one character */ // primary channel MAP_DMA_setChannelControl(DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1); // secondary channel MAP_DMA_setChannelControl(DMA_CH0_EUSCIA0TX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1); /* Setting channel transfers */ // primary channel MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, zUI8_BUFF_A_TX, (void*) MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_MODULE), SIZE_BUFF_A_TX); // secondary channel MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIA0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, zUI8_BUFF_B_TX, (void*) MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_MODULE), SIZE_BUFF_B_TX); /* Assigning interrupts */ MAP_DMA_assignInterrupt(DMA_INT1, zCHAN_DMA_UART_TX); /* Enable intrrupts for both DMA channels */ MAP_Interrupt_enableInterrupt(DMA_INT1); /* Enable DMA channel */ MAP_DMA_enableChannel(zCHAN_DMA_UART_TX); } //***************************************************************************** // ISR routine for 'DMA_INT1' //***************************************************************************** void DMA_UART_TX_IntHndlr(void) { uint32_t ui32Mode; // Check if the ping-pong "A" transfer is complete. ui32Mode = MAP_DMA_getChannelMode( DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT ); if(ui32Mode == UDMA_MODE_STOP) { MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN1); MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, zUI8_BUFF_A_TX, (void*) MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_MODULE), SIZE_BUFF_A_TX); } // Check if the ping-pong "B" transfer is complete. ui32Mode = MAP_DMA_getChannelMode( DMA_CH0_EUSCIA0TX | UDMA_ALT_SELECT ); if(ui32Mode == UDMA_MODE_STOP) { MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN2); MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIA0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, zUI8_BUFF_B_TX, (void*) MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_MODULE), SIZE_BUFF_B_TX); } } //***************************************************************************** // ISR for DMA errors (DMA_ERR ISR) //***************************************************************************** void uDMAErrorHandler(void) { uint32_t ui32Status; // Check for uDMA error bit ui32Status = MAP_DMA_getErrorStatus( ); // If there is a uDMA error, then clear the error and increment the error counter if(ui32Status) { MAP_DMA_clearErrorStatus(); // toggle an LED to indicate DMA error MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); } } int main(void) { /* Halting WDT */ MAP_WDT_A_holdTimer(); /* Initializing buffers */ memset(zUI8_BUFF_A_TX, 'A', SIZE_BUFF_A_TX); memset(zUI8_BUFF_B_TX, 'B', SIZE_BUFF_B_TX); /*Config Sys Clk*/ ConfigSysClk(); /* Config LED */ ConfigLED_Pins(); /* Config UART */ ConfigUart(); /* Config DMA */ ConfigDma4Uart(); /* Config LPM */ MAP_PCM_gotoLPM0(); __no_operation(); }
When I run this program on the uC, and from the host PC connect to the Application/User COM port of the launchpad, I do not receive anything. Could someone point out where is the problem in the code.
Kind regards
Jatala