Hi all,
i use softdevice and app timer. I know that the softdevice use a RTC0 and app timer RTC1.
I would use a rtc to have a timestamp. but i see that after 512 second the counter come back to 0. Someon can clarify why?
Thanks, Anna
Hi all,
i use softdevice and app timer. I know that the softdevice use a RTC0 and app timer RTC1.
I would use a rtc to have a timestamp. but i see that after 512 second the counter come back to 0. Someon can clarify why?
Thanks, Anna
Hi,
The RTC is a low-frequency timer (real time counter), not a Real Time Clock, as the acronym is used for in some other settings.
The RTC counts using a 24 bit register. With the timer running at 32768 Hz, the register will overflow after 512 seconds.
You can set the PRESCALER register, to make the RTC count at a slower rate, allowing it to run up to 582.542 hours before overflowing.
See this thread for more information.
Best regards,
Jørgen
I implemented a workaround for this by using a Repeated App-Timer, with the timeout handler going off the moment before it overflows.
To create timer:
err_code = app_timer_create(&m_millis_id,
APP_TIMER_MODE_REPEATED,
timer_a_handler);
To start timer:
err_code = app_timer_start(m_millis_id, APP_TIMER_TICKS(511999, APP_TIMER_PRESCALER), NULL);
APP_ERROR_CHECK(err_code);
Timeout handler:
static void timer_a_handler(void *p_context) {
overflow++;
}
You can then retrieve the timestamp from the code below
void timestampGet(timestamp_t *ts) {
uint32_t ticks, s, t;
ticks = app_timer_cnt_get();
s = ticks / TIMER_TICKS_PER_SECOND; // becomes >>
t = ticks % TIMER_TICKS_PER_SECOND; // becomes &
ts->seconds = overflow * ((1 << RTC_TICKS_BITS) / TIMER_TICKS_PER_SECOND) + s;
ts->milli_seconds = t * (APP_TIMER_PRESCALER + 1) * (1000.0 / APP_TIMER_CLOCK_FREQ);
}
The code above is adapted from Clem Taylor's answer here (devzone.nordicsemi.com/.../). I had implemented his approach, but found the PPI based counting mechanism increased the current draw from 50ua to 500ua.
My code above feels like a bit of a hack, so any criticism/suggestions are welcome.
Hi cirlam, Thanks for the answer. if i understood correctly, the idea is count the number of times that the rtc go in overflow, and use it to calculate the second and millisecond. it's good idea, but i have a doubt. If a create a timer with a delay of one second, and in the his handler i incremented a variable second, can i use it to trace the time? Somethink like this:
void DRV_RTC_Init(void)
{
uint32_t err_code = 0; // Create Rtc timer err_code=TIMER_Create(TIMER_RTC,APP_TIMER_MODE_REPEATED,DRV_RTC_handler_rtc1); APP_ERROR_CHECK(err_code);
DRV_RTC_Start();
}
uint32_t DRV_RTC_ReturnValue()
{
return lOneSecond;
}
void DRV_RTC_Start(void)
{
uint32_t err_code ;
// Start rtc timers.
err_code = TIMER_Start (TIMER_RTC,TIMER_RTC_CALLBACK_DELAY,NULL);
APP_ERROR_CHECK(err_code);
}
void DRV_RTC_handler_rtc1(void * p_context)
{
UNUSED_PARAMETER(p_context);
lOneSecond++;
}
Do you think that can be a problem?
Thanks, Anna
I believe if you are using a softdevice, then you may find that the ble stack delays your timer interrupt handler a little, meaning your 'lOneSecond' variable won't be accurate. The link to the thread i posted in the answer above gives some useful information about this.
thank you cirlam!
It's very useful, but what's the value of RTC_TICKS_BITS? Thanks