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.

uDMA and ADC triggered by Timer 0 on 129x (PINGPONG mode)

Hello. I have found a new issue with my 129 development board.

I have written some code to get 2-channels  1024 ADC samples with DMA, using a Timer as the trigger for the ADC (that is why we are using ADC_TRIGGER_TIMER).

This code was working on the 123 boards. 

However,  inside the  ADC interrupt handler, uDMAChannelModeGet is always stuck in mode UDMA_MODE_PINGPONG, so I never get the samples into the destination array. I am watching in the timer debug pin, the desired frequency.

The ADCinterrupt handler is called in every timer cycle.

Is there anything new with the uDMA interrupts for the 129x family?

 

Here is some code:

void ADC2IntHandler(void)
    {



    cnt_DMA_int++;
    clk_ADC2IntHandler=!clk_ADC2IntHandler;
    Shot_debug_signal2(clk_ADC2IntHandler);

    ulStatus = ADCIntStatus(ADC0_BASE, ADC_SEQUENCER,false);

    // Clear the ADC interrupt

    ADCIntClear(ADC0_BASE, ADC_SEQUENCER);

    //
    // If the channel's not done capturing, we have an error
    //
    /*if (uDMAChannelIsEnabled (UDMA_CHANNEL_ADC2))
     {
     g_ulBadPeriphIsr2++;
     return;

     }/**/

    /*  if (uDMAChannelIsEnabled(UDMA_CHANNEL_ADC2))
     {
     g_ulBadPeriphIsr2++;
     // ADCIntDisable(ADC0_BASE, ADC_SEQUENCER);
     //   IntPendClear(INT_ADC0SS2);
     // return;
     }

     //
     // Verify count remaining is 0.
     //
     ulMode = uDMAChannelSizeGet(UDMA_CHANNEL_ADC2);
     if (ulMode)
     {
     g_ulBadPeriphIsr1++;
     //return;
     }


     /**/


    ulMode = uDMAChannelModeGet(UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT);

    if (ulMode == UDMA_MODE_STOP)
	{
	cnt_bloque1++;


	uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)), g_ulADCValues, 2 * NUM_SAMPLES);/**/

	flag_ADC_ready = 1;

	//UARTprintf("Block  1 - ADC: %d", cnt_bloque1);

	}


    ulMode = uDMAChannelModeGet(UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT);

    if (ulMode == UDMA_MODE_STOP)
	{

	cnt_bloque2++;

	uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)), g_ulADCValues, 2 * NUM_SAMPLES);/**/

	flag_ADC_ready = 1;

	uDMAChannelEnable (UDMA_CHANNEL_ADC2);

	//UARTprintf("Block  2 - ADC: %d", cnt_bloque2);
	}

    }

Thank you

Thank you

  • Hello PAk,

    Massive code... And yes there are changes in TM4C129x

    Anyways, the DMA Request from ADC has to be enabled using

    ADCSequenceDMAEnable

    Secondly you need to set the ADCIM.DMAMASKn for the correct sequencer and in the Interrupt Handler has to use the ADCMIS.DMAMASKn status bit to check if the Ping-Pong is done.

    Regards

    Amit

  • Amit Ashara said:

    Hello PAk,

    Massive code...

    You are right....it was just to show you everything to rule out some common errors (startup_css.c, interrupt handlers, etc).

    Corrected.

    Amit Ashara said:

    And yes there are changes in TM4C129x

    Anyways, the DMA Request from ADC has to be enabled using

    ADCSequenceDMAEnable

    Secondly you need to set the ADCIM.DMAMASKn for the correct sequencer and in the Interrupt Handler has to use the ADCMIS.DMAMASKn status bit to check if the Ping-Pong is done.

    Is there any document where all this information is collected?

    I found a reference about ADCSequenceDMAEnable in the document spma065 you pointed us, but nothing about ADCIM, not there neither the workshop.

    Regards

     

  • Hello PAk,

    The user guide is the document to refer to. Also I would suggest a read of the UDMA chapter for interrupts as this has changed between TM4C123 and TM4C129. In TM4C129 the peripheral interrupt and dma done interrupt can now come at the same time unlike on TM4C123 where DMA interrupt on peripheral interrupt line used to block the peripheral interrupt sources.

    The ADCIM is accessed through the ADCIntEnable and it has additional macros for unmasking the DMA as source of interrupt.

    Regarda

    Amit