Device: nRF52840
SDK: 16.0.
Softdevice: 6.1.1
Hello,
I'm using Timer 2 peripheral using simple timer driver. It's working fine but I have serious drift/accuracy issue. The timer drifts about 5s in 30mins. I don't understand why so much drift is happening here.
Simple timer sdk_config.h settings:
// <e> SIMPLE_TIMER_ENABLED - app_simple_timer - Simple application timer functionality
//==========================================================
#ifndef SIMPLE_TIMER_ENABLED
#define SIMPLE_TIMER_ENABLED 1
#endif
// <o> SIMPLE_TIMER_CONFIG_FREQUENCY - Timer frequency if in Timer mode
// <0=> 16 MHz
// <1=> 8 MHz
// <2=> 4 MHz
// <3=> 2 MHz
// <4=> 1 MHz
// <5=> 500 kHz
// <6=> 250 kHz
// <7=> 125 kHz
// <8=> 62.5 kHz
// <9=> 31.25 kHz
#ifndef SIMPLE_TIMER_CONFIG_FREQUENCY
//#define SIMPLE_TIMER_CONFIG_FREQUENCY 4
#define SIMPLE_TIMER_CONFIG_FREQUENCY 9
#endif
// <o> SIMPLE_TIMER_CONFIG_INSTANCE - TIMER instance used
// <0=> 0
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
#ifndef SIMPLE_TIMER_CONFIG_INSTANCE
//#define SIMPLE_TIMER_CONFIG_INSTANCE 1
#define SIMPLE_TIMER_CONFIG_INSTANCE 2
#endif
// </e>
The timer code:
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "app_error.h"
#include "nrf_log.h"
#include "app_timer.h"
#include "nrf_delay.h"
#include "app_simple_timer.h"
#include "scr_execute.h"
//#define TIMEOUT_VALUE 50000 //50ms, if f=1Mhz
//#define TIMEOUT_VALUE 31650 // 3s in 10mins
//#define TIMEOUT_VALUE 31750 // 1s in 10mins
// used with timer 2, SIMPLE_TIMER_CONFIG_FREQUENCY=9
//#define TIMEOUT_VALUE_1S 31800 // 1s tick. 7ms in 30min
#define TIMEOUT_VALUE_1S 31250 // 1s tick
//#define TIMEOUT_VALUE_100MS 3180 // 100ms tick
// Used with timer 2, SIMPLE_TIMER_CONFIG_FREQUENCY=4 => 1MHz clock
//#define TIMEOUT_VALUE 50000 // 50ms
//#define T_OUT 20 // 20*50 = 1000ms = 1s
void timeout_handler(void * p_context);
uint32_t scr_timer_tick=0;
uint32_t scr_timer_tick_100ms=0;
uint32_t timer_tick=0;
void timeout_handler(void * p_context)
{
//NRF_LOG_INFO("Timer_tick_st: %lu", scr_timer_tick++);
#ifdef TIMEOUT_VALUE_100MS
scr_timer_tick_100ms++;
if (scr_timer_tick_100ms>=10){
scr_timer_tick_100ms=0;
scr_timer_tick++;
}
#endif
#ifdef TIMEOUT_VALUE
timer_tick++;
if (timer_tick >= T_OUT){
NRF_TIMER2->TASKS_CAPTURE[0] = 1;
uint32_t counter = NRF_TIMER2->CC[0];
scr_timer_tick++;
NRF_LOG_INFO("Timer tick=%lu, Counter capture val=%lu", scr_timer_tick, counter);
timer_tick=0;
}
#endif
#ifdef TIMEOUT_VALUE_1S
scr_timer_tick++;
NRF_LOG_INFO("Timer tick=%lu", scr_timer_tick);
#endif
// Check if 24Hrs (=86400s) have passed, if yes, reset the clock
if (scr_timer_tick >= 86400){
scr_timer_tick = 0;
}
//scr_execute_chunk();
}
void scr_timer_init(void){
uint32_t err_code = app_simple_timer_init();
APP_ERROR_CHECK(err_code);
}
void scr_timer_start(void){
#ifdef TIMEOUT_VALUE_100MS
uint32_t err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_REPEATED, timeout_handler, TIMEOUT_VALUE_100MS, NULL);
#endif
#ifdef TIMEOUT_VALUE_1S
uint32_t err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_REPEATED, timeout_handler, TIMEOUT_VALUE_1S, NULL);
#endif
#ifdef TIMEOUT_VALUE
uint32_t err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_REPEATED, timeout_handler, TIMEOUT_VALUE, NULL);
#endif
APP_ERROR_CHECK(err_code);
}
void scr_timer_reset(void){
scr_timer_tick = 0;
}
void scr_timer_stop(void){
uint32_t err_code = app_simple_timer_stop();
APP_ERROR_CHECK(err_code);
}