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.

CC1310: DMA UART

Part Number: CC1310

Hi
I try to enable DMA transfer from the Uart Tx on CC1310 by software request
but without success. I use simplelink_cc13x0_sdk_2_20_00_38
As a memory to Memory transfer, Dma works fine.
What I miss in the following code?

With regards

u8 u8DMAControlTable[64] __attribute__ ((aligned(1024)));

extern u8   u8uart_tx_Buf[200];                             // Source buffer used for the DMA transfer.

// ----------------------------------------------------------------------------
void uDma_init(void)
{
    EventRegister(EVENT_O_UDMACH2BSEL, EVENT_UDMACH2BSEL_EV_UART0_TX_DMABREQ);
    UARTDMAEnable(UART0_BASE, UART_DMA_TX);                 // uart dma enable for transmit

    PRCMPeripheralRunEnable(PRCM_PERIPH_UDMA);
    PRCMLoadSet();

    uDMAEnable(UDMA0_BASE);                                                      // Enable the uDMA controller.
    uDMAControlBaseSet(UDMA0_BASE, u8DMAControlTable);      // register the channel control table.
    uDMAChannelAttributeDisable(UDMA0_BASE, UDMA_CHAN_UART0_TX, UDMA_ATTR_ALL);
    uDMAChannelAttributeEnable (UDMA0_BASE, 
                                UDMA_CHAN_UART0_TX,
                                UDMA_ATTR_USEBURST |		                    // burst transfer
                                UDMA_ATTR_REQMASK);

    // set up characteristics of the transfer
    uDMAChannelControlSet(  UDMA0_BASE,
                            UDMA_CHAN_UART0_TX | UDMA_PRI_SELECT,

                            UDMA_SIZE_8 |                   // 0x00000000
                            UDMA_SRC_INC_8 |            // 0x00000000
                            UDMA_DST_INC_NONE |    // 0xC0000000
                            UDMA_ARB_8);                    // 0x0000c000
}

// ----------------------------------------------------------------------------
void uDma_startTransfer(void)
{
    uDMAChannelTransferSet( UDMA0_BASE,
                            UDMA_CHAN_UART0_TX | UDMA_PRI_SELECT,
                            UDMA_MODE_BASIC,                // transfer automatically runs to completion after the request
                            &u8uart_tx_Buf[1],                       // pointer to the data source
                            (u8 *)(UART0_BASE + UART_O_DR), // pointer to the destination,
                            u8uart_tx_Buf[0]);                         // transfer size

    uDMAChannelEnable (UDMA0_BASE, UDMA_CHAN_UART0_TX);
    uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_UART0_TX);
}

  • Hi Boris, 

    Thanks for question.

    I'll look into this and get back to you as fast as possible. 

    Thanks, 
    Elin

  • Hi Elin.

    Is there some news?

    We are seriously stuck without a solution.

    IAdd another pies of code that how we enabling UART.

    void uart_init(void)
    {
        UART_init();
    
        {// initialize uart
            UART_Params uartParams;
            UART_Params_init(&uartParams);
            uartParams.readMode = UART_MODE_CALLBACK;           // Non-blocking and will return immediately. When UART_write() or
                                                                // UART_read() has finished, the callback function is called from either
                                                                // the caller's context or from an interrupt context.
            uartParams.readCallback = Rx_UART_Callback;
            uartParams.readTimeout = 1;                         // UART_Params.readTimeout is not in use when using UART_MODE_CALLBACK mode.
    
            uartParams.readDataMode = UART_DATA_BINARY;
            uartParams.readReturnMode = UART_RETURN_FULL;       // Unblock/callback when buffer is full.
            uartParams.readEcho = UART_ECHO_OFF;
    
            uartParams.writeMode = UART_MODE_CALLBACK;          // Non-blocking and will return immediately. When UART_write() or
                                                                // UART_read() has finished, the callback function is called from either
                                                                // the caller's context or from an interrupt context.
            uartParams.writeCallback = Tx_UART_Callback;
            uartParams.writeTimeout = 1;
    
            uartParams.writeDataMode = UART_DATA_BINARY;
            uartParams.baudRate = 19200;
    
            uart_Handle = UART_open(Board_UART0, &uartParams);
    
            if (uart_Handle == null)
                GenError("019");
        }// initialize uart
    
        UART_control(uart_Handle, UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE, NULL);
    
        UARTFIFODisable(UART0_BASE);                // 0x40001000
    
    UARTDMAEnable(UART0_BASE, UART_DMA_TX);                 // uart dma enable for transmit
    
        stWre_Status.Flags.UartRead = 1;
        UART_read(uart_Handle, Rx_UART_Buf, 1);
    }

    Regard

    Boris

  • Hi Boris, 

    Thanks for the update. 

    It's difficult to comment on what can be missing or incorrect in the code without knowing what problem you are seeing on your end. Can you describe the issue you are experiencing? 

    Thanks, 
    Elin 

  • Hi Elin

    Generally, we try to communicate via UART when receiving direction handled by Rx interrupts, rather transmit imposed to be done through the UART DMA since the decision to transmit and transmit start done inside RX interrupt.
    This will reduce the impact on CPU and time that the interrupts steal from RTOS.

    The code of uDMA and UART handling already been sent to you.
    So when function void uDma_startTransfer(void);  is invoked I expect to see UART starts to transfer data. This doesn't happen.
    My feeling that I misunderstood somewhat in EventRegister(..)

    Please your help

  • Hi Boris,

    I'm sorry for the delay.

    As a start - did you look into the Technical Reference Manual chapter on DMA:

    It looks like you're not allocating the control table entries. You can do this with register writes (explained in the TRM) or you can use the ALLOCATE_CONTROL_TABLE_ENTRY() macro defined in the driver.

  • Hi Marie

    Thanks for the answer. 

    Of course, I looked in the TRM. 

    Again, I got no problem with memory to memory transfer. And as I assume that means that the control table and the appropriate control table entry are defined correctly. 

    In addition, when I set up the uDMA channel for the UART transfer, using the uDMAChannelControlSet(), the desired table entry in the case of UART it UDMA_CHAN_UART0_TX, which is 2,

    receives correct values (I browse it via debugger).

    The head of the thread includes two functions that initiate the transfer: void uDma_init(void) and void uDma_startTransfer(void) both, of them about twelve lines. Could you please indicate what is wrong with these functions? Or, alternatively, send a sample code that works.

    However, if you insist on using ALLOCATE_CONTROL_TABLE_ENTRY(ENTRY_NAME, CHANNEL_INDEX)

    please point where can I find the definitions for the ENTRY_NAME.  As I understand, CHANNEL_INDEX in my case is UDMA_CHAN_UART0_TX. Is it correct?

     

    Thanks for your cooperation.

  • Hi, 

    This question is being resolved over email. 

    Thanks, 
    Elin 

  • Hi Elin.

    Unfortunately, I've got from You by email only '.h' file which describes structures that suppose to support UART uDMA.

    But there are no '.c' files. 

    Regards 

    Boris

  • Hi Boris, 

    Unfortunately, the .h file is the only one that's available for this kind of example. 

    Thanks, 
    Elin