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-TM4C1294XL: udma inquiry

Part Number: EK-TM4C1294XL

Hi Team,

I am posting on behalf of the customer.

From the datasheet about pingpong mode 9.2.6.3:
"When the transfer using the primary control structure is complete, the μDMA controller reads the alternate control structure for that channel to continue the transfer. Each time this happens, an interrupt is generated, and the processor can reload the control structure
for the just-completed transfer."

How is this interrupt enabled? In the pingpong example code, the ADC sequencer interrupt is called for each sample and used to poll whether the DMA transfer is done and setting up the new control structure.
I'm not able to figure out how to configure it from the datasheet either, as the uDMA module interrupts seems to be for error or only the SW channel, and the ADC DMA interrupts seems to only be for the ADC FIFO half full (table 9-2), and none of those seems to be useful for the ping pong setup?

To get more time to process the ADC samples and to get the most out of the DMA, I would like to only get an interrupt when the ADC_SAMPLE_BUF_SIZE number has been transferred to the buffer.

I am hoping you can help.

Regards,

Marvin

  • Hi Marvin,

    How is this interrupt enabled? In the pingpong example code, the ADC sequencer interrupt is called for each sample and used to poll whether the DMA transfer is done and setting up the new control structure.

      If you look at the transfer configuration, see below code, the transfer size parameter is ADC_SAMPLE_BUF_SIZE which is equal to 64. This is true for both the primary and secondary control structures. Therefore, only after 64 samples are transferred will the uDMA send a signal to ADC to generate an interrupt. I think what might be confusing to you is that you expect the uDMA to generate interrupt after the transfer is complete. However, this is not the case. uDMA only sends a "dma_done" signal to ADC module to notify the completion of the transfer. Upon receiving the signal, it is ADC who generates an interrupt. This is why you see the ADCSeq0Handler() ISR is used to handle the completion of the transfer. 

        //
        // Set up the transfer parameters for the ADC0 primary control structure
        // The mode is set to ping-pong, the transfer source is the ADC Sample
        // Sequence Result FIFO 0 register, and the destination is the receive
        // "A" buffer.  The transfer size is set to match the size of the buffer.
        //
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(ADC0_BASE + ADC_O_SSFIFO0),
                               &pui16ADCBuffer1, ADC_SAMPLE_BUF_SIZE);
    
        //
        // Set up the transfer parameters for the ADC0 primary control structure
        // The mode is set to ping-pong, the transfer source is the ADC Sample
        // Sequence Result FIFO 0 register, and the destination is the receive
        // "B" buffer.  The transfer size is set to match the size of the buffer.
        //
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(ADC0_BASE + ADC_O_SSFIFO0),
                               &pui16ADCBuffer2, ADC_SAMPLE_BUF_SIZE);
     

  • Thank you for you reply Charles.

    Are you sure about this? In the code, the sequencer 0 interrupt is enabled:

    ADCIntEnable(ADC0_BASE, 0);

    If I add a counter to the ADCSeq0Handler() to see how often it triggers, and print it out together with the ui32SamplesTaken, they are very close to being the same.

    So it does not seem like the sequencer interrupt is changing it's behavior when the DMA is enabled, it is still triggered after each sample.

     

  • If I add a counter to the ADCSeq0Handler() to see how often it triggers, and print it out together with the ui32SamplesTaken, they are very close to being the same.

    I think there are two things are play here. See below line of code. First the ADC sequencer 0  is set up to sample only one channel. Upon completion of ADC_CTL_CH0, it will generate a DMA request. Although the FIFO for sequencer 0 can hold 8 samples, but you only have channel setup and therefore you can think of FIFO depth as 1 in this case. If you have 8 channels setup for sequencer 0 then you would see it generate dma_req when FIFO is full with 8 samples. 

    ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END |
    ADC_CTL_IE);

    15.3.2.2 DMA Operation
    DMA may be used to increase efficiency by allowing each sample sequencer to operate independently
    and transfer data without processor intervention or reconfiguration.
    The ADC asserts single and burst μDMA request signals (dma_sreq and dma_req) to the μDMA
    controller based on the FIFO level.

     Next is the below line where the arbitration boundary is set to UDMA_ARB_1. When the arbitration size is set to 1, the uDMA will rotate out to other channels for every one transfer. If you change from UDMA_ARB_1 to UDMA_ARB_64 then you can force uDMA to stay with ADC channel for up to 64 data before sending back ADC an dma_done signal. Please try change to UDMA_ARB_64 for both the primary and alternate control structure and I think you should see the difference in behavior. 

    uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 |
    UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);

  • Thanks again for you reply. Have you tested this yourself?

    I changed the arbitration size, and there ADC sequencer 0 interrupt is still triggered after each sample, which I do believe is the correct behavior for that interrupt.

    I would like to only get an interrupt when the ADC_SAMPLE_BUF_SIZE have been transferred to the buffer, not after each sample, is this possible?

    -Marte

  • Hi,

      I was out of office the last few days and just got back. 

    Have you tested this yourself?

    Yes, I did. I put a breakpoint at line 188. After the processor went to this line twice, I see there are 128 samples transferred. Why don't you try for yourself.