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.

Why do I experience ADC jitter on Tiva C Launchpad?

Other Parts Discussed in Thread: TM4C123GH6PM

Hello!

I'm using TI Tiva C TM4C123GH6PM on the Tiva C launchpad to drive an AD9850 DDS chip.  Programming is done in Code Composer Studio 5.5. My clock frequency is 80 MHz.

My basic workflow is right now relatively simple:

I have a main function and at its beginning I set up TM4C's peripherals and reset the AD9850. The peripherals I use are GPIO ports B,E and F via the AHB. I also use the ADC0 and FPU.


Next comes a loop in which I sample the ADC, calculate settings for the AD9850 and then transfer them using GPIO ports. The calculation and transfer part is constant an takes around 10.4 microseconds. I confirmed this by having a pin go high and then low at the end of the data transfer.

What is problematic is the part where I'm waiting for the ADC to finish. The time it takes for it to do conversion does not seem to be constant.


Here's code I used to set up the ADC:

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);//Pin is PD1=>channel AIN6
ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 64);
//Averages 64 samples and stores them in one FIFO slot,
//has apparently no effect on the conversion time, same results when disabled

HWREG(ADC0_BASE+ 0x038) = 0x40;//This enables hardware dithering


ADCSequenceConfigure(ADC0_BASE,3,ADC_TRIGGER_PROCESSOR,0);
//Uses ADC0, sequence 3=>FIFO with length of one, highest prioroty
ADCSequenceStepConfigure(ADC0_BASE,3,0,ADC_CTL_CH6|ADC_CTL_IE|ADC_CTL_END);
//First and last step, selects ADC0, sequence 3, step zero, channel 6,
// enables interrupt and ends sequence
ADCSequenceEnable(ADC0_BASE,3);
//Enables sequence

Here's the code I'm using to get the ADC data and toggle a pin when it's done:

ROM_ADCIntClear(ADC0_BASE, 3);//clears interrupt flag

while(!ROM_ADCIntStatus(ADC0_BASE, 3, false))//Waits for ADC to finish converting
{//Busy wait to be replaced with an ISR at some point
}
ROM_ADCSequenceDataGet(ADC0_BASE, 3, adcData);
//adcData pointer to memory location GPIOPinWrite(GPIO_PORTE_AHB_BASE, GPIO_PIN_1, 2);
GPIOPinWrite(GPIO_PORTE_AHB_BASE, GPIO_PIN_1, 0);

My idea is to later on trigger ADC from a timer interrupt and then do the data processing in ADC's interrupt, but before that, I want to understand what exactly is happening here.

Here's an image of the pin I'm wiggling when the ADC finishes:

  • Hi Andreja,

    There are a few clocking items at play here

    1. The System clock is running at 80MHz and is definitely coming from the PLL which adds jitter of it's own (that may not be of consequence when seen in stand alone)

    2. The ADC sampler is working at 16MHz. The Interrupt on conversion has to be synchronized across the clock domains and so does the data which is to be read by the M4. These clock edges may not align all the time and hence the synchronization has to ensure that when it does not the data is still transferred correctly from ADC conversion clock domain to System Clock Domain.

    What is important to assess here is if the expectation between two successive GPIO toggles is X (assuming that ADC operation is the only step being run) then how much does it vary on +/- side. I would expect it to be not more than ~100ns, if all the code is using ROM. But if code from Flash is being executed then for TM4C123 Flash Wait times also have to be factored in which can make it substantial.

    Amit