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.

HOW TO DETERMINE THE CLOCK SPEED OF TM4C129x ADC and VARY THE SAMPLING RATE USING TIMERS

Other Parts Discussed in Thread: TIDM-TM4C129POEAUDIO

Hi,

I'am using TM4C1294XL launchpad. Basically i want to change the sampling Rate of the ADC to 1khz using Timers.

My system clock is set to 120Mhz using the below command

ui32SysClkFreq= SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

I'am trying to set the ADC clock configuration with the below API

ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24);

When i check the ADC clock configuration using

 ui32Config = ADCClockConfigGet(ADC0_BASE, &ui32ClockDiv);

it shows me value of ui32Config is 112?? I don't understand why is it showing 112???

Also i'am using timer interrupt to trigger the ADC. How to calculate the value of Timerload set so that my sampling rate changes to 1khz.???

Below is my code


void Timer0IntHandler(void)
{
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_TIMER, 0);
    
}

int main(void)
{
    uint32_t ui32Period;


    uint32_t ui32Config, ui32ClockDiv;

 
    inputF32 = &inputsamples[0];

    outputF32 = &testOutput[0];

     

    ui32SysClkFreq= SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);


    /******* ADC INITIALIZATION***********/
    SysCtlPeripheralDisable(SYSCTL_PERIPH_ADC0);

            SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)));

         ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24);

         ui32Config = ADCClockConfigGet(ADC0_BASE, &ui32ClockDiv);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)));

        GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);


        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);


        //GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

            TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

            ui32Period = 16000000/160000;

            TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period-1);


            TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
         

          
            ADCSequenceDisable(ADC0_BASE, 1);
            //ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
            ADCSequenceStepConfigure(ADC0_BASE,1,0,ADC_CTL_CH0);
            ADCSequenceStepConfigure(ADC0_BASE,1,1,ADC_CTL_CH1);
            ADCSequenceStepConfigure(ADC0_BASE,1,2,ADC_CTL_CH2);
            ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END);
            ADCSequenceEnable(ADC0_BASE, 1);

/*********************************************************************/
            /******* UART6 & INTERRUPT INITIALIZATION***********/
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);

        GPIOPinConfigure(GPIO_PP0_U6RX);
        GPIOPinConfigure(GPIO_PP1_U6TX);
        IntMasterEnable();
        GPIOPinTypeUART(GPIO_PORTP_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        UARTConfigSetExpClk(UART6_BASE, ui32SysClkFreq, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));


      


        IntEnable(INT_UART6);


        UARTIntEnable(UART6_BASE, UART_INT_RX | UART_INT_RT);


     
        IntEnable(INT_TIMER0A);


        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
     
        TimerEnable(TIMER0_BASE, TIMER_A);
    


     

        while(1)
        {

            ADCIntClear(ADC0_BASE, 1);


            while(!ADCIntStatus(ADC0_BASE, 1, false))
            {
            }
        ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
        CH1ADC = ui32ADC0Value[0];
        CH2ADC = ui32ADC0Value[1];
        CH3ADC = ui32ADC0Value[2];
        CH4ADC = ui32ADC0Value[3];

}

}

  • Hello Sumit

    The value of 0x112 is based on the parameters that you have setup for the ADCCC and the ADCPC register. The lower byte is indicative of the divider value and the upper nibble of the Sampling Rate.

    You can refer to the software in the following TI Reference Design software (audiocontrol.c) for setting up the timer (via an external GPIO loopback) for ADC sampling: TIDM-TM4C129POEAUDIO

    Further more, you can refer to the touch.c file in DK-TM4C129X driver software files for setting up a timer.
  • Hi Amit,

    I really appreciate your reply to my post!

    My Main concerns is:
    1). I need to have control over sampling rate of ADC because i'am using CMSIS DSP lib to calculate the FIR LPF coeffecients through Matlab.
    I'am getting the result of the filter but it is not correct as I'am not sure about the sampling rate.

    I've read in TI forum that ADCClockConfigGet(ADC0_BASE, &ui32ClockDiv) gives a bug of 112 .
    However my concern is that ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24) should set the clock to 20Mhz .

    Even if it is fixed , I want to know How to control the sampling rate of the ADC???? If i divide 20000000/20000, will it change the sampling frequency to 1khz???

    I understand that my problem is relate to ADC clock configuration & timer load set value.
  • Hello Sumit

    Setting the ADCCC register decides the rate at which the communication between ADC analog and the digital controller will be established. Considering the use case here it would result in a maximum sample rate of 1.25 MSPS (20MHz / 16 clocks of conversion).

    To decided on the sampling rate the timer clock has to be considered and not the ADC clock. The system is you cases is configured for 120MHz. So to get 1KHz the load value should be 120MHz/1KHz = 120,000. this value cannot fit in a 16-bit timer mode. So the timer needs to be configured for 32-bit mode.
  • Hi amit,

    How to configure the timer for 32-bit mode??
    I'am confused here..Could you please tell me the code for my configuration requirement.
    All i want to achieve is 1Khz sampling rate of the ADC.
    its really important for me because my project completion will result in our company's mass production of our product
  • Hello Sumit

    Please refer to the code file in TivaWare

    D:\ti\TivaWare_C_Series-2.1.3.156\examples\boards\dk-tm4c129x\drivers\touch.c

    The function TouchScreenInit shows how to configure a timer for ADC trigger. In the code the timer is configured for 16 bit mode with sub-timer B. What you would need to do is to replace

    ROM_TimerConfigure(TIMER5_BASE, (TIMER_CFG_SPLIT_PAIR |
    TIMER_CFG_A_PWM |
    TIMER_CFG_B_PERIODIC))

    with

    ROM_TimerConfigure(TIMER5_BASE, TIMER_CFG_A_PERIODIC);

    in your code. Replace the TIMER_B define with TIMER_A define and adjust the TimerLoadSet API for 120,000 for 1KHz trigger.
  • Hi amit,

    you mean to say thay I should change my code to below mentioned(considering I'am not using ROM)

    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

    ui32Period = 12000000/1000;

    TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period-1);
  • Hello Sumit

    Yes, that is correct, except that the System clock value has one less "0" for 120MHz.
  • Thanks Amit,

    Great answers!!!! No wonder Ti products are amazing and there support service.....

    I'am really thankful for your support. Will get back if i face any further problem in my development for CMSIS DSP lib.( will be posting in a new post)
  • Sumit Mourya said:
    its really important for me because my project completion will result in our company's mass production of our product

    And price, delivery, feature set, new product introductions (by this vendor or (God forbid) others) shall have NO bearing on such, "mass production!"

    Repeatedly vendor's Amit has proved that he requires no such "motivation" to do his (usual) great job for client-users here...

  • Thumbs up for this post.

    I have a hard time to fathom the obvious lack of diligence in many "locations" when tackling projects ...