Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

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/CC2640R2F: How to improve accuracy for GPTimer of CC2640R2F?

Part Number: CC2640R2F

Tool/software: Code Composer Studio

Hi Sir,

Base on customer request I need generate 18.52ms ISR by GPTimer when some function work of system.

I reference GPTimer tutorial (http://dev.ti.com/tirex/content/simplelink_cc26x2_sdk_2_20_00_36/docs/tidrivers/doxygen/html/_g_p_timer_c_c26_x_x_8h.html#a30f6c028f0abea0b35c3be3d1609ea9b)  to implement test code to test GPTimer.

elow is myself test result:

GPTimer seting : GPT_CONFIG_16BIT + GPT_MODE_PERIODIC_UP + GPTimerCC26XX_DEBUG_STALL_ON

CPU Frequence : 48MHz

Load Value :

923075 => ISR  = 19.20ms

905659 => ISR  = 18.84ms

888887 => ISR  = 18.44ms(Closest 18.52ms)

872726 => ISR  = 18.08ms

Test as below:

/*
 *  ======== GPTimer_Test ========
 */
/* For usleep() */
#include <unistd.h>
#include <stddef.h>

/* Driver Header files */
//#include <ti/drivers/PWM.h>

/* Example/Board Header files */
#include "Board.h"

#include "ti/drivers/timer/GPTimerCC26XX.h"
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Types.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>

#if 0
    /* Period and duty in microseconds */
    uint16_t   pwmPeriod = 3000;
    uint16_t   duty = 0;
    uint16_t   dutyInc = 750;

    /* Sleep time in microseconds */
    //uint32_t   time = 50000;  //50ms
    //uint32_t   time = 1000000;  //1S
    PWM_Handle pwm1 = NULL;
    PWM_Handle pwm2 = NULL;
    PWM_Params params;
#endif

    GPTimerCC26XX_Handle hTimer_One_Fourth_Line_Time; // 1/4 line time
    uint32_t One_Fourth_Line_Time_Timer_Interrupt_Count = 0;
    uint8_t One_Fourth_Line_Time_LED_OUTPUT_ON = 0;

    GPTimerCC26XX_Handle hTimer_Full_Line_Time; // full line time
    uint32_t Full_Line_Time_Timer_Interrupt_Count = 0;
    uint8_t Full_Line_Time_LED_OUTPUT_ON = 0;

    uint8_t PK_Timer_Disable = 0;
    uint8_t Timer_Enable = 0;

    void One_Fourth_Line_Time_timerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
        // interrupt callback code goes here. Minimize processing in interrupt.
            One_Fourth_Line_Time_Timer_Interrupt_Count++;

#if 0
        PWM_setDuty(pwm1, duty);

        if (pwm2) {
            PWM_setDuty(pwm2, duty);
        }

        duty = (duty + dutyInc);

        if (duty == pwmPeriod || (!duty)) {
            dutyInc = - dutyInc;
        }
#endif
        if(!One_Fourth_Line_Time_LED_OUTPUT_ON)
        {
            /* Turn on user LED */
            GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
            /* Turn on user LED */
            //GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
            One_Fourth_Line_Time_LED_OUTPUT_ON = 1;
        }
        else
        {
            /* Turn on user LED */
            GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
            /* Turn on user LED */
            //GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
            One_Fourth_Line_Time_LED_OUTPUT_ON = 0;
        }
    }

    void Full_Line_Time_timerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
        // interrupt callback code goes here. Minimize processing in interrupt.
        Full_Line_Time_Timer_Interrupt_Count++;
        if(!Full_Line_Time_LED_OUTPUT_ON)
        {
            /* Turn on user LED */
            //GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
            /* Turn on user LED */
            GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
            Full_Line_Time_LED_OUTPUT_ON = 1;
        }
        else
        {
            /* Turn on user LED */
            //GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
            /* Turn on user LED */
            GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
            Full_Line_Time_LED_OUTPUT_ON = 0;
        }
    }

/*
 *  ======== mainThread ========
 *  Task periodically increments the PWM duty for the on board LED.
 */
void *mainThread(void *arg0)
{
    GPTimerCC26XX_Params params;
    GPTimerCC26XX_Params_init(&params);
    params.width          = GPT_CONFIG_16BIT;
    params.mode           = GPT_MODE_PERIODIC_UP;
    params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_ON;

// 1/4 line time
    hTimer_One_Fourth_Line_Time = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0A, &params);
// full line time
    hTimer_Full_Line_Time = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER1A, &params);
    //hTimer_Full_Line_Time = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0B, &params_XD);
    if(hTimer_One_Fourth_Line_Time == NULL ||  hTimer_Full_Line_Time == NULL) {
      //Log_error0("Failed to open GPTimer");
      //Task_exit();
        while (1);
    }
    Types_FreqHz  freq;
    BIOS_getCpuFreq(&freq);
// 1/4 line time
    GPTimerCC26XX_Value loadVal = freq.lo / 215 - 1; //216 = 4.63ms, 30 = 33ms, 100 = 10ms
    GPTimerCC26XX_setLoadValue(hTimer_One_Fourth_Line_Time, loadVal);
    GPTimerCC26XX_registerInterrupt(hTimer_One_Fourth_Line_Time, One_Fourth_Line_Time_timerCallback, GPT_INT_TIMEOUT);

// full line time
    // GPTimerCC26XX_Value need dedicated variable ... PK 20181211+
    GPTimerCC26XX_Value loadVal_XD = freq.lo / 54 - 1; // 54(Load Value = 888887) = 18.44ms
    GPTimerCC26XX_setLoadValue(hTimer_Full_Line_Time, loadVal_XD);
    GPTimerCC26XX_registerInterrupt(hTimer_Full_Line_Time, Full_Line_Time_timerCallback, GPT_INT_TIMEOUT);

    GPTimerCC26XX_start(hTimer_One_Fourth_Line_Time);
    GPTimerCC26XX_start(hTimer_Full_Line_Time);

    /* Loop forever incrementing the PWM duty */
    while (1) {
        if(PK_Timer_Disable && Timer_Enable)
        {
            GPTimerCC26XX_stop(hTimer_One_Fourth_Line_Time);
            GPTimerCC26XX_stop(hTimer_Full_Line_Time);
            Timer_Enable = 0;
        }
        else if(!PK_Timer_Disable && !Timer_Enable)
        {
            GPTimerCC26XX_start(hTimer_One_Fourth_Line_Time);
            GPTimerCC26XX_start(hTimer_Full_Line_Time);
            Timer_Enable = 1;
        }

        Task_sleep(BIOS_WAIT_FOREVER);

    }
}

Is workable if we need improve GPTimer accuracy to 0.01ms? (ISR = 18.51ms~18.53ms)

Could you please check for me?

Many thanks.