LP-AM13E230: How to transmit via UART using DMA

Part Number: LP-AM13E230
Other Parts Discussed in Thread: AM13E23019, SYSCONFIG

Hi,

The AM13E23019 SDK doesn't have any examples of how to use UART with DMA; in fact, it doesn't have any examples of how to use any peripheral with DMA. Therefore, I need an example of how to transmit via UART using DMA, or at least some guidance on how to configure a project for this and which functions to use.

Ari

 

  • Hi Ari,

    You are correct, since this is a pre-release device, we don't have the full set of software examples available in the SDK. When the device is active on ti.com, I believe we are planning to include a UART+DMA example in the updated SDK version. 

    The best content we have available right now is the TRM. I would suggest reading through the DMA chapter and looking at the DMA section in the UART chapter. For the UART+DMA case, I would suggest using the "fixed address to block of addresses" for RX operation and the "block of addresses to fixed address" for the TX operation. Let me know if you have any other specific questions, and if so, please describe your UART+DMA use case a little bit more (how many bytes need to be sent/received at a time, when interrupts need to fire etc.)

    Best Regards,

    Delaney

  • Hi Delaney,

    In my application, I only need to transmit via DMA. Reception is done via interrupt, and that's already working.

    In the DMA configuration in Sysconfig, I'm unsure what to configure in the "Address Mode" and "Transfer Mode" fields.

    In the UART configuration in Sysconfig, what should be entered in the "Configure DMA TX Trigger" field?

    Ari

  • Hi Ari,

    Let me take a look at the Sysconfig and get back to you.

    Best Regards,

    Delaney

  • Yes please. I am also looking for this. Also, Provide for DMA Uart Reception. 

  • Hi Dheeraj,

    The "Configure DMA TX Trigger" and "Configure DMA RX Trigger" inputs are configuring the signal from the UART perspective. Some DMA trigger paths have more than one condition option (for example UART RX has RX FIFO level trigger OR receive timeout trigger option.) For this you can just select one and keep the enable box checked.

    Inside the DMA module in Sysconfig, you need to determine the transfer and addressing mode you want to use based on the nature of your data. For the TX side, is all the data you want to transmit laid out in a memory buffer? Or will software update a single memory location? What about on the RX side - how does received data need to be placed in memory?

    Best Regards,

    Delaney

  • Ok, My actual application is pretty complicated as I need to implement a custom protocol based on UART. It involves upto 6-7 DMAs and Timers chained together for my requirement. I am facing some basic issues. I have created stripped down version of my application as specified below. 

    Goal

    Transmit the data from txbuffer using DMA and Receive the data using DMA into the rxbuffer. I am not using the Tx and Rx FIFO thresholds. 

    Configurations for UART5 (specifying important and nondefault values)

    • Baud Rate : 5M
    • RX Timeout Interrupt Counts : 15 
    • DMA RX Trigger : UART RX Interrupt
    • DMA TX Trigger : UART TX Interrupt
    • Tx Pin : A22 | Rx Pin : A10 | UC5

    TX DMA : APP_DMACH_UC5_TX


    RX DMA : APP_DMACH_UC5_RX

    #define MML_TX_BUFFER_SIZE (90)
    #define MML_RX_BUFFER_SIZE (128)
    
    uint8_t txbuffer[MML_TX_BUFFER_SIZE] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17,
                                                    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
                                                    36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
                                                    54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
                                                    72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89};
    uint8_t rxbuffer[MML_RX_BUFFER_SIZE];
    
    int main()
    {
        Diag_InitCounters(); // Clear the counters used for debugging 
        
        Device_Init();
    
        /* Resetting the DMA Channels */
        DL_DMA_resetChannel(APP_DMACH_UC5_TX_DMA_INST, APP_DMACH_UC5_TX_CHANNEL_ID);
        DL_DMA_resetChannel(APP_DMACH_UC5_RX_DMA_INST, APP_DMACH_UC5_RX_CHANNEL_ID);
    
        DL_UART_reset(APP_UART_0_INST);
        SYSCFG_DL_init();
        
        /* Clear TX and RX Fifo */
        UC5_UART->IFLS |=  0x88;
    
        /* Clearing all pending interrupts for UART */
        DL_UART_clearInterruptStatus(APP_UART_0_INST, 0xFFFFFFFF);
    
        /* TX DMA Configuration */
        DL_DMA_setSrcAddr(APP_DMACH_UC5_TX_DMA_INST, APP_DMACH_UC5_TX_CHANNEL_ID, (uint32_t)txbuffer);
        DL_DMA_setDestAddr(APP_DMACH_UC5_TX_DMA_INST, APP_DMACH_UC5_TX_CHANNEL_ID, (uint32_t)&UC5_UART->TXDATA);
        DL_DMA_setTransferSize(APP_DMACH_UC5_TX_DMA_INST, APP_DMACH_UC5_TX_CHANNEL_ID, MML_TX_BUFFER_SIZE);
        DL_DMA_enableChannel(APP_DMACH_UC5_TX_DMA_INST, APP_DMACH_UC5_TX_CHANNEL_ID);
    
        /* RX DMA Configuration */
        DL_DMA_setSrcAddr(APP_DMACH_UC5_RX_DMA_INST, APP_DMACH_UC5_RX_CHANNEL_ID, (uint32_t)&UC5_UART->RXDATA);
        DL_DMA_setDestAddr(APP_DMACH_UC5_RX_DMA_INST, APP_DMACH_UC5_RX_CHANNEL_ID, (uint32_t)rxbuffer);
        DL_DMA_setTransferSize(APP_DMACH_UC5_RX_DMA_INST, APP_DMACH_UC5_RX_CHANNEL_ID, MML_RX_BUFFER_SIZE);
        DL_DMA_enableChannel(APP_DMACH_UC5_RX_DMA_INST, APP_DMACH_UC5_RX_CHANNEL_ID);
    
        /* For Logic Analyser Time Marking */
        BSP_AM13E230_E2::Debug10Pin_Low();
        DEVICE_DELAY_MS(100);
        BSP_AM13E230_E2::Debug10Pin_High();
        DEVICE_DELAY_MS(100);
        BSP_AM13E230_E2::Debug10Pin_Low();
    
        soft_timer1.Start(); /* 1ms loop */
        soft_timer2.Start(); /* 10ms loop */
        soft_timer3.Start(); /* 100ms loop */
        soft_timer4.Start(); /* 1000ms loop */
        
        // DL_UART_disable(APP_UART_0_INST);
        // DL_UART_enableDMATransmitEvent(APP_UART_0_INST);
        // DL_UART_enable(APP_UART_0_INST);
    
        LOG("Entering While Loop \r\n");
        while (1)
        {
            g_diagCounters.mainLoopCnt++;
            
            /* Run all timers periodically */
            us32 currentTime = Millis::GetMs();
            soft_timer1.PeriodicRun(currentTime);
            soft_timer2.PeriodicRun(currentTime);
            soft_timer3.PeriodicRun(currentTime);
            soft_timer4.PeriodicRun(currentTime);
        }
        return 0;
    }


    I am triggering the UART DMA by calling this function in one second loop 
    DL_UART_transmitData(APP_UART_0_INST, txbuffer[0]);


    I am first testing with UART Tx DMA and I observe following issues 

    • The DMA start sending the data as soon as I enable the DMA  during initialisation process. It should have waiting untill I manually send one byte to start triggering for further buffer transmission. I checked the Interrupt flag and TXIFG flag is set when checking the debug mode before the enable channel was done. 
    • Somehow 3 Launchpad Debugger section(MCU is fine) have gone bad while debugging UART DMA ( 1- E1 Launchpad, 2- E2 Launchpad) 

  • Hi Dheeraj,

    I have replied on the other thread, and we can continue the conversation there. I will close this thread.

    Best Regards,

    Delaney