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

nrf52840 RTC vs app_timer plus timestamping

hello Nordic

i am working with nrf52840, sdk16, over the peripheral app_ble_blinky example

my system will go to sleep mode for 10 minutes each time, i wonder if there is any advantage to use RTC directly instead of app_timer in meters of power consumption, is there less cpu interventions or over head when using RTC directly ?

also if i have some gpio interrupt during the 10 min sleep then i want to be able to read the current clock at resolution of 100ms. 

first thought was to use an app_timer that counts in 100ms intervals but that seems wasteful, i think i should seek for a way to have one timer interrupt every 10 minutes but ne able to get the current time stamp from the clock maybe.

1. is there a way to read a clock value while in sleep mode, that has some meaning, does it start from '0' every time we put the power on so we can try to calculate the delta each time ? 

2. is there a way to have an app_timer running on REPEATED mode that wakes up every 10 minutes ? does it really save something or it ticks every 32khz anyway? and is it better to do it directly with RTC ?

not so relevant but what's the difference between WFI and WFE beside the Event/Interrupt, does it refer to the type of sleep mode - system ON sleep(for WFE) vs system OFF sleep (for WFI)?

hope to read from you soon

best regards

Ziv

  • Hi,

    ziv123 said:

    when running the rtc example (SDK 16) for nrf542840, when changing the 

    config.prescaler = 32767; //15; //8191; // 32767; //4095;
     config.prescaler = 32767; //15; //8191; // 32767; //4095;

    from 4095 to 32767, i was expecting that blinking will slow down to 1 sec blink but it seems the blinking stays the same.. how come ? 

     The PRESCALER register is only 12 bits, which means that 4095 is the highest value you can set.

    ziv123 said:
    another strange thing for me is that the compare event happens only once at start, is it not supposed to happen every 3 sec and not only after the first 3 sec, is there no zeroing of the counter after each compare event ? 

    The interrupt handler in the RTC driver disables the event and the interrupt for the COMPAREx event when the event is detected. You either need to comment out these two lines in the driver, or call nrf_drv_rtc_cc_set()? again in the event handler.

    ziv123 said:
    one more thing which is critical for me is that i get the event handler to be called on each tick event, i don't want this in my program, i want the event to be called only when compare event has accurse, can you explain what changes i need to make to get that ? 

    Comment out the enabling of tick event and interrupt in timers_init():

        //Enable tick event & interrupt
        //nrf_drv_rtc_tick_enable(&rtc_10_min,true);
     

    Best regards,
    Jørgen

  • The interrupt handler in the RTC driver disables the event and the interrupt for the COMPAREx event when the event is detected. You either need to comment out these two lines in the driver, or call nrf_drv_rtc_cc_set()? again in the event handler.

    well i did not want to change the nrfx_rtc.c but calling the nrf_rtc_cc_set does not seem to generate another compare event, so maybe i m using it in the wrong place ?

    static void rtc_10_min_handler(nrf_drv_rtc_int_type_t int_type)
    {
        if (int_type == NRF_DRV_RTC_INT_COMPARE0)
        {
            main_state = MAIN_STATE_EVERY_10_MIN_SAMPELING;
            physic_sample_done_flag = false;
            accelo_sample_done_flag = false;   
            
            nrf_drv_rtc_cc_set(&rtc_10_min,0,COMPARE_COUNTER_10_MIN, true);
            
    //nrf_gpio_pin_toggle(COMPARE_EVENT_OUTPUT);
        }
    
        count++;
    //    else if (int_type == NRF_DRV_RTC_INT_TICK)
    //    {
    //    calculaTE delta    
    //nrf_gpio_pin_toggle(TICK_EVENT_OUTPUT);
    //    }
    }
    

    [this was edited to the response later] actually what i did that made it work is to clear the counter, i guessed that if the counter keeps on running after compare event then the value for compare event which is fixed will never meat the counter again , if there is something wrong with that logic please elaborate

    The PRESCALER register is only 12 bits, which means that 4095 is the highest value you can set.

    is there a way to change the RTC2 frequency (below code in the sdk_config.h) without changing it also for the RTC0 and RTC1 ?

    // <e> RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver - legacy layer
    //==========================================================
    #ifndef RTC_ENABLED
    #define RTC_ENABLED 1
    #endif
    // <o> RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
    
    
    #ifndef RTC_DEFAULT_CONFIG_FREQUENCY
    #define RTC_DEFAULT_CONFIG_FREQUENCY 32768
    #endif
    

    best regards

    Ziv

  • ziv123 said:
    [this was edited to the response later] actually what i did that made it work is to clear the counter, i guessed that if the counter keeps on running after compare event then the value for compare event which is fixed will never meat the counter again , if there is something wrong with that logic please elaborate

    Yes, that is correct. You need to clear the RTC if you want to restart it from 0. You would still hit the COMPARE event again if you let the RTC run, but this would first happen after it overflows and hit the CC point again.

    ziv123 said:
    is there a way to change the RTC2 frequency (below code in the sdk_config.h) without changing it also for the RTC0 and RTC1 ?

    RTC_DEFAULT_CONFIG_FREQUENCY is only used to set the prescaler in the default config. Since you set the prescaler in your code, there is no need to care about this config. Also, note that this config only affects RTC instances controlled by the RTC driver. Neither the softdevice, nor the app_timer library uses the RTC driver for interacting with the RTC peripheral.

  • RTC_DEFAULT_CONFIG_FREQUENCY is only used to set the prescaler in the default config. Since you set the prescaler in your code, there is no need to care about this config. Also, note that this config only affects RTC instances controlled by the RTC driver. Neither the softdevice, nor the app_timer library uses the RTC driver for interacting with the RTC peripheral.

    in the sdk_config comments it is written - Frequency  <16-32768> , so is it possible to set the frequency here for something like 8191 (more then 12 bits) ? and then to set prescaler to zero ?

  • No, like you see in my link, RTC_DEFAULT_CONFIG_FREQUENCY is passed to RTC_FREQ_TO_PRESCALER, which will calculate the prescaler for the given frequency. If you set the frequency to 8191 in your sdk_config.h file, the calculated prescaler will be (32768/8191)-1=3. 

    And again, since you set the prescaler in the code, this will be overwritten and have no effect:

    nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
    config.prescaler = 32767; //8191; // 32767; // 4095; // with 32768 it should tick every one second

Related