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

SoftDevice does 26ms of work inside first call to sd_app_evt_wait()

nRF52832_XXAA, S132 v5.0.1, SDK 14.0.0

We enable SoftDevice via nrf_sdh_enable_request(). We immediately assert nrf_sdh_is_enabled() so we know it worked. On the first call to sd_app_evt_wait() we see SoftDevice take control of the CPU for 26ms. We have not started advertising or done any BLE work, the device is silent.

In certain boot conditions, this is fine and we don't care, SD can do what it wants. In other boot conditions, this 26ms work happens while we're doing open-loop battery measurement and powering the device off of a tiny capacitor. SD's mystery work immediately overwhelms this cap and the measurement aborts.

The code looks almost exactly like this:

nrf_sdh_enable_request();
volatile bool done = false;
while (!done) {
  sd_app_evt_wait();
}

Questions:

1. What is SD doing?

2. How do we know when SD will do work when we sleep?

3. Is there any API for us to test that SD is done with whatever its 26msec work is?

4. Will this work ever take more or less time than 26msec?

We need to know when it's safe to sleep for 125msec with no SD activity, or we can't boot correctly.

(Note that we used to enable SD after doing all of this work, but that led to a race when initializing the LFCLK so we enable SD very early now).

Parents Reply Children
  • "done" is never set to true, the point is to enter an infinite sleep loop immediately before/after enabling softdevice to prove that the CPU work isn't being done by our application code. An ETM trace has proven that there are no interrupt handlers firing inside our application; the only code that's running is softdevice.

    If we do an infinite WFE loop _before_ enabling softdevice, we don't see this current draw.

    If we do an infinite sd_app_evt_wait loop _immediately after_ enabling softdevice, we do see this current draw.

  • It does take some time to start up the LFCLK if you use an external LFXTAL, and the time depends on the XTAL that you use. For testing purposes, you can try to use the RC Oscillator instead (which needs less time to start). You set the LFCLOCK source in sdk_config.h.

  • Is there a way we can learn with 100% certainty when this work is complete?

    Immediately after enabling softdevice, but before we see this 26ms sleep-time work, we make a nrf_drv_lfclk_request and assert that the handler is called before nrf_drv_lfclk_request returns. Our handler asserts that the event is NRF_DRV_CLOCK_EVT_LFCLK_STARTED, so that we know the system is running.

    Apparently this is not the full story, since /after/ we get our EVT_LFCLK_STARTED, we do an sd_app_evt_wait call and see SD wake up and do 26ms of work.

    How can we learn when SD has no queued work that's just waiting for an sd_app_evt_wait?

    (also, why do we get the LFCLK_STARTED event if the clock isn't really ready?)

Related