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

SDK 14 soft device manager running error

I'm using SDK14, S132 5.0 and nRF52832, and trying to enable and disable softdevice in my application. In main function, the power management loop is like

  while(1)
  {
    if(nrf_sdh_is_enabled( ))
    {
      app_sched_execute();
      ret_code_t ret = sd_app_evt_wait();
      APP_ERROR_CHECK(ret);
    }
    else
    {
      __WFE();
      __SEV();
      __WFE();
    }
  }	

When call nrf_sdh_disable_request() to stop softdevice, the program is stopped inside the function call line sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLED); (line 256 of nrf_sdh.c). In line 234 the same function is called as sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLE_PREPARE); with no problem. More specially, the program is topped in function sdh_state_observer_notify() line handler(evt, p_observer->p_context); inside "for" loop (line 143 of nrf_sdh.c). The for loop is repeated 2 times base on my observation, however, the 1st time repeat of "for" loop is OK, the problem is the 2nd (last) repeat of "for" loop, the program is stopped.

My question, is there any synchronization requirement between the power management loop and the soft device status? because inside power management loop, there are 2 branches according soft device status.

Another point is that inside function nrf_sdh_disable_request(), just skip the line sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLED); (commented out), the program is no problem to run, soft device can be enabled and disabled freely. Is it OK to remove the line sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLED); inside function nrf_sdh_disable_request()?

I'm using GCC.

Thanks a lot.

More information:

I'm using ANCS example ble_app_ancs_c, some codes are added to stop soft device after some time:

/****************************************************************************/
APP_TIMER_DEF(stop_sd_timer_id); 

/****************************************************************************/
void stop_sd_timer_handler(void * p_context)
{
  uint32_t err_code;
	
  // Stop any impending connection parameters update.
  err_code = ble_conn_params_stop();
  APP_ERROR_CHECK(err_code);

  // Stop application timers.
  err_code = app_timer_stop(m_sec_req_timer_id);
  APP_ERROR_CHECK(err_code);

  NRF_LOG_INFO("==================== disable softdevice ====================");	
  err_code = nrf_sdh_disable_request();
  APP_ERROR_CHECK(err_code);		
  NRF_LOG_INFO("==================== softdevice disabled ====================");
}

/****************************************************************************/
void sd_timer_config(void)
{
  uint32_t ret;
	
  // Create SD stop timer.
  ret = app_timer_create(&stop_sd_timer_id, APP_TIMER_MODE_SINGLE_SHOT,
                         stop_sd_timer_handler);
  APP_ERROR_CHECK(ret);
}
/****************************************************************************/

And in main function, following codes are added just before the power management loop:

/****************************************************************************/
sd_timer_config( );
			
NRF_LOG_INFO("==================== start sd-stop timer ===================");
uint32_t ret = app_timer_start(stop_sd_timer_id, 32768 * 10, NULL);
APP_ERROR_CHECK(ret);		
/****************************************************************************/

If the power management loop is unchanged, the program can be run without stop, but there is a Fatal and reset, the INFO output is as:

<info> app: Apple Notification Center Service client example started.
<info> app: Fast advertising
<info> app: ==================== start sd-stop timer ===================
<info> app: ==================== disable softdevice ====================
<info> app: ==================== softdevice disabled ====================
<error> app: Fatal
<info> app: Apple Notification Center Service client example started.
<info> app: Fast advertising
<info> app: ==================== start sd-stop timer ===================
<info> app: ==================== disable softdevice ====================
<info> app: ==================== softdevice disabled ====================
<error> app: Fatal
<info> app: Apple Notification Center Service client example started.
......

But if the power management loop is changed as:

for (;;)
{
  if(nrf_sdh_is_enabled( ))
  {
    app_sched_execute();
    if (NRF_LOG_PROCESS() == false)
    {
      power_manage();
    }
  }
  else
  {
    __WFE();
    __SEV();
    __WFE();
  }
}

The program is stop at the function call nrf_sdh_disable_request();, the output is as:

<info> app: Fast advertising
<info> app: ==================== start sd-stop timer ===================
<info> app: ==================== disable softdevice ====================

There is no output line " app: ==================== softdevice disabled ====================" after the function call nrf_sdh_disable_request();, since the program stop inside the function.

The only difference is the power management loop, softdevice behavior is so different.

Are there any bugs in my code? I just want to stop softdevice after some time, here use app_timer to trigger the softdevice stop event. In my application program, it is triggered by user input or other GPIOTE events.

Related