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

How to implement a simple non-blocking delay on nRF51822 with SoftDevice

Using nrf_delay_ms() can be energy consuming and indeterministic. I am trying to use application timers (from "app_timer.h") in nRF SDK 8.0. The way I did could be partially described as follows:

#define LED_DURATION_IN_MS    400   
#define LED_DURATION_TICKS      APP_TIMER_TICKS(LED_DURATION_IN_MS, APP_TIMER_PRESCALER)

static app_timer_id_t m_lazy_wait_timer;
static volatile uint8_t lazy_wait_flag = 0;

static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}

void lazy_wait_handler(void * p_context)
{ 
	// Clear the wait flag 
	lazy_wait_flag = 0;
}

static void timers_init(void)
{
  APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
  err_code = app_timer_create(&m_lazy_wait_timer, APP_TIMER_MODE_SINGLE_SHOT, lazy_wait_handler);
  APP_ERROR_CHECK(err_code);
}
	
void main()
{
    ...
    ...

    timers_init();
    nrf_gpio_cfg_output(1);
    nrf_gpio_pin_set(1);
    uint32_t err_code = app_timer_start(m_lazy_wait_timer, LED_DURATION_TICKS, NULL);
    APP_ERROR_CHECK(err_code);
    lazy_wait_flag = 1;
    while(lazy_wait_flag) {
        power_manage();
    }
    nrf_gpio_pin_clear(1);

    for (;;)
    {
        app_sched_execute();
        power_manage();
    }
}

However, the code doesn't work as expected. It seems the "lazy_wait_flag" is not cleared and the code is stuck in the while loop. What is the correct way of doing it?

Parents
  • If the LED being set indicates success, i believe your code behaves exactly how it should be :) If you call app_sched_execute() before power_manage(), this happens: power_manage()->Timer event->app_sched_execute->lazy_wait_handler->power_manage(). It never escaped the while loop, it will sleep forever inside power manage. If you call it after: power_manage()->Timer event->app_sched_execute->lazy_wait_handler->While loop checking flag ->escape while loop. See the scheduler docs for some more info.

Reply
  • If the LED being set indicates success, i believe your code behaves exactly how it should be :) If you call app_sched_execute() before power_manage(), this happens: power_manage()->Timer event->app_sched_execute->lazy_wait_handler->power_manage(). It never escaped the while loop, it will sleep forever inside power manage. If you call it after: power_manage()->Timer event->app_sched_execute->lazy_wait_handler->While loop checking flag ->escape while loop. See the scheduler docs for some more info.

Children
No Data
Related