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.

CC2640R2F: How to reset the GPT timer value after timer stop when using the RTOS driver

Part Number: CC2640R2F

Hi,

I am using a GPT timer in CC2640R2F in conjunction with RTOS driver GPTimerCC26XX to create semaphores after a certain delay time.I am using the GPT_MODE_ONESHOT_UP offered by the driver.There are events where I need to stop the timer before it reaches the match value in order to avoid the semaphore. In the cases when I stopped the timer and I want to engage the timer again by setting a new match value and start the timer again I realize that the counter value of the timer is still at the point when I stopped the timer. Therefore I am looking for a way to set the counter value of the timer to zero. There is no function in the RTOS driver and I did not find a proper command in the driverlib.

How can a get the counter value to zero after stopping it by the driver function GPTimerCC26XX_stop?

The commands I am using is:

// ****** Initialization

     GPTimerCC26XX_Handle  SCB_Timer;

    GPTimerCC26XX_Params params;
    GPTimerCC26XX_Params_init(&params);
    params.width          = GPT_CONFIG_16BIT;
    params.mode           = GPT_MODE_ONESHOT_UP;
    params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    SCB_Timer = GPTimerCC26XX_open(SCN_SCBTimer_Id, &params);
    if (!SCB_Timer) {
        Report_System_Message(SYSTEM_MESSAGE_SCBTIMER_OPEN_FAIL);
        Task_exit();
    }
    GPTimerCC26XX_registerInterrupt(SCB_Timer, SCB_TimerINT_SendSemaphoreAfterDelay, GPT_INT_TIMEOUT);

// ........the timer is used then in a lot of stages in a state machine to create the delayed semaphore by the following inline function

inline void SCB_SetTimerIntForDelayedFunctionCall(UInt32 Delaytime)
{

    GPTimerCC26XX_setLoadValue(SCB_Timer, Delaytime);         
    GPTimerCC26XX_start(SCB_Timer);
}

Thanks in advance and best regards

