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?
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?
Hi,
Are you using nRF Connect SDK or nRF5SDK?
Can you share your code?
regards
Jared
I am using nRF5 SDK v16.0.0.
#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.
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