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

does app_timer_stop() clear timer interrupts from the interrupt queue

Hello, 

I am using nRF5 SDK16. 

Let's say app_timer generates an interrupt right before a call to app_timer_stop(). Example:

// app_timer_stop() is called inside a GPIOTE ISR.

void gpiote_ISR(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {

  do something(); // at this stage, app_timer generates an interrupt with same or less priority compared to current GPIOTE interrupt, so there is no context switch.

  app_timer_stop(timer_);

}

Will the generated timer interrupt be called after GPIOTE ISR is finished? Or will it be removed from the interrupt queue? In other words, does app_timer_stop() remove all timer interrupts waiting in the queue. 

I would appreciate your help.

Parents
  • I was able to find the answer by writing a test program. app_timer_stop() removes the generated timer interrupts waiting in the queue. Here is a test program: 

    #include "stdbool.h"
    #include "stdint.h"
    #include "nrf.h"
    #include "nordic_common.h"
    #include "boards.h"
    #include "app_error.h"      
    #include "nrf_drv_gpiote.h" 
    #include "nrf_drv_clock.h"  
    #include "app_timer.h"      
    #include "nrf_delay.h"
    
    APP_TIMER_DEF(timer_); 
    
    #define BUTTON_PIN 13
    
    void timeout_handler(void *p_context) {
      printf("timer\r\n");
    }
    
    void button_press_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
      printf("button started\r\n");
      // start timer so that it generates an event after 1500 ms
      uint32_t err_code = app_timer_start(timer_, APP_TIMER_TICKS(1500), NULL);
      APP_ERROR_CHECK(err_code);
      // wait 3 seconds - during this period timer interrupt should be fired and placed in the queue
      nrf_delay_ms(3000);
      // stop timer - when stopped, timer ISR will not be called afterwards. If not stopped, it will be called
      err_code = app_timer_stop(timer_);
      APP_ERROR_CHECK(err_code);
      printf("button finished\r\n");
    }
    
    int main(void) {
      uint32_t err_code;
      // init GPIOTE 
      err_code = nrf_drv_gpiote_init();
      APP_ERROR_CHECK(err_code);
      // init lfck
      err_code = nrf_drv_clock_init();
      APP_ERROR_CHECK(err_code);
      nrf_drv_clock_lfclk_request(NULL);
      // init app_timer
      err_code = app_timer_init();
      APP_ERROR_CHECK(err_code);
      err_code = app_timer_create(&timer_, APP_TIMER_MODE_SINGLE_SHOT, timeout_handler);
      APP_ERROR_CHECK(err_code);
      // init button interrupt
      nrf_drv_gpiote_in_config_t button_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
      button_config.pull = NRF_GPIO_PIN_PULLUP;
      err_code = nrf_drv_gpiote_in_init(BUTTON_PIN, &button_config, button_press_handler);
      APP_ERROR_CHECK(err_code);
      nrf_drv_gpiote_in_event_enable(BUTTON_PIN, true);
    
      while (true) {
    
      }
    }
    

Reply
  • I was able to find the answer by writing a test program. app_timer_stop() removes the generated timer interrupts waiting in the queue. Here is a test program: 

    #include "stdbool.h"
    #include "stdint.h"
    #include "nrf.h"
    #include "nordic_common.h"
    #include "boards.h"
    #include "app_error.h"      
    #include "nrf_drv_gpiote.h" 
    #include "nrf_drv_clock.h"  
    #include "app_timer.h"      
    #include "nrf_delay.h"
    
    APP_TIMER_DEF(timer_); 
    
    #define BUTTON_PIN 13
    
    void timeout_handler(void *p_context) {
      printf("timer\r\n");
    }
    
    void button_press_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
      printf("button started\r\n");
      // start timer so that it generates an event after 1500 ms
      uint32_t err_code = app_timer_start(timer_, APP_TIMER_TICKS(1500), NULL);
      APP_ERROR_CHECK(err_code);
      // wait 3 seconds - during this period timer interrupt should be fired and placed in the queue
      nrf_delay_ms(3000);
      // stop timer - when stopped, timer ISR will not be called afterwards. If not stopped, it will be called
      err_code = app_timer_stop(timer_);
      APP_ERROR_CHECK(err_code);
      printf("button finished\r\n");
    }
    
    int main(void) {
      uint32_t err_code;
      // init GPIOTE 
      err_code = nrf_drv_gpiote_init();
      APP_ERROR_CHECK(err_code);
      // init lfck
      err_code = nrf_drv_clock_init();
      APP_ERROR_CHECK(err_code);
      nrf_drv_clock_lfclk_request(NULL);
      // init app_timer
      err_code = app_timer_init();
      APP_ERROR_CHECK(err_code);
      err_code = app_timer_create(&timer_, APP_TIMER_MODE_SINGLE_SHOT, timeout_handler);
      APP_ERROR_CHECK(err_code);
      // init button interrupt
      nrf_drv_gpiote_in_config_t button_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
      button_config.pull = NRF_GPIO_PIN_PULLUP;
      err_code = nrf_drv_gpiote_in_init(BUTTON_PIN, &button_config, button_press_handler);
      APP_ERROR_CHECK(err_code);
      nrf_drv_gpiote_in_event_enable(BUTTON_PIN, true);
    
      while (true) {
    
      }
    }
    

Children
No Data
Related