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.

CCS/F28M35H52C: Wrong timing for a 32-bit timer count decrement

Part Number: F28M35H52C
Other Parts Discussed in Thread: CONTROLSUITE

Tool/software: Code Composer Studio

Hi,

   I am implementing a timer with no interrupt (ie. timer runs in the background) on Concerto.

The content in the datasheet and what is happening in the real scenario is slightly different. 
I am using the 32-bit timer. So, I loaded the TAILR register with 0xFFFFFFFF. The register value went down to 0 in 171.6 secs.
This is not what I calculated.
(2^32) * (1 /75 x10^6) = 57.266 sec (I am using 75MHz clock on M3)
I also checked various other load values:
0xFFFFFFFF = 171.6 sec
0xFFFFFF     = 222.8 msec
0xFFFF         = 7.87 msec
0xFF             = 10.25 usec
10                 = 884 nsec
1                   = 540 nsec
 
To my understanding, 1 count decrement should happen in 1/75M = 13.33 nsec but it actually took 540nsecs. Is the clock running slow?
Right now, I am unsure of what value of time should be used as time per count to calculate the time elapsed. 
 
 
Thank you for your time,
Anoja
  • Anoja,

    Please double check the source clock values and divide settings.  It looks like you are off by a factor of 3.  For reference, please see lab 2 in the F28M35 workshop:

    https://training.ti.com/c2000-f28m35x-microcontroller-workshop?cu=1137791

    Also, please see the timer example in controlSUITE at:

    C:\ti\controlSUITE\device_support\f28m35x\v220\F28M35x_examples_Master

    I hope this helps. If this answers your question, please click the green "Verified Answer" button. Thanks.

    - Ken

  • Hi Ken,

       The example at  C:\ti\controlSUITE\device_support\f28m35x\v220\F28M35x_examples_Master uses timer interrupt. What I want is to run timer in background and read the TAR register when required.

    Here is my settings:

       // Disable the timers.
        HWREG(TIMER0_BASE + TIMER_O_CTL) &= ~(TIMER_CTL_TAEN | TIMER_CTL_TBEN);
    
        // Clean timer configuration register - 32bit configuration
        HWREG(TIMER0_BASE + TIMER_O_CFG) = 0x00;
    
        //Configure mode register - periodic
        HWREG(TIMER0_BASE + TIMER_O_TAMR) = 0x02;
    
        // Load start value
        HWREG(TIMER0_BASE + TIMER_O_TAILR) =  0xFFFFFFFF;
    
        // Enable the timer module.
        HWREG(TIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TBEN);

     The clock setting I used is

    // Setup main clock tree for 75MHz - M3 and 150MHz - C28x
    SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
    SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 | SYSCTL_XCLKDIV_4);

    This is what I am unsure of. In a while loop, I am polling when the load value goes to 0. Can you tell me if there is another way to test the count decrement of timer?

        while(1)
        {
            unsigned long loadValue = HWREG(TIMER0_BASE + TIMER_O_TAR);
            if(!loadValue)
            {
                GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_6,~GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_6)); 
            }
        }

  • Anoja,

    The issue is you are using the timer in periodic mode:

    //Configure mode register - periodic

     HWREG(TIMER0_BASE + TIMER_O_TAMR) = 0x02;

    This means when counter expires on next cycle it will restart and checking the value of 0x0 in TAR register is not deterministic:

    while(1)
    {
        unsigned long loadValue = HWREG(TIMER0_BASE + TIMER_O_TAR);
        if(!loadValue)
        {
            GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_6,~GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_6));
        }
    }

    Therefore, by the time you read the value, the counter may have restarted again. It would be best to use interrupts or read the interrupt status register instead of the value or use one-shot mode instead of periodic mode.

    This should explain the issue you are experiencing.  If this answers your question, please click the green "Verified Answer" button. Thanks.

    - Ken

  • Anoja,

    It's been a while since I have heard from you last. Therefore, I am assuming that my last reply resolved your issue and I will close this thread. If this isn’t the case, please reject this resolution or reply to this thread. If this thread locks, please make a new thread describing the current status of your issue. Thank you.

    - Ken

  • Hi Ken,

    I found the issue. The below code worked fine.

    I am using timer0 without interrupt.

        // Disable the timers.
        HWREG(TIMER0_BASE + TIMER_O_CTL) &= ~(TIMER_CTL_TAEN | TIMER_CTL_TBEN);
    
        // Clean timer configuration register - 32bit configuration
        HWREG(TIMER0_BASE + TIMER_O_CFG) = 0x00;
    
        //Configure mode register - periodic
        HWREG(TIMER0_BASE + TIMER_O_TAMR) = 0x02;
    
        // Load start value
        static long ticksPerMillisecond = 0x3A9C; //0.2msec
    //    static long ticksPerMillisecond = 0xB726C; //10msec
        HWREG(TIMER0_BASE + TIMER_O_TAILR) =  0xFFFFFFFF;
    
        // Enable the timer module.
        HWREG(TIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TBEN);
    
        // Set the stall mode.
        HWREG(TIMER0_BASE + TIMER_O_CTL) |= TIMER_CTL_TASTALL | TIMER_CTL_TBSTALL;
    

    And in the while loop:

    static unsigned long oldValue = 0;
    
        oldValue = HWREG(TIMER0_BASE + TIMER_O_TAR);
        // Loop forever while the timers run.
        while(1)
        {
            unsigned long volatile newValue = HWREG(TIMER0_BASE + TIMER_O_TAR);
            unsigned long elapsed = oldValue - newValue;
            if(elapsed >= ticksPerMillisecond)
            {
                GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_6,~GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_6)); 
                oldValue = newValue;
            }
        }