This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2538: SW DMA

Part Number: CC2538

Hi,

I am trying to copy buffer from One to Other In cc2538 using DMA, But It seems more buffers are transferring than the length of buffers. Can any one please look at my code, why its happening, I am first time using DMA.

//*****************************************************************************
//
// The application must allocate the channel control table.
// This one is a full table for all modes and channels.
// NOTE: This table must be 1024-byte aligned.
//
//*****************************************************************************
#if defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=1024
unsigned char ucDMAControlTable[1024];
#else
unsigned char ucDMAControlTable[1024] __attribute__ ((aligned(1024)));
#endif

//*****************************************************************************
//
// Source and destination buffers used for the DMA transfer.
//
//*****************************************************************************
unsigned char SourceBuffer[16];
unsigned char DestBuffer[16];

//*****************************************************************************
//
// ISR called when uDMA software transfer is done.
// The function will compare the two buffers and report if move was done.
//
//*****************************************************************************
void 
uDMAIntHandler(void)
{
    uint32_t IntStat = uDMAIntStatus();
    printf("IntStat = %d\n", IntStat);
    uDMAIntClear(IntStat);

    printf("SRC=%s\n", SourceBuffer);
    printf("DST=%s\n", DestBuffer);
}

//*****************************************************************************
//
// Configure the SysTick and SysTick interrupt with a period of 1 second.
//
//*****************************************************************************
int
main(void)
{
    uint16_t i;
  
    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // (no ext 32k osc, no internal osc)
    //
    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

    //
    // Set IO clock to the same as system clock
    //
    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
    
    
    //
    // Fill Source buffer with some data
    //
   for(i=0; i<16; i++)
    {
        SourceBuffer[i] = 'A' + i;
    }
    
    //
    // Display the initial Src and Dstn buffers on the console.
    //
    printf("SRC=%s\n", SourceBuffer);
    printf("DST=%s\n", DestBuffer);
    
    //
    // Enable the uDMA controller.
    //
    uDMAEnable();

    //
    // Set the base for the channel control table.
    //
    uDMAControlBaseSet(&ucDMAControlTable[0]);

    //
    // No attributes must be set for a software-based transfer.
    // The attributes are cleared by default, but are explicitly cleared
    // here, in case they were set elsewhere.
    //
    uDMAChannelAttributeDisable(UDMA_CH30_SW, UDMA_ATTR_ALL);
    
    //
    // Now set up the characteristics of the transfer for
    // 8-bit data size, with source and destination increments
    // in bytes, and a byte-wise buffer copy.  A bus arbitration
    // size of 8 is used.
    //
    uDMAChannelControlSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                          UDMA_SIZE_8 | UDMA_SRC_INC_8 |
                          UDMA_DST_INC_8 | UDMA_ARB_8);

    //
    // The transfer buffers and transfer size are now configured.
    // The transfer uses AUTO mode, which means that the
    // transfer automatically runs to completion after the first
    // request.
    //
    uDMAChannelTransferSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                           UDMA_MODE_AUTO, SourceBuffer, DestBuffer,
                           sizeof(DestBuffer));

    //
    // Enable Interrupt for DMA
    //
    IntEnable(INT_UDMA);
    
    //
    // Finally, the channel must be enabled.  Because this is a
    // software-initiated transfer, a request must also be made.
    // The request starts the transfer.
    //
    uDMAChannelEnable(UDMA_CH30_SW);
    uDMAChannelRequest(UDMA_CH30_SW);    
    
    //
    // Put cpu to sleep and wait for interrupt (when DMA transfer is done)
    //
    SysCtrlSleep();
    
    //
    // Loop forever while the SysTick runs.
    //
    while(1)
    {
    }
}

Ouput:

SRC=ABCDEFGHIJKLMNOP
DST=
IntStat = 1073741824
SRC=ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP8901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
DST=ABCDEFGHIJKLMNOP8901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345

Expected Output:

