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.

EK-TM4C129EXL: Scatter Gather DMA Loops

Part Number: EK-TM4C129EXL
Other Parts Discussed in Thread: TLC6983, EK-TM4C1294XL

Hello,

I have some questions related to peripheral scatter gather DMA.

I need to send assorted frames of data from RAM to SSI0 using DMA. There will be occasional frames to update data to an LED driver IC (TLC6983) and regular frames to send idle states and sync messages. The TLC6983 demands a continuous back to back stream of SPI data (idle/sync). I plan to use scatter gather DMA with the source being areas of RAM defined in the DMA task list, the destination is always SS!0 TX register. Ideally the DMA will loop (as described in the data sheet) and send the idle states and the sync messages all on its own, but when a new image needs to be shown, a different task list be used to do this, then the DMA reverts to the idle/sync task list.

1. The data sheet states "the end of the list is marked by programming the control word for the last entry to use Auto transfer mode." - Should this be done when looping? I suspect not as it will stop the DMA controller. So, when looping should the last task list entry have the mode set to scatter gather, the same as the others?

2. When looping in this manner, is the DMA complete interrupt still set when the last transfer in the task list been run? (This would be the entry to copy the primary control structure to point back to the beginning of the list (or to a new list). If not is there any way to determine the end of the list has been reached?

3. The data sheet states that the last task list entry can point to a new list - how can I switch from task list A to a task list B in a seamless way, so ensuring back to back DMA transfers from task list A to task list B? Ideally the last task in the task list will be overwritten with the new one asynchronously, but to do this while the DMA controller is looping sounds dangerous, as the DMA controller might try to access it while it is being updated - unless this is double buffered in some way?. If it is updated in the DMA complete ISR it might be too late - the DMA will have already looped around and restarted the current task list.

4. This should work: Do not loop, but run task list A, then on DMA complete interrupt load task list B and start DMA - but this will cause a gap between SSI transmissions.

5. Related to (4) above, at what point exactly will the DMA complete interrupt be set? If it is when the last request is done then there could be the TX time of the last byte(s) over the SSI in which to service the DMA complete ISR.

Thanks in advance for your help,

Matthew

  • Hi,

    1. The data sheet states "the end of the list is marked by programming the control word for the last entry to use Auto transfer mode." - Should this be done when looping? I suspect not as it will stop the DMA controller. So, when looping should the last task list entry have the mode set to scatter gather, the same as the others?

    I think you are referring to the Memory Scatter-Gather mode rather than Peripheral Scatter-Gather. Please refer to the example in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\udma_scatter_gather. This example will do both Memory Scatter-Gather as well as Peripheral Scatter-Gather. For Peripheral Scatter-Gather the destination peripheral is a UART. But you should get the idea and can adapt to SSI. 

    If you look at the example task list, the last entry for memory scatter-gather is Auto Mode. For peripheral task list, the last entry is Basic. 

  • Thanks for your help. I’d really appreciate help, with questions 2 and 3 above if possible.

    Regards,

    Matthew

  • with questions 2 and 3 above if possible.
    2. When looping in this manner, is the DMA complete interrupt still set when the last transfer in the task list been run? (This would be the entry to copy the primary control structure to point back to the beginning of the list (or to a new list). If not is there any way to determine the end of the list has been reached?

    I suppose you are talking about peripheral scatter gather. If this is the case then no, there is no DMA complete interrupt to indicate the last transfer in the task list. Rather, the UART interrupt would have indicated that the task list is complete. See below example for scatter gather transfer to UART. For your application using SSI, the idea is the same. 

    //
    // If the UART1 DMA TX channel is disabled, that means the TX DMA transfer
    // is done.
    //
    if(!MAP_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
    {
    //
    // Start another DMA transfer to UART1 TX. Repeat the same peripheral
    // task list.
    //
    MAP_uDMAChannelScatterGatherSet(UDMA_CHANNEL_UART1TX, 3,
    pvUARTTxTaskList, true);

    //
    // The uDMA TX channel must be re-enabled.
    //
    MAP_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
    }

    3. The data sheet states that the last task list entry can point to a new list - how can I switch from task list A to a task list B in a seamless way, so ensuring back to back DMA transfers from task list A to task list B? Ideally the last task in the task list will be overwritten with the new one asynchronously, but to do this while the DMA controller is looping sounds dangerous, as the DMA controller might try to access it while it is being updated - unless this is double buffered in some way?. If it is updated in the DMA complete ISR it might be too late - the DMA will have already looped around and restarted the current task list.

    Agree that changing the task list while the DMA is ongoing to dangerous if it is done in an asynchronous fashion. You should change the task list only after the task list is complete and then restart the channel on the updated task list. 

  • Thank you for your help Charles,

    Regards,

    Matthew