This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

RTC1 counter return to 0

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

Related