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

Suddenly app_timer events trigger instantly

Ok, so I've been trying to get to the bottom of a problem for a few days now where suddenly the app_timer is acting like it's on crack and running super fast, i.e. triggering events instantly.

prescaler=0, no scheduler, sd initalized with SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, NULL);

For example, I am using the bsp library for button events and on a 'press' I start a timer for 3277 ticks (100ms) so that I can time how long the button is being pressed. As long as the button stays pressed, the timer will restart for another 3277 ticks. Once the button is 'released' I call a function for something to happen (depending on how long the button was pressed). When the problem occurs, the button handler fires instantly, and keeps on restarting the 3277-tick timer over and over again.

Other timers will do the same thing. I have one that checks battery level (adc) every 10 seconds that also gets called over and over again.

Also, a bsp led for advertising that is supposed to blink once every 5 seconds, ends up basically solid.

Eventually, everything sorts itself out. But that can take anywhere from 30 seconds to a few minutes. Either way, something is going wrong I have not been able to figure out what.

So far this has only happened when the device isn't doing anything (advertisements have timed out and the soft device is idle). At that point the only thing running is an 8-minute singleshot timer where I increment a counter and restart the timer every 8 minutes. During this time, when I press a button is when the problem occurs, but not every time... I've traced the code with printf's and everything looks good (app_timer_start gets called with the correct values, etc.)

Is something going to sleep during the idle time that could mess up app_timers? Does the clock that app_timer uses go to sleep and require some wake-up time? I don't explicitly stop the soft device, clock, or anything. The device is in power_manage(), except when it wakes up the every 8 minutes.

Some sort of race condition where what's put into the app_timer queue immediately gets executed?

  • Read all the comments at the end of devzone.nordicsemi.com/.../ that question which talks about a race condition which causes events to trigger instantly and discusses two potential fixes.

  • I should have mentioned that I already implemented the "nrf_delay_us(100);" 'fix' from that thread, but I thought it was something else since it sounded like one misfire, whereas mine is misfiring continuously. I would like to try your solution, but I don't completely understand how to implement it. Do you mean to put "pre_counter_val = (pre_counter_val-1) & 0xffffff;" instead of "nrf_delay_us(100);"?

  • Ah - yes does help to know what you've tried, if that didn't work for you then it looks like a different bug. I meant that in this case you should, instead of the delay, set the counter to that value ( pre_counter_val - 1 ) & 0xffffff, I guess it would be something like

    rtc1_compare0_set( ( pre_counter_val - 1 ) & 0xffffff );
    

    it goes in the same if() block where timer_timeouts_check_sched() is called, before or after, shouln't matter.

    The idea behind the nrf_delay( 100 ) fix is to ensure that the counter event has definitely fired before you return, which means it won't fire during the RTC1 interrupt handler. The idea behind the other fix is to set the counter to a value way in the future, so if it hasn't fired already, it won't fire until long after the interrupt handler has finished. Having the RTC1 compare occur during the RTC1 interrupt is the race condition.

  • I think I 'fixed' this by creating a dummy timer as in this post here: devzone.nordicsemi.com/.../

    So far no more glitches (crosses fingers...).

    In that post, Håkon Alseth, alludes that this should not be needed post SDK6.1, but I am on 8.0.0.

Related