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

Setting nRF52840 to deep sleep (sytem-off) and waking up on dedicated pin interrupt.

Hello All,

I am working on the development of a  product based on the nFR52840 SoC (SDK 16 and softdevice 14) and have several pheripherals connected to the chip, one of which is the nRF9160 SiP. My question is a 2 parter;

1. I can software shutdown the other pheripherals, but I couldn't figure out how to do this for the nRF9160, could It be done? If yes, please how do I proceed (software shutdown)?

2. I had a  look at some similar cases and explanations point towards the ble_pheripheral_templetate which advertises for 3 min and goes into deep sleep if no connection is made. Then it should wake up on pressing btn1.

   But it wakes up when any btn in pressed or NFC is detected. How could I implement this concept for my device while sensing only 1 choosen gpio pin as interrupt for waking up the nrf52840 chip ?

Thanks in advance for you time and response.

  • Hi Styve,

    For nRF52840 and using the SDK 16 I would advice looking into the "Power Management " sample in the use that as reference.


    For nRF9160 I would advice you to use the Serial LTE modem sample in NCS as reference. Especially the enter_sleep() function as reference.

    Best regards,
    Martin L.

  • Hello Martin,

    thanks for you reply. I would take a look and try to implement as adviced. I will update the ticket with the outcome I get.

  • Hello

    I have been trying out power management library and I used the nrf_gpio_cfg_sense_input(pin Num, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW) to assigne the wakeup pin. This works well in the  "Power Management " sample" but when I port it to my firmware and try to use btn 4 to put the device to sleep, it crashes with the following error: 

    <info> app: Power management allowed to reset to DFU mode.
    <error> app: ERROR 3735928559 [Unknown error code] at C:\...\components\libraries\pwr_mgmt\nrf_pwr_mgmt.c:418
    PC at: 0x0003DC77
    <error> app: End of error report

     ret_code_t ret_code = sd_power_system_off();  return 2 from nrf_pwr_mgmt.c line 417, even though the softdevice is enabled.

    I could not trace back to the problem, do you have any idea on why this occurs and the solution to it? 

    Thanks again .

    here is the shutdown handler:

    /**@brief Handler for shutdown preparation.
    */
    bool shutdown_handler(nrf_pwr_mgmt_evt_t event)
    {
    uint32_t err_code;
    
    if (m_is_ready == false)
    {
    m_sysoff_started = true;
    return false;
    }
    
    switch (event)
    {
    case NRF_PWR_MGMT_EVT_PREPARE_SYSOFF:
    NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_SYSOFF");
    err_code = bsp_buttons_disable();
    APP_ERROR_CHECK(err_code);
    break;
    
    case NRF_PWR_MGMT_EVT_PREPARE_WAKEUP:
    NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_WAKEUP");
    err_code = bsp_buttons_disable();
    // Suppress NRF_ERROR_NOT_SUPPORTED return code.
    UNUSED_VARIABLE(err_code);
    
    // err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP);
    // // Suppress NRF_ERROR_NOT_SUPPORTED return code.
    // UNUSED_VARIABLE(err_code);
    
    nrf_gpio_cfg_sense_input(24, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    
    err_code = bsp_nfc_sleep_mode_prepare();
    // Suppress NRF_ERROR_NOT_SUPPORTED return code.
    UNUSED_VARIABLE(err_code);
    break;
    
    case NRF_PWR_MGMT_EVT_PREPARE_DFU:
    NRF_LOG_ERROR("Entering DFU is not supported by this example.");
    APP_ERROR_HANDLER(NRF_ERROR_API_NOT_IMPLEMENTED);
    break;
    
    case NRF_PWR_MGMT_EVT_PREPARE_RESET:
    NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_RESET");
    break;
    }
    
    err_code = app_timer_stop_all();
    APP_ERROR_CHECK(err_code);
    
    return true;
    }
    
    /**@brief Register application shutdown handler with priority 0. */
    NRF_PWR_MGMT_HANDLER_REGISTER(shutdown_handler, 0);

  • Hello,

    As previously adviced, I have tested out the recommendations from but I stumbled into another issue in the nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type) in nrf_pwr_mgmt.c  which calls the following;

    /**@brief Function runs the shutdown procedure.
     */
    static void shutdown_process(void)
    {
        NRF_LOG_INFO("Shutdown started. Type %d", m_pwr_mgmt_evt);
        // Executing all callbacks.
        for (/* m_handlers_iter is initialized in nrf_pwr_mgmt_init(). Thanks to that each handler is
                called only once.*/;
             nrf_section_iter_get(&m_handlers_iter) != NULL;
             nrf_section_iter_next(&m_handlers_iter))
        {
            nrf_pwr_mgmt_shutdown_handler_t * p_handler =
                (nrf_pwr_mgmt_shutdown_handler_t *) nrf_section_iter_get(&m_handlers_iter);
            if ((*p_handler)(m_pwr_mgmt_evt))
            {
                NRF_LOG_INFO("SysOff handler 0x%08X => ready", (unsigned int)*p_handler);
            }
            else
            {
                // One of the modules is not ready.
                NRF_LOG_INFO("SysOff handler 0x%08X => blocking", (unsigned int)*p_handler);
                return;
            }
        }
    
        PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY();
        NRF_LOG_INFO("Shutdown complete.");
        NRF_LOG_FINAL_FLUSH();
    
        if ((m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_RESET)
         || (m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_DFU))
        {
            NVIC_SystemReset();
        }
        else
        {
            // Enter System OFF.
    #ifdef SOFTDEVICE_PRESENT
            if (nrf_sdh_is_enabled())
            {
                ret_code_t ret_code = sd_power_system_off();
                ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
                UNUSED_VARIABLE(ret_code);
    #ifdef DEBUG
                while (true)
                {
                    /* Since the CPU is kept on in an emulated System OFF mode, it is recommended
                     * to add an infinite loop directly after entering System OFF, to prevent
                     * the CPU from executing code that normally should not be executed. */
                    __WFE();
    
                }
                
    #endif
                 
            }
               
    #endif // SOFTDEVICE_PRESENT
            nrf_power_system_off();
        }
    }
     

    The retcode is 2 the ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)); fails causing the program to crash, being it in Debug as well as in release mode. I also tried the sd_power_system_off() but it fails too with the retcode = 4095. 

    Could someone have a solution to this ? 


    Thanks.

Related