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

NRF app_timer stops (rtc1 couter also stop) after 3 days working of NRF52840

Hello,

SDK : 16.0.0
Controller : NRF52840

I have 2 app_timer instance, one is used for longer sleep like 24 hours, and other is used to blink led when device is performing ble operation.

Device works perfectly 3 days approx led blinking stop and device behavior is unknown ,In log it is found that, rtc1 counter (value from app_timer_cnt_get()) is not incrementing.

APP_TIMER_DEF(Sip_timer);                 // Creates timer id for our program.
APP_TIMER_DEF(_1Sec_timer);				//Create 1 sec timer id

void sec1_handler(void * p_context){
  sec++;
  static bool pinState=false;
  //nrf_gpio_pin_toggle(STATUS_LED);
  if(pinState){
    pinState=false;
    nrf_gpio_pin_clear(STATUS_LED);
    app_timer_stop(_1Sec_timer);
    ret_code_t err_code;
    err_code = app_timer_start(_1Sec_timer, APP_TIMER_TICKS(3000L), NULL); //3000 ms= 3 sec
    APP_ERROR_CHECK(err_code);
  }
  else{
    pinState=true;
    nrf_gpio_pin_set(STATUS_LED);
    app_timer_stop(_1Sec_timer);
    ret_code_t err_code;
    err_code = app_timer_start(_1Sec_timer, APP_TIMER_TICKS(50L), NULL); 
    APP_ERROR_CHECK(err_code);
  }
}

void timer_timeout_handler(void * p_context)   //given time Sec timer handler
{
        inSleep=0;
        app_timer_stop(Sip_timer);
}

static void timers_init(void)
{

    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_create(&Sip_timer, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_create(&_1Sec_timer, APP_TIMER_MODE_REPEATED, sec1_handler);
    APP_ERROR_CHECK(err_code);
}

static void application_timers_start(void) // sleep timer after timeout device will wakeup
{
	ret_code_t err_code;
    NRF_LOG_INFO("sleep for %d",sleepInterval);
    err_code = app_timer_start(Sip_timer, APP_TIMER_TICKS(sleepInterval * 1000L), NULL); //1000 ms= 1 sec
    APP_ERROR_CHECK(err_code);
	
}

static void led_timers_start(void)
{
	ret_code_t err_code;
        sec=0;
        err_code = app_timer_start(_1Sec_timer, APP_TIMER_TICKS(1000L), NULL); //1000 ms= 1 sec
        APP_ERROR_CHECK(err_code);
	
}


I have attached timer functions snippet .

Please help me regarding this.

Thank You

Bivay





Parents
  • Can you please give more details about your timer configuration? SDK version used, code snippets of institutionalization and callbacks etc to better understand the problem.

  • Few observations.

    1. sip_timer is stopped in the timer timeout callback, which seems to me like you need this to run only once. I would recommend you to create this timer with APP_TIMER_MODE_SINGLE_SHOT instead of APP_TIMER_MODE_REPEATED
    2. It looks like you want to restart your _1Sec_timer inside the _1Sec_timer timeout handler. The way you are doing it is to stop the app_timer and immediately start it. You need to understand that the app_timer is not stopped immediately but they are scheduled to stop by pending SWI_IRQn.

    If you look into the app_timer.c , the priority of RTC1 and SWI0 IRQ are set the same, which means that scheduling (pending SWI0) will be postponed until your timeout handler is finished since your timeout handler is called from RTC1 interrupt handler and hence the same priority as SWI interrupt.

    In short, call the app_timer_Stop and app_timer_start immediately with different timeouts from the same priority as SWI IRQ priority will not work as intended.

    I have not tried this before, but try to edit the value in app_timer.c

    #define RTC1_IRQ_PRI            APP_TIMER_CONFIG_IRQ_PRIORITY               /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */
    #define SWI_IRQ_PRI             (APP_TIMER_CONFIG_IRQ_PRIORITY  - 1)             /**< Priority of the SWI  interrupt (used for updating the timer list). */
    
    This will force the handling of any requests into synchronous and hopefully, a call to app_timer_stop is processed completely before you call the app_timer_start in the same context.

    If this does not work, then you need to use the app_scheduler to call the app_timer_stop and app_timer_start from thread context to make this timer restart feature work correctly

Reply
  • Few observations.

    1. sip_timer is stopped in the timer timeout callback, which seems to me like you need this to run only once. I would recommend you to create this timer with APP_TIMER_MODE_SINGLE_SHOT instead of APP_TIMER_MODE_REPEATED
    2. It looks like you want to restart your _1Sec_timer inside the _1Sec_timer timeout handler. The way you are doing it is to stop the app_timer and immediately start it. You need to understand that the app_timer is not stopped immediately but they are scheduled to stop by pending SWI_IRQn.

    If you look into the app_timer.c , the priority of RTC1 and SWI0 IRQ are set the same, which means that scheduling (pending SWI0) will be postponed until your timeout handler is finished since your timeout handler is called from RTC1 interrupt handler and hence the same priority as SWI interrupt.

    In short, call the app_timer_Stop and app_timer_start immediately with different timeouts from the same priority as SWI IRQ priority will not work as intended.

    I have not tried this before, but try to edit the value in app_timer.c

    #define RTC1_IRQ_PRI            APP_TIMER_CONFIG_IRQ_PRIORITY               /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */
    #define SWI_IRQ_PRI             (APP_TIMER_CONFIG_IRQ_PRIORITY  - 1)             /**< Priority of the SWI  interrupt (used for updating the timer list). */
    
    This will force the handling of any requests into synchronous and hopefully, a call to app_timer_stop is processed completely before you call the app_timer_start in the same context.

    If this does not work, then you need to use the app_scheduler to call the app_timer_stop and app_timer_start from thread context to make this timer restart feature work correctly

Children
No Data
Related