How to prevent nRF52832 device to enter sleep mode?

I found after a while I can't scan BLE device "ANCS2". Since I don't implement wake up mechanism, how to prevent  nRF52832 device to enter sleep mode?

Parents
  • Hi,

    Are you using nRF Connect SDK or nRF5SDK? 

    Can you share your code?

    regards

    Jared 

  • #include "sdk_config.h"
    #include "advertising.h"
    #include "ble_types.h"
    #include "ble_nus.h"
    #include "bsp.h"
    #include "bsp_btn_ble.h"
    #include "error.h"
    #include "nrf_log.h"
    #include "nrf_sdh_ble.h"
    
    #define APP_ADV_INTERVAL               800             /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    #define APP_ADV_DURATION               1800            /**< The advertising duration (180 seconds) in units of 10 milliseconds. */         
    #define APP_ADV_FAST_DURATION          0//1800          /**< The advertising duration of fast advertising in units of 10 milliseconds. */
    #define APP_ADV_SLOW_DURATION          0//1800          /**< The advertising duration of slow advertising in units of 10 milliseconds. */
    #define APP_ADV_FAST_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< The advertising interval (in units of 0.625 ms). The default value corresponds to 25 ms. */
    #define APP_ADV_SLOW_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< Slow advertising interval (in units of 0.625 ms). The default value corresponds to 2 seconds. */
    #define NUS_SERVICE_UUID_TYPE          BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
    
    BLE_ADVERTISING_DEF(_gAdvertising);  /**< Advertising module instance. */ 
    
    #if 1
    static ble_uuid_t _gAdvUuids[]          = {                                         /**< Universally unique service identifier. */ 
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    #else
    static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
    {
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    
    #endif
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
    static void _sleepModeEnter(void) {
        ret_code_t errCode;
        errCode = bsp_indication_set(BSP_INDICATE_IDLE);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Prepare wakeup buttons.
        errCode = bsp_btn_ble_sleep_mode_prepare();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_btn_ble_sleep_mode_prepare() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        errCode = sd_power_system_off();
    #ifndef DEBUG_NRF    
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_power_system_off() failed, errCode=0x%x\n", errCode);
            return;
        }
    #endif
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function is called for advertising events that are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void _advertisingEvtHandler(ble_adv_evt_t evt) {
        ret_code_t errCode;
    
        switch (evt) {
            case BLE_ADV_EVT_FAST:
            {    
                NRF_LOG_INFO("BLE_ADV_EVT_FAST");
                errCode = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                if (errCode != NRF_SUCCESS) {
                    NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
                    return;
                }
            }
            break;
                        
            case BLE_ADV_EVT_IDLE:
            {   
                NRF_LOG_INFO("BLE_ADV_EVT_IDLE");
                _sleepModeEnter();
            }
            break;
    
            default:
            break;
        }
    }
    
    #if 0
    int advertisingInit(void) {
        ret_code_t errCode;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = false;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.advdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.srdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.config.ble_adv_whitelist_enabled = false;
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_FAST_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_FAST_DURATION;
        init.config.ble_adv_slow_enabled  = true;
        init.config.ble_adv_slow_interval = APP_ADV_SLOW_INTERVAL;
        init.config.ble_adv_slow_timeout  = APP_ADV_SLOW_DURATION;
        init.evt_handler = _advertisingEvtHandler;
    
        errCode = ble_advertising_init(&_gAdvertising, &init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_init() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_INITIALIZE_FAIL;
        }
    
        ble_advertising_conn_cfg_tag_set(&_gAdvertising, APP_BLE_CONN_CFG_TAG);
    
        return 0;
    }
    #else
    int advertisingInit(void) {
        uint32_t               errCode;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.srdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
        init.evt_handler = _advertisingEvtHandler;
    
        errCode = ble_advertising_init(&_gAdvertising, &init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_init() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_INITIALIZE_FAIL;
        }
    
        ble_advertising_conn_cfg_tag_set(&_gAdvertising, APP_BLE_CONN_CFG_TAG);
    
        return 0;
    }
    
    #endif
    
    
    ble_adv_modes_config_t advertisingConfigGet(void) {
        ble_adv_modes_config_t config;
        memset(&config, 0, sizeof(ble_adv_modes_config_t));
    
        config.ble_adv_fast_enabled           = true;
        config.ble_adv_fast_interval          = APP_ADV_INTERVAL;
        config.ble_adv_fast_timeout           = APP_ADV_DURATION;
        config.ble_adv_on_disconnect_disabled = true;
    
        return config;
    }
    
    void advertisingModesConfigSet(void) {
        const ble_adv_modes_config_t config = advertisingConfigGet();
        ble_advertising_modes_config_set(&_gAdvertising, &config);
    }    
    
    
    /* Function for starting advertising. */
    int advertisingStart(void) {
    //        memset(m_whitelist_peers, PM_PEER_ID_INVALID, sizeof(m_whitelist_peers));
    //        m_whitelist_peer_cnt = (sizeof(m_whitelist_peers) / sizeof(pm_peer_id_t));
    
    //        peer_list_get(m_whitelist_peers, &m_whitelist_peer_cnt);
    
    //        ret = pm_whitelist_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        APP_ERROR_CHECK(ret);
    
    //        // Setup the device identies list.
    //        // Some SoftDevices do not support this feature.
    //        ret = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        if (ret != NRF_ERROR_NOT_SUPPORTED)
    //        {
    //            APP_ERROR_CHECK(ret);
    //        }
    
    
        const ret_code_t errCode = ble_advertising_start(&_gAdvertising, BLE_ADV_MODE_FAST);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_start() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_START_FAIL;
        }
        
        return 0;
    }
    
    

  • Hi,

    In BLE_ADV_EVT_IDLE you call sd_system_off() by _sleepModeEnter(). The program will enter BLE_ADV_EVT_IDLE after advertising has ended. If you want to avoid the program going to system off sleep then remove the function call from the BLE_ADV_EVT_IDLE event.

     
    regards
    Jared 
  • Thanks for your suggestion! I have removed calling  _sleepModeEnter(). But nRF Connect still can't scan BLE device "ANCS2" after  _advertisingEvtHandler() handles BLE_ADV_EVT_IDLE event.

    The following is log messages of nRF52832 device:
    00> <info> app: POWER_ON.
    00> <info> app: BLE_ADV_EVT_FAST
    00> <info> app: BLE_ADV_EVT_IDLE

Reply Children
  • #include "sdk_config.h"
    #include "advertising.h"
    #include "ble_types.h"
    #include "ble_nus.h"
    #include "bsp.h"
    #include "bsp_btn_ble.h"
    #include "error.h"
    #include "nrf_log.h"
    #include "nrf_sdh_ble.h"
    
    #define APP_ADV_INTERVAL               800             /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    #define APP_ADV_DURATION               1800            /**< The advertising duration (180 seconds) in units of 10 milliseconds. */         
    #define APP_ADV_FAST_DURATION          0//1800          /**< The advertising duration of fast advertising in units of 10 milliseconds. */
    #define APP_ADV_SLOW_DURATION          0//1800          /**< The advertising duration of slow advertising in units of 10 milliseconds. */
    #define APP_ADV_FAST_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< The advertising interval (in units of 0.625 ms). The default value corresponds to 25 ms. */
    #define APP_ADV_SLOW_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< Slow advertising interval (in units of 0.625 ms). The default value corresponds to 2 seconds. */
    #define NUS_SERVICE_UUID_TYPE          BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
    
    BLE_ADVERTISING_DEF(_gAdvertising);  /**< Advertising module instance. */ 
    
    #if 1
    static ble_uuid_t _gAdvUuids[]          = {                                         /**< Universally unique service identifier. */ 
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    #else
    static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
    {
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    
    #endif
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
    static void _sleepModeEnter(void) {
        ret_code_t errCode;
        errCode = bsp_indication_set(BSP_INDICATE_IDLE);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Prepare wakeup buttons.
        errCode = bsp_btn_ble_sleep_mode_prepare();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_btn_ble_sleep_mode_prepare() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        errCode = sd_power_system_off();
    #ifndef DEBUG_NRF    
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_power_system_off() failed, errCode=0x%x\n", errCode);
            return;
        }
    #endif
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function is called for advertising events that are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void _advertisingEvtHandler(ble_adv_evt_t evt) {
        ret_code_t errCode;
    
        switch (evt) {
            case BLE_ADV_EVT_FAST:
            {    
                NRF_LOG_INFO("BLE_ADV_EVT_FAST");
                errCode = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                if (errCode != NRF_SUCCESS) {
                    NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
                    return;
                }
            }
            break;
                        
            case BLE_ADV_EVT_IDLE:
            {   
                NRF_LOG_INFO("BLE_ADV_EVT_IDLE");
                // _sleepModeEnter();
            }
            break;
    
            default:
            break;
        }
    }
    
    #if 0
    int advertisingInit(void) {
        ret_code_t errCode;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = false;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.advdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.srdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.config.ble_adv_whitelist_enabled = false;
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_FAST_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_FAST_DURATION;
        init.config.ble_adv_slow_enabled  = true;
        init.config.ble_adv_slow_interval = APP_ADV_SLOW_INTERVAL;
        init.config.ble_adv_slow_timeout  = APP_ADV_SLOW_DURATION;
        init.evt_handler = _advertisingEvtHandler;
    
        errCode = ble_advertising_init(&_gAdvertising, &init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_init() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_INITIALIZE_FAIL;
        }
    
        ble_advertising_conn_cfg_tag_set(&_gAdvertising, APP_BLE_CONN_CFG_TAG);
    
        return 0;
    }
    #else
    int advertisingInit(void) {
        uint32_t               errCode;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.srdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
        init.evt_handler = _advertisingEvtHandler;
    
        errCode = ble_advertising_init(&_gAdvertising, &init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_init() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_INITIALIZE_FAIL;
        }
    
        ble_advertising_conn_cfg_tag_set(&_gAdvertising, APP_BLE_CONN_CFG_TAG);
    
        return 0;
    }
    
    #endif
    
    
    ble_adv_modes_config_t advertisingConfigGet(void) {
        ble_adv_modes_config_t config;
        memset(&config, 0, sizeof(ble_adv_modes_config_t));
    
        config.ble_adv_fast_enabled           = true;
        config.ble_adv_fast_interval          = APP_ADV_INTERVAL;
        config.ble_adv_fast_timeout           = APP_ADV_DURATION;
        config.ble_adv_on_disconnect_disabled = true;
    
        return config;
    }
    
    void advertisingModesConfigSet(void) {
        const ble_adv_modes_config_t config = advertisingConfigGet();
        ble_advertising_modes_config_set(&_gAdvertising, &config);
    }    
    
    
    /* Function for starting advertising. */
    int advertisingStart(void) {
    //        memset(m_whitelist_peers, PM_PEER_ID_INVALID, sizeof(m_whitelist_peers));
    //        m_whitelist_peer_cnt = (sizeof(m_whitelist_peers) / sizeof(pm_peer_id_t));
    
    //        peer_list_get(m_whitelist_peers, &m_whitelist_peer_cnt);
    
    //        ret = pm_whitelist_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        APP_ERROR_CHECK(ret);
    
    //        // Setup the device identies list.
    //        // Some SoftDevices do not support this feature.
    //        ret = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        if (ret != NRF_ERROR_NOT_SUPPORTED)
    //        {
    //            APP_ERROR_CHECK(ret);
    //        }
    
    
        const ret_code_t errCode = ble_advertising_start(&_gAdvertising, BLE_ADV_MODE_FAST);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_start() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_START_FAIL;
        }
        
        return 0;
    }
    
    

  • I have removed calling  _sleepModeEnter() and calling advertisingStart() when _advertisingEvtHandler() handles BLE_ADV_EVT_IDLE event. Do you think it is good idea?

    00> <info> app: POWER_ON.
    00>
    00> <info> app: External devices initializing start
    00>
    00> <info> app: BLE_ADV_EVT_FAST
    00>
    00> <info> app: External devices initializing finish
    00>
    00> <info> app: bsp_button_longkey_handler 1.
    00>
    00> <info> app: BLE_ADV_EVT_IDLE
    00>
    00> <info> app: BLE_ADV_EVT_FAST
    00>
    00> <info> app: BLE_ADV_EVT_IDLE
    00>
    00> <info> app: BLE_ADV_EVT_FAST
    00>
    00> <info> app: BLE_ADV_EVT_IDLE
    00>
    00> <info> app: BLE_ADV_EVT_FAST
    00>
    00> <info> app: BLE_ADV_EVT_IDLE
    00>
    00> <info> app: BLE_ADV_EVT_FAST
    00>
    00> <info> app: BLE_ADV_EVT_IDLE
    00>
    00> <info> app: BLE_ADV_EVT_FAST

  • Hi,

    Are you able to find the device advertising if you remove the filter?

    snowuyl said:
    I have removed calling  _sleepModeEnter() and calling advertisingStart() when _advertisingEvtHandler() handles BLE_ADV_EVT_IDLE event. Do you think it is good idea?

    Yes, this is fine. The advertising module will go to IDLE state after it has iterated through all the enabled advertising states and no connection requests has been received. Restarting advertising when it has reached the IDLE state is ok.

    Are you using a custom board or the development kit?

    regards

    Jared  

Related