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(¶ms); 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, ¶ms); // full line time hTimer_Full_Line_Time = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER1A, ¶ms); //hTimer_Full_Line_Time = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0B, ¶ms_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.