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.

LAUNCHXL-CC1352P: DMA TI-RTOS memory to memory example

Part Number: LAUNCHXL-CC1352P

Dear Support:

Is there any example code available that shows me what I need to do to perform a DMA memory-to-memory transfer using TI-RTOS?

The DMA example code I see in the SDK is tied to a peripheral.  Currently I am using the CPU to move memory from one location to another and would like to use the DMA to do this, but am in a TI-RTOS environment and don't see any example code that I can use for a reference vs using bare-metal code.

Ideally I would like to take the lower byte of a buffer that is 16-bit wide data and transfer it to another buffer that is byte-wise and pack it so that the lower bytes of the 16-bit buffer is moved to another buffer that is packed 8-bit wide data.  Would be nice if we have any example code that would provide this as a reference.  Please advise.

Thanks,
Tim

  • Hi Tim,

    There is no such examples as you have seen, this as there is no high-level driver provided for using the DMA today. You could leverage the CC26XX DMA driver layer used by the SPI to some extent, but you would have to fill in with some DriverLib APIs as well. Here is a small example on how you could make a software triggered transfer:

    #include <ti/drivers/dma/UDMACC26XX.h>
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    #include DeviceFamily_constructPath(inc/hw_gpt.h)
    #include DeviceFamily_constructPath(inc/hw_event.h)
    #include DeviceFamily_constructPath(driverlib/udma.h)
    
    /* Allocate the DMA software 0 table */
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaSoftwareDmaPri, UDMA_CHAN_SW_EVT0);
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaSoftwareDmaAlt, (UDMA_CHAN_SW_EVT0 + UDMA_ALT_SELECT));
    
    uint16_t mySoftwareTable[5] = {1, 2, 3, 4, 5};
    
    UDMACC26XX_Handle dmaHandle;
    
    /* Open the uDMA driver */
        dmaHandle = UDMACC26XX_open();
        while(!dmaHandle){};
    
    /* 1. ================= Software triggered DMA from table to single variable ================= */
    
        /* Dummy variable to write to */
        uint16_t dummy = 0;
    
        /* Setup DMA transfer table */
        dmaSoftwareDmaPri.ui32Control =  UDMA_MODE_BASIC |                                                             // Basic mode
                                         UDMA_SIZE_16 |                                                                // 16-bit transfers
                                         UDMA_SRC_INC_16 |                                                             // Increment source address as 16-bit
                                         UDMA_DST_INC_NONE |                                                           // Do not increment destination address
                                         UDMA_ARB_1 |                                                                  // Arbitrate system bus for 1 transfer at a time
                                         UDMACC26XX_SET_TRANSFER_SIZE(sizeof(mySoftwareTable) / sizeof(uint16_t));     // Setup number of transfers (in frames of 16-bit)
        dmaSoftwareDmaPri.pvSrcEndAddr = (void *)(mySoftwareTable + (sizeof(mySoftwareTable) / sizeof(uint16_t)) - 1); // Set source end address (mind the pointer arithmetic)
        dmaSoftwareDmaPri.pvDstEndAddr = &dummy;                                                                       // Set destination end address
    
        /* Enable DMA software channel 0 */
        UDMACC26XX_channelEnable(dmaHandle, 1 << UDMA_CHAN_SW_EVT0);
    
        /* Trigger SW DMA transfer event */
        uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
        while(uDMAGetStatus(UDMA0_BASE) & 0xF0);
        /* Dummy is now 1 */
        uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
        while(uDMAGetStatus(UDMA0_BASE) & 0xF0);
        /* Dummy is now 2 */
        uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
        while(uDMAGetStatus(UDMA0_BASE) & 0xF0);
        /* Dummy is now 3 */
        uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
        while(uDMAGetStatus(UDMA0_BASE) & 0xF0);
        /* Dummy is now 4 */
        uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
        while(uDMAGetStatus(UDMA0_BASE) & 0xF0);
        /* Dummy is now 5 */
    
        /* Disable DMA software channel 0 */
        UDMACC26XX_channelDisable(dmaHandle, 1 << UDMA_CHAN_SW_EVT0);

  • Thanks MW - this is helpful and pretty much what I needed.  I appreciate the quick response and details.  Per my understanding from the TRM:

    it appears that the CC1352 would not be able to move the lower bytes from a 16-bit word buffer and move only the lower 8-bits from this source buffer to a destination buffer that is an 8-bit buffer such that the bytes were contiguous in the destination buffer.  Hence the source data size would be 16-bits and the destination data size would be 8-bits.   Is this not possible with the uDMA of the CC1352?

    Thanks,
    Tim

  • Hey MW:

    Whoops, looks like the cut-and-paste from the TRM didn't get copied properly into the forum post.  I was referring to Section 14.3.7 Transfer Size and Increments which the 2nd sentence says: "The source and destination data size must be the same for any given transfer".

    Tim

  • Hi Tim,

    I would assume you could get it to work if you treat both destination and source as 8-bit buffers. You could the choose to increment the source buffer by steps of 16-bits while using 8-bit steps for the destiantion. I have not tested this myself but it should be rather quickly done using the example I posted above. 

  • Hey M-W:

    Yes, that is a good point and you're right should work.  I will check this out with your example - much appreciated your help and advice.

    Thanks,
    Tim