Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 does not wake from sleep when radio timeslot is active

Hi,

We use the nRF radio timeslot API to take control over the radio and other peripherals periodically. We have noticed that when the timeslot is active (we own the peripherals) and we call nrf_pwr_mgmt_run() to sleep, the system never wakes again. To solve it we have to do the following workaround:

static void IdleStateHandler(void)
{
  // Handle pending app events before going to sleep
  app_sched_execute();
  // NOTE: Dont sleep if radio timeslot active since it does not wake again
  // Likely related to the usage of radio timeslot
  if (!RadioTimeslotIsActive() && NRF_LOG_PROCESS() == false)
  {
#if NRF_MODULE_ENABLED(NRF_PWR_MGMT)
    nrf_pwr_mgmt_run();
#endif
  }
}

I would like to know how this is meant to work!

I understand that it may be an issue if the system goes to deep sleep since the wakeup time may introduce a jitter. However, it should be possible to go to shallow sleep (WFI) to save the power consumption of the MCU core. The workaround above means that the MCU core is spinning as long as the timeslot is active, which drains the battery faster.

We use:

nRF52840 DK

nRF5 SDK ver 16.0.0

Softdevice: s113_nrf52_7.0.1_softdevice.hex

BR / Björn

Parents
  • Hello Björn,

    Are there any evens that you expect to wait up from after you enter nrf_pwr_mgmt_run()? If so, what events are you waiting for?

    If you are not sure, perhaps you can try to set up a repeated app_timer with timeout e.g. 1 second. Does that timeout event still fire after you call nrf_pwr_mgmt_run()?

    I know very little about your application. When you call the timeslots from the softdevice. Is the softdevice doing anything else? Advertising? Scanning? In a connection?

    Best regards,

    Edvin

Reply
  • Hello Björn,

    Are there any evens that you expect to wait up from after you enter nrf_pwr_mgmt_run()? If so, what events are you waiting for?

    If you are not sure, perhaps you can try to set up a repeated app_timer with timeout e.g. 1 second. Does that timeout event still fire after you call nrf_pwr_mgmt_run()?

    I know very little about your application. When you call the timeslots from the softdevice. Is the softdevice doing anything else? Advertising? Scanning? In a connection?

    Best regards,

    Edvin

Children
  • Hi Edvin,

    I understand that you need more info :-)I will try to clarify by some example code, see below. First of all, I'm only waiting for a TIMER0 interrupt, and it does not come after I have received the signal NRF_RADIO_CALLBACK_SIGNAL_TYPE_START. TIMER0 is my engine, driving the timeslot state machine forward.

    Regarding the application it is based on Softdevice, but we dont use the Softdevice BLE stack at all. We just request a timeslot every 10 ms and send BLE packets directly using the RADIO. So the Softdevice does not do anything.

    /**
     * Setup the timer when a nrf timeslot starts
     */
    static void TimerSetup(uint32_t timeUs)
    {
        NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
        NRF_TIMER0->CC[0] = timeUs;
        NVIC_EnableIRQ(TIMER0_IRQn);
    }
    
    /**
     * Set time for next event
     */
    static void TimerSetNextEvent(uint32_t timeUs)
    {
        // Clear timer evt/irq
        NRF_TIMER0->EVENTS_COMPARE[0] = 0;
        // Arm next evt
        NRF_TIMER0->CC[0] = timeUs;
    }
    
    /**
     * Timeslot event handler
     */
    static nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
    {
        switch (signal_type)
        {
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
                // Start of the nrf timeslot
    
                // Setup Timer to trigger event/irq
                TimerSetup(firstJobDueTime);
    
                // Remain in timeslot, timer irq is expected
                signal_callback_return_param.params.request.p_next = NULL;
                signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
                break;
    
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
                // Radio IRQ
                break;
    
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
                // Timer IRQ
    
                DoSomeJob();
    
                // Constant time from IRQ to client callback is important!
                // The client shall normally send a packet in the callback
                // Radio IRQ SHOULD NOT be enabled since it will happen
                // just before next timer IRQ and MAY interfere with the timing
    
                if (moreJobToDo()) {
                    // Timer IRQ when next job
                    TimerSetNextEvent(nextJobDueTime);
    
                    // Remain in timeslot, timer IRQ is expected
                    signal_callback_return_param.params.request.p_next = NULL;
                    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
                } else {
                    // Stop current and schedule next timeslot
                    signal_callback_return_param.params.request.p_next = &m_timeslot_request;
                    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
                }
                break;
    
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
                // Fall through
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
                // Shall never happen since extensions not requested
                ASSERT(false);
                break;
    
            default:
                //No implementation needed
                break;
        }
    
        return (&signal_callback_return_param);
    }
    
    

    Let me know if you need more info.

    BR / Björn

  • I am not aware of any bugs regarding the nrf_pwr_mgmt_run() and timeslots. You are sure that the timer is running and you have enabled the IRQ at the time you call nrf_pwr_mgmt_run()? Can you try to set up an app timer and have it set to a repeated timer and see if these interrupts still occur? Or alternatively try with another Timer. One that is not used by the softdevice by default.

    If they don't occur. Is it possible for me to reproduce this on a DK? Would you be able to set up a project that you can send to me here that will reproduce the issue?

    Best regards,

    Edvin

  • Hi Edvin,

    Yes, I'm sure that since this is done in the timeslot signal handler.

    I will consider to set up a simplified project for a DK.

    I can add other timers for debugging, but I'm reluctant since I dont want them in the end. In our project it's crucial that it works with the timeslot API and TIMER0 since this is the engine for our protocol.

    BR / Björn

  • Hi Edvin,

    I have isolated the problem now and attach the whole project. Unpack it in the folder nrf5_sdk\examples\ble_peripheral, make for pca10056 and flash.

    I have copied "ble_app_beacon" into a new project "ble_app_beacon_ts". Here I have added a sample timeslot implementation that blinks the LEDs. If processing in the main context is required then the app will not work since the power manager sleeps forever. If a dummy IRQ is triggered at the end of timeslot then system will wake up.

    Play with the following defines in ts_sample.c:

    // Set to restart LED timers in main context
    // Will not work since Timeslot IRQ does not make
    // the power manager wake up
    #define START_LED_TIMERS_IN_MAIN (1)

    // Set to wake the power manager after end of timeslot
    // Workaround to make processing in main context work
    #define TRIGGER_IRQ_AT_END_OF_TIMESLOT (0)

    So the very clear conclusion is that timeslot IRQs don't wake the system, which in my mind is a bug.

    I'm looking forward to your response.

    BR / Björn

    ble_app_beacon_ts.zip

  • Have you tried to add a log message in NRF_RADIO_CALLBACK_SIGNAL_TYPE_START? I don't quite follow your LED logic, but I see that the NRF_RADIO_CALLBACK_SIGNAL_TYPE_START event occurs even if the LEDs are not toggling. Could it be that the issue is related to the LED logic or the timer?

    BR,

    Edvin

Related