SRC=ABCDEFGHIJKLMNOP
DST=
IntStat = 1073741824
SRC=ABCDEFGHIJKLMNOP
DST=ABCDEFGHIJKLMNOP

This code is edit of CC2538 foundation firmware DMA_SW example project.

Thank you

 

  • Hi Raghunandana DS,

    Give me 1-2 days to set up the hardware and software so that I can replicate your situation and figure out what the issue is.

    In the meantime, try modifying only the declaration of your buffers as:

    unsigned char SourceBuffer[17];

    unsigned char DestBuffer[17];

    (Note: Do not modify your for loop at all. Only change the buffer sizes to 17).

    I am working on an explanation as to why changing the buffer sizes from 16 to 17 works.

    Regards,

    Toby

  • Hi Raghunandana DS,

    Here is why changing buffer size from 16 to 17 works.

    You have declared two arrays consecutively, so they are highly likely to be in contiguous locations in physical memory. Specifically, you declare “SourceBuffer” before declaring “DestBuffer”, so that &SourceBuffer < &DestBuffer. By default, these buffers are initialized with the value 0x0000.

    After you populate SourceBuffer, you print it as a string. By default in C, strings are null terminated, ie printf will keep printing characters from SourceBuffer until it finds a null (aka 0). Because DestBuffer[0] has not been initialized, it contains 0, so printf will stop printing as soon as it reads SourceBuffer[16]. (Note that &SourceBuffer[16] == &DestBuffer[0]).

    Now, after the uDMA is complete, DestBuffer[0] contains ‘A’ rather than 0. Thus if you try to print SourceBuffer as a string using printf, you will find that it will print more than what you expect. In fact, printf will keep printing characters until it reads a null.

    By changing buffer size to 17, you leave SourceBuffer[16] == 0, so printf will stop printing SourceBuffer at that point. Also after uDMA, DestBuffer[16] == 0, so printf will stop printing after reading DestBuffer[16].
    Instead of printing the buffers to compare, you may want to consider using the C function memcmp.

    Regards,
    Toby
  • Hi Toby,
    Thank you, the issue is resolved.
    This is done for DMA SW, can you please tell how to use DMA with Peripherals . I was first time using DMA feature so the issue.
    Thank you.
  • Raghunandana DS,

     

    I’m glad the previous issue is resolved.

     

    Is there a specific peripheral (ADC, UART, timers, etc) that you would like to use DMA with?

    There is an example for setting up a peripheral for simple transmit on the link (starts on pg 303): http://www.ti.com/lit/ug/swru319c/swru319c.pdf

    Also, the documentation of the uDMA API is on the link (starts on pg 174) http://www.ti.com/lit/ug/swru325a/swru325a.pdf

     

    Toby

  • Hi Toby,
    Thank you for suggesting me to write point.
    I was not yet clear about DMA transfer with Peripherals.
    Thank you.
  • Raghunandana DS,

    Have you taken a look at the dma_flash.c in the foundation firmware? This is an example of DMA transfer with a peripheral.

    The general method of uDMA is on the link (pg 175): www.ti.com/.../swru325a.pdf

    I can help you more directly if you have a specific peripheral in mind for DMA.

    Toby
  • Hi Toby,
    Thank you so much, How can I implement for UART.
  • There is UART example in CC2538 foundation firmware.

  • Hi Toby,
    I just played around dma_flash.c And tried it, it's worked fine. But I was not getting any interrupt after the completion.

    void
    uDMAIntHandler(void)
    {
    uint32_t IntStat = uDMAIntStatus();
    printf("IntStat = %d\n", IntStat);
    uDMAIntClear(IntStat);
    }

    I defined this method, but DMA not calling this after completion.

    Thank you.
  • Hi Toby,
    How can I make it in reverse, I mean Using DMA how can I copy data from Flash to RAM. It looks in flash only write reg no read reg. Can you please clarify.

    Thank you.
  • Raghunandana DS,

    In order for the uDMAIntHandler() to be called, you need to enable that interrupt using: IntEnable(INT_UDMA). It was enabled in dma_sw.c, but not in dma_flash.c.

    Regards,
    Toby
  • Raghunandana DS,

    You are correct, dma_flash.c implements a write to flash.

    According to the document, you cannot uDMA read from flash because the uDMA controller and flash use different buses (pg 287 in www.ti.com/.../swru319c.pdf ).

    To read from flash, you would use the flash API (in flash.c) function:
    uint32_t FlashGet(uint32_t ui32Addr)

    Regards,
    Toby
  • Hi Toby,

    I had defined uDMAIntHandler() and called the IntEnable(IntUDMA); but not getting interrupt .

    Please look at my code.

    #include <stdbool.h>
    #include <stdint.h>
    #include "hw_memmap.h"
    #include "hw_ints.h"
    #include "hw_flash_ctrl.h"
    #include "flash.h"
    #include "gpio.h"
    #include "hw_ioc.h"
    #include "ioc.h"
    #include "interrupt.h"
    #include "sys_ctrl.h"
    #include "udma.h"
    #include "cpu.h"
    #include "uartstdio.h"
    #include "string.h"
    #include "uart.h"
    #include "debug.h"
    
    
    //*****************************************************************************
    // NOTE:
    // This example has been run on a SmartRF06 evaluation board.  
    //
    //*****************************************************************************
    //
    //! \addtogroup dma_examples_list
    //! <h1>uDMA Flash Transaction (dma_flash)</h1>
    //!
    //! This example shows how to set up the uDMA controller to perform a 
    //! peripheral-initiated SRAM-to-flash transfer.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - NONE
    //*****************************************************************************
    
    #define PAGE_SIZE                2048
    #define PAGE_TO_ERASE            14
    #define PAGE_TO_ERASE_START_ADDR (FLASH_BASE + (PAGE_TO_ERASE * PAGE_SIZE))
    
    //*****************************************************************************
    //
    // The application must allocate the channel control table.
    // This one is a full table for all modes and channels.
    // NOTE: This table must be 1024-byte aligned.
    //
    //*****************************************************************************
    #if defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment=1024
    unsigned char ucDMAControlTable[1024];
    #else
    unsigned char ucDMAControlTable[1024] __attribute__ ((aligned(1024)));
    #endif
    
    //*****************************************************************************
    //
    // Source buffer used for the DMA transfer.
    //
    //*****************************************************************************
    static uint32_t ucSourceBuffer[16];
    static uint32_t ucDestinationBuffer[16];
    
    //*****************************************************************************
    //
    // ISR called when uDMA software transfer is done.
    // The function will compare the two buffers and report if move was done.
    //
    //*****************************************************************************
    void 
    uDMAIntHandler(void)
    {
        uint32_t IntStat = uDMAIntStatus();
        printf("IntStat = %d\n", IntStat);
        uDMAIntClear(IntStat);
    }
    
    //*****************************************************************************
    //
    // Main function, setup DMA and perform flash write. Verify the transaction.
    //
    //*****************************************************************************
    int
    main(void)
    {
        uint16_t i;
        int32_t i32Res;
    
        // Set the clocking to run directly from the external crystal/oscillator.
        // (no ext 32k osc, no internal osc)
        SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);
    
        // Set IO clock to the same as system clock //
        SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
    
        // Erase Flash page that will hold our transferred data //
        i32Res = FlashMainPageErase(PAGE_TO_ERASE_START_ADDR);
        ASSERT(i32Res==0);
    
        // Fill Source buffer (to be copied to flash) with some data //
        for(i=0; i<16; i++)
        {
            ucSourceBuffer[i] = 'A' + (i % 26);
        }
        
        ucDestinationBuffer[16] = 0;
        
        // Enable the uDMA controller.//
        uDMAEnable();
        
        // Init Copying Data from RAM to Flash //
        
        // Disable the uDMA channel to be used, before modifications are done.//
        uDMAChannelDisable(UDMA_CH2_FLASH);
    
        // Set the base for the channel control table.//
        uDMAControlBaseSet(&ucDMAControlTable[0]);
    
        // Assign the DMA channel //
        uDMAChannelAssign(UDMA_CH2_FLASH);
    
        // Set attributes for the channel.//
        uDMAChannelAttributeDisable(UDMA_CH2_FLASH, UDMA_ATTR_HIGH_PRIORITY);
    
        // Now set up the characteristics of the transfer.
        // 32-bit data size, with source increments in words (32 bits), 
        // no destination increment.
        // A bus arbitration size of 1 must be used.
        uDMAChannelControlSet(UDMA_CH2_FLASH, UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                              UDMA_DST_INC_NONE | UDMA_ARB_1);
    
        // Set transfer parameters. 
        // Source address is the location of the data to write
        // and destination address is the FLASH_CTRL_FWDATA register.
        uDMAChannelTransferSet(UDMA_CH2_FLASH, UDMA_MODE_BASIC, ucSourceBuffer, 
                               (void *) FLASH_CTRL_FWDATA, sizeof(ucSourceBuffer));
        //
        // Enable Interrupt for DMA
        //
        IntEnable(INT_UDMA);
    
        // Asure that the flash controller is not busy.
        while(HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY)
        {
        }
    
        // Initialize Flash control register without changing the cache mode.
        HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M;
    
        // Setup Flash Address register to address of first data word (32-bit)
        HWREG(FLASH_CTRL_FADDR) = PAGE_TO_ERASE_START_ADDR;
    
        // Finally, the DMA channel must be enabled.
        uDMAChannelEnable(UDMA_CH2_FLASH);
    
        // Set FCTL.WRITE, to trigger flash write
        //
        HWREG(FLASH_CTRL_FCTL) |= FLASH_CTRL_FCTL_WRITE;
    
        // Wait until all words has been programmed. //
        while( HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_FULL )
        {
        }
     
        // Check if flash write was successfull //
        if (HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_ABORT)
        {
            printf("Write to Flash not successful!\n");
        }
        else
        {
            printf("Write to Flash success!\n");
        }
    
        // Set control register back to reset value without changing the cache mode. //
        HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M;
    
        // Compare source buffer and destination flash page //
        if(memcmp(ucSourceBuffer, (void*) PAGE_TO_ERASE_START_ADDR, 256)==0)
        {
            printf("Success!\n");
        }
        else
        {
            printf("Not Success!\n");
        }
    
        memcpy(ucDestinationBuffer, (void*) PAGE_TO_ERASE_START_ADDR, 256);
        for(int i=0; i<16; i++){
        printf("%c", ucDestinationBuffer[i]);
        }
        printf("\n");
        // End Copying Data from RAM to Flash //
    
        // We are done, loop forever //
        while(1)
        {
        }
    }

    Thank you.

  • Raghunandana DS,

     

    First, I recommend that you don’t write to ucDestinationBuffer[16]. Please either declare the buffer with size 17 (and you can write to [16]), or leave it size 16 but don’t write to [16]. If you declare an array with size 16, you can access elements 0 to 15 (inclusive). Even though in your current code it won’t cause bugs, in general writing outside the bounds of your array could cause you headache later.

    One question I have for you: is the flash uDMA write successful?

    So actually, after reading the reading swru319c.pdf (pg 304), I stand corrected. You should be using the interrupt handler for the peripheral itself (in our case, use FlashIntHandler instead of uDMAIntHandler). So you would replace IntEnable(INT_UDMA) with IntEnable(INT_FLASH). You would rename your uDMAIntHandler to FlashIntHandler.

    You may also need to include IntMasterEnable().

    Let me know if this works. I expect that the FlashIntHandler will be called after the transfer is complete.

     

    Regards,

    Toby

  • Hi Toby,
    I can able to get the interrupt to "FlashIntHandler();", and "IntMasterEnable()" is not necessary.
    I have confusion that, in my code I am trying to copy the data from RAM Buffer to Flash over "UDMA," then why I was not any getting to interrupt to "uDMAIntHandler()", at least to confirm "UDMA" has did its assigned work as it was happening in "SW-UDMA".
  • Raghunandana DS,

     

    The uDMAIntHandler is triggered by completion of a software request DMA (from one buffer to another). According to the documentation, the uDMA controller generates an interrupt on the peripheral’s interrupt (if you are using uDMA with peripheral).

    My understanding is the following:

    Suppose an application has multiple requests to use uDMA. For example, it may request uDMA for UART, flash, SSI, etc. What happens when one transfer is complete? If you use the same interrupt (uDMAIntHandler) for all kinds of uDMA transfers, then how can the application know which uDMA transfer is actually complete? For example, if UART uDMA transfer is done, and if the uDMAIntHandler is called, how do you know whether UART, flash, or SSI is the uDMA transfer that has completed? That’s why the uDMA will trigger the appropriate interrupt (either UART, flash, or SSI interrupts).

    However, for software uDMA requests (for buffer to buffer transfer) completion, the application needs to know what kind of interrupt was triggered. For example, the application could be interrupted by a GPIO edge or timer. If the software uDMA interrupt is triggered, then uDMAIntHandler is called (and thus the application is assured that the interrupt was caused by uDMA and not, say, GPIO).

     

    Regards,

    Toby

  • Hi Toby,
    Thanks for the information, but as of my knowledge if get to interrupt to one handler means cpu can get the Status of the interrupt by calling Particular interrupt Status API, so cpu can know by the status bit why this interrupt is or from where. That's OK any where getting interrupt is fine, as you told cpu can get the interrupt to respective peripheral's on completion that's also enough.
    But you told that you will help to know effective use of UDMA with any peripheral. Can you please help me to use with UART, it's the great help expecting from you.

    Thank you.
  • Raghunandana DS,

     

    As YK Chen mentioned, please refer to UART example given in the foundation firmware (uart_polled.c).

    Initialize the uDMA controller as in the previous examples. Use the appropriate UART uDMA channels (use the uDMA channel assignment table in swru319c.pdf and the channel #define in udma.h). Additionally, use the UARTDMAEnable function.

    Using the example, I recommend that you prepare a buffer of characters, then use uDMA to write these characters to UART tx.

     

    Regards,

    Toby

  • Hi Toby,

    I made as you and YK Chen told, but my code is sops in between can you please look at my code,

    #include "hw_memmap.h"
    #include "hw_types.h"
    #include "hw_ioc.h"
    #include "sys_ctrl.h"
    #include "uart.h"
    #include "gpio.h"
    #include "ioc.h"
    
    #include "udma.h"
    #include "hw_uart.h"
    
    
    #define EXAMPLE_PIN_UART_RXD            GPIO_PIN_0 
    #define EXAMPLE_PIN_UART_TXD            GPIO_PIN_1 
    #define EXAMPLE_GPIO_BASE               GPIO_A_BASE
    
    static uint32_t ucSourceBuffer[16];
        
        #pragma data_alignment=1024
        unsigned char ucDMAControlTable[1024];
          
    //*****************************************************************************
    //
    // Configure the UART and perform reads and writes using polled I/O.
    //
    //*****************************************************************************
    int
    main(void)
    {
        char cThisChar;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // (no ext 32k osc, no internal osc)
        //
        SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);
    
        //
        // Set IO clock to the same as system clock
        //
        SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
       
        //
        // Enable UART peripheral module
        //
        SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0);
    
        
        
          for(int i=0; i<16; i++)
        {
            ucSourceBuffer[i] = 'A' + (i % 26);
        }
        
        
        
        //
        // Disable UART function
        //
        UARTDisable(UART0_BASE);
    
        //
        // Disable all UART module interrupts
        //
        UARTIntDisable(UART0_BASE, 0x1FFF);
    
        //
        // Set IO clock as UART clock source
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Map UART signals to the correct GPIO pins and configure them as
        // hardware controlled.
        //
        IOCPinConfigPeriphOutput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_TXD, IOC_MUX_OUT_SEL_UART0_TXD);
        GPIOPinTypeUARTOutput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_TXD); 
        IOCPinConfigPeriphInput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_RXD, IOC_UARTRXD_UART0);
        GPIOPinTypeUARTInput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_RXD);
         
        //
        // Configure the UART for 115,200, 8-N-1 operation.
        // This function uses SysCtrlClockGet() to get the system clock
        // frequency.  This could be also be a variable or hard coded value
        // instead of a function call.
        //
        UARTConfigSetExpClk(UART0_BASE, SysCtrlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE));
    //    UARTEnable(UART0_BASE);
        
      
        // Enable the uDMA controller.//
        uDMAEnable();
        
        UARTDMAEnable(UART0_BASE, UART_DMA_RX);
    
        // Init Copying Data from RAM to Flash //
        
        // Disable the uDMA channel to be used, before modifications are done.//
        uDMAChannelDisable(UDMA_CH9_UART0TX);
    
        // Set the base for the channel control table.//
        uDMAControlBaseSet(&ucDMAControlTable[0]);
    
        // Assign the DMA channel //
        uDMAChannelAssign(UDMA_CH9_UART0TX);
    
        // Set attributes for the channel.//
        uDMAChannelAttributeDisable(UDMA_CH9_UART0TX, UDMA_ATTR_HIGH_PRIORITY);
    
    
        // Now set up the characteristics of the transfer.
        // 32-bit data size, with source increments in words (32 bits), 
        // no destination increment.
        // A bus arbitration size of 1 must be used.
        uDMAChannelControlSet(UDMA_CH9_UART0TX, UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                              UDMA_DST_INC_NONE | UDMA_ARB_1);
    
    
        // Set transfer parameters. 
        // Source address is the location of the data to write
        // and destination address is the FLASH_CTRL_FWDATA register.
        uDMAChannelTransferSet(UDMA_CH9_UART0TX, UDMA_MODE_BASIC, ucSourceBuffer, 
                               (void *) UART_O_DMACTL, sizeof(ucSourceBuffer));
        
        
       // Stops Here
        
       
        
       
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }    
    }

    It's transmitting nothing to UART, And Stop at the last step.

    Thank you

  • Raghunandana DS,

     

    I had suggested that you use the uDMA controller to do UART tx. Regarding your code, I would recommend the following:

    The UART FIFOS are 16 x 8 bits, so you need to write 8-bit data

    • Use uint8_t instead of uint32_t for ucSourceBuffer
    • For uDMAChannelControlSet, change to
      • uDMAChannelControlSet(UDMA_CH9_UART0TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 |              UDMA_DST_INC_NONE | UDMA_ARB_1);

    You need to enable UART on the tx, not rx

    • Change to UARTDMAEnable(UART0_BASE, UART_DMA_TX);

    You must set destination of uDMA transfer to the UART data register address:

    • In uDMAChannelTransferSet, replace UART_O_DMACTL with (UART0_BASE + UART_O_DR)

    In the end, you need to enable the uDMA channel:

    • Add uDMAChannelEnable(UDMA_CH9_UART0TX) after the uDMAChannelTransferSet

    Use the UARTEnable

    • Add UARTEnable(UART0_BASE) after the uDMAChannelEnable

     

    (You may want to try commenting out the IOCPinConfigPeriphOutput and GPIOPinTypeUARTOutput for the tx.)

     

    After initializing the UART and setting up tx for uDMA, you should add a loop that will do the UART rx (ie read from uart and print to console) to check if it works.

     

    Regards,

    Toby