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

Missing APP_TIMER interrupts?

I am using nRF5 SDK 16 on a Rigado BMD-300 (nRF52832) series evaluation kit.  The application receives button presses and releases from a peripheral (characteristic change notifications).  I'm using an app timer to process button timing (e.g. single clicks, double clicks, long holds, etc).  Button activity is then sent to a host through the UART (using a FIFO).  Without the timer interrupt, there is no button activity and no UART activity.

The timer calls a routine in my button module:

static void buttons_timer_callback(void* p_context)
{
  if (buttons_data.timer_callback) buttons_data.timer_callback();
}

which calls a callback set when the button processing module is initialized.  It's never set again.

The callback just sets the flag:

void button_timer_callback(void)
{
  main_event_flags.do_buttons = true;
}

So short of the redirection of the callback, I'm doing just about the absolute minimum in the timer interrupt.

The problem is that the app timer seems to stop after a few seconds of activity and it's not consistent when it stops.  Sometimes it stops for up to 100 ms and when it resumes, it misses more than it makes.

In the app timer callback, I'm setting a global flag and processing the buttons in the main idle loop so it spends very little time in the interrupt.  The timer is set for 5 ms.  Here is my sdk_config.h setup;

/ <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
//==========================================================
#ifndef APP_TIMER_ENABLED
#define APP_TIMER_ENABLED 1
#endif
// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.
 
// <0=> 32768 Hz 
// <1=> 16384 Hz 
// <3=> 8192 Hz 
// <7=> 4096 Hz 
// <15=> 2048 Hz 
// <31=> 1024 Hz 

#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY
#define APP_TIMER_CONFIG_RTC_FREQUENCY 1
#endif
[

In app_timer_start(), timeout_ticks is 82.  I calculate that to be 5ms.

  NRF_LOG_DEBUG("Starting button timer, ticks = %d", ticks);
  (void)app_timer_start(zrf_buttons_timer_id, ticks, NULL);

Here is the log message:

<debug> app: Starting button timer, ticks = 82

My question is, is there anything about processing app timer events/interrupts that you have to be careful of?  I saw a 6 year old post about using the app scheduler, to process app timer events, but don't see how that can be done -- does that still apply?  Could this be an interrupt priority issue?  If so, that would imply I'm doing a bunch of stuff in interrupts and I just don't see that.  Any suggestions on what to check?

  • the ble_evt_handler() would probably stop your timer interrupts, yes, depending on the timer priority. But the timer interrupt handler will be called after ble_evt_handler() is done. In fact, there are a few events in the softdevice that will block your application from time to time. But if there is an interrupt waiting it will always be handled after the softdevice interrupts. This is just the way interrupt handlers work. So unless you spend too long time (>5ms) in an interrupt handler, you will not loose any interrupts. If you spend e.g. 15ms in an interrupt handler, so that your timer has up to 3 timer interrupts, then you may not see 2 of them, because it will only see that a timer interrupt has occured, but not that it has occured 3 times.

    As mentioned, the softdevice has a lot of interrupts, on different priorities, but none that takes up to 5ms. So unless you do so in the ble_evt_handler() or any of your other application interrupt handlers, it shouldn't break your timer.

    Do you do anything that takes up very long time in your ble_evt_handler()? 

    What is your timer interrupt priority? 

    You can read about the softdevice priorities here.

    BR,

    Edvin

  • No I'm not doing anything in the BLE event handler that would take that long.  For the most part, the only thing that I'm seeing when this is happening is the BLE_GATTC_EVT_HVX event which I posted above.  I don't see how that can take 15 ms.

    The interrupt priorty should be what I sent you in the sdk_config.h.  I haven't changed it other than when you requested I do so and then I put it back because it didn't make any difference.

    I have read the documentation you linked.

  • jbmillard said:
    I have read the documentation you linked.

     Good stuff. 

    Until I know how your application works, I don't know how to approach this issue then. If you can't share the project due to company policies, then I suggest that you try to replicate the issue in one of the SDK examples. It doesn't sound like much changes from the ble_app_blinky and ble_app_blinky_c examples. Perhaps these can be used as a starting point.

Related