Berthold

  • Hi Berthold,

    I'm not seeing in your provided code where GPTimerCC26XX_stop is called.
    However, using GPTimerCC26XX_setLoadValue(SCB_Timer, 0) once it is stopped should reset it.

    -Sy Su
  • Hi Sy,

    thanks for your quick reply, however I think the timer is not reset by the SetLoadValue(SCB_Timer, 0) command. I have created a short program which demonstrates my problem by some Oscilloscope shots (see below).

    In this program I have implemented two timers (Timer1 and Timer2) and I use a digital output Board_DIO1 which show the timer result and which I added the scope shots.

    I initially start Timer1 and Timer2 at the same time, whereby Timer1 is loaded with a delay time of 8ms and Timer2 is loaded with a delay time of 5 ms. Both timers call an interrupt routine which creates a semaphore, the main program is waiting for this semaphore . After Timer2 has finished the 5ms delay the main program continues and stops the Timer1 which has not yet reached the match value. In the second step I want to create another 2ms delay with Timer1 (which was stopped before) and create another pulse of 2 ms . The desired result of the digital output is a pulse of 5ms closely followed by a 2ms delay and another 2 ms pulse. The Oscilloscope shot shows that there is a delay of roughly 350ms between the 1st and 2nd pulse which I only can explain that the timer value is not reset when loading the 2ms match value but still has the 5ms from the first run - as a matter of fact the timer completely counts up the 24 value which is 0xFFFFFF at 48MHz or 350ms and then reaches the match value of 2ms. I have also tried your proposal of setting a SetLoadValue(Timer1, 0) after the Timer_stop() but there was no different result.

    Reading the technical reference I also understand that the timer value is only reset to the load value for the count down mode - I do not find any remark in technical reference that in count up mode the timer value is modified and I also did not find any special command in the driver source code which gives an indication of timer value modification.

    My real program is a driver for a UART communication where I use Timer1 to read bytes out of the Uart FIFO, sample certain bits etc. (it is a quite extensive state machine). The Timer2 is in my application the interrupt of Uart frame errors in communication which need to trigger time critical synchronization.

    Here is the code which I used to demonstrate and I attached the scope shots:

       GPTimerCC26XX_Params params1;

       GPTimerCC26XX_Params_init(&params1);

       params1.width          = GPT_CONFIG_16BIT;

       params1.mode           = GPT_MODE_ONESHOT_UP;

       params1.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;

       GPTimerCC26XX_Handle Timer1 = GPTimerCC26XX_open(CC2640R2_GPTIMER1A, &params1);

       GPTimerCC26XX_registerInterrupt(Timer1, SCB_TimerINT_SendSemaphoreAfterDelay, GPT_INT_TIMEOUT);

       GPTimerCC26XX_Params params2;

       GPTimerCC26XX_Params_init(&params2);

       params2.width          = GPT_CONFIG_16BIT;

       params2.mode           = GPT_MODE_ONESHOT_UP;

       params2.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;

       GPTimerCC26XX_Handle Timer2 = GPTimerCC26XX_open(CC2640R2_GPTIMER1B, &params2);

       GPTimerCC26XX_registerInterrupt(Timer2, SCB_TimerINT_SendSemaphoreAfterDelay, GPT_INT_TIMEOUT);

       Types_FreqHz  freq;

       BIOS_getCpuFreq(&freq);

       GPTimerCC26XX_Value LoadVal_per1msec = freq.lo / 1000;

       GPTimerCC26XX_Value DelayTime1 = 8 * LoadVal_per1msec - 1;

       GPTimerCC26XX_Value DelayTime2 = 5 * LoadVal_per1msec - 1;

       GPTimerCC26XX_setLoadValue(Timer1, DelayTime1);                // Timer1 setup to count up to 8ms

       GPTimerCC26XX_setLoadValue(Timer2, DelayTime2);                // Timer2 stops after 6ms and creates semaphore

       PIN_setOutputValue(&SYSPinState, Board_DIO1, 1);

       GPTimerCC26XX_start(Timer1);

       GPTimerCC26XX_start(Timer2);

       Semaphore_pend(Task_SCB_Semaphore, BIOS_WAIT_FOREVER);

       PIN_setOutputValue(&SYSPinState, Board_DIO1, 0);

       GPTimerCC26XX_stop(Timer1);

    //    GPTimerCC26XX_setLoadValue(Timer1, 0);                       // here I inserted the SetLoadValue = 0 which had no effect

       DelayTime1 = 2 * LoadVal_per1msec;

       GPTimerCC26XX_setLoadValue(Timer1, DelayTime1);                // Timer1 setup to count up to 8ms

       GPTimerCC26XX_start(Timer1);

       Semaphore_pend(Task_SCB_Semaphore, BIOS_WAIT_FOREVER);

       PIN_setOutputValue(&SYSPinState, Board_DIO1, 1);

       GPTimerCC26XX_setLoadValue(Timer1, DelayTime1);                // Timer1 setup to count up to 8ms

       GPTimerCC26XX_start(Timer1);

       Semaphore_pend(Task_SCB_Semaphore, BIOS_WAIT_FOREVER);

       PIN_setOutputValue(&SYSPinState, Board_DIO1, 0);

       while (1) {;}

    The first scpe shot shows the delay time of both pulses, the 2nd shot only shows the first pulse.

  • Hi Berthold, I am currently working on the oneshot up timer as well, same results. Have you been able to solve this issue?

  • Hi Dan,

    I have implemented now a workaround which works in my case: After stopping the timer I read the free running timer value and add this to the new delay time. Not very smart, but I tested a few cases and it seems to work in my case.

    The modification of the test code which I posted recently is as follows:

        GPTimerCC26XX_stop(Timer1);
        UInt32 CurrentCntVal = GPTimerCC26XX_getFreeRunValue(Timer1) & 0xFFFFFF;
        DelayTime1 = CurrentCntVal + 5 * LoadVal_per1msec;                 // delay time of 5ms
        GPTimerCC26XX_setLoadValue(Timer1, DelayTime1);               
        GPTimerCC26XX_start(Timer1);
        Semaphore_pend(Task_SCB_Semaphore, BIOS_WAIT_FOREVER);

    Best regards

    Berthold