Hi I am trying to program the bsp buttons on the NRF52 DK, so pushing button 1 will toggle start advertising and going to sleep by calling sd_app_evt_wait().
I have successfully got the button to go to sleep when pressed, but in my current code below after it goes to sleep it cannot be woken up if I press button 1 again or any other button on the DK. I use an integer variable 'bsp_adv_bool' to keep track of whether the NRF should go to sleep or wake up & advertise when button 1 is pressed. Should I be using another method to wake up button 1 and then set it call sd_app_evt_wait() on the next press?
static uint8_t bsp_adv_bool = 0;
static void sleep_mode_enter(void)
{
ret_code_t err_code;
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
// Prepare wakeup buttons.
err_code = bsp_btn_ble_sleep_mode_prepare();
APP_ERROR_CHECK(err_code);
err_code = sd_app_evt_wait();
APP_ERROR_CHECK(err_code);
}
static void bsp_event_handler(bsp_event_t event)
{
ret_code_t err_code;
switch (event)
{
case BSP_EVENT_SLEEP:
if(bsp_adv_bool == 0)
{
bsp_adv_bool = 1;
sleep_mode_enter();
}
else if (bsp_adv_bool == 1)
{
bsp_adv_bool = 0;
bool erase_bonds;
advertising_start(erase_bonds);
}
break; // BSP_EVENT_SLEEP
case BSP_EVENT_DISCONNECT:
err_code = sd_ble_gap_disconnect(m_conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
if (err_code != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(err_code);
}
break; // BSP_EVENT_DISCONNECT
case BSP_EVENT_WHITELIST_OFF:
if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
{
err_code = ble_advertising_restart_without_whitelist(&m_advertising);
if (err_code != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(err_code);
}
}
break; // BSP_EVENT_KEY_0
default:
break;
}
}
static void buttons_leds_init(bool * p_erase_bonds)
{
ret_code_t err_code;
bsp_event_t startup_event;
err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
APP_ERROR_CHECK(err_code);
err_code = bsp_btn_ble_init(NULL, &startup_event);
APP_ERROR_CHECK(err_code);
*p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}
static void idle_state_handle(void)
{
if (NRF_LOG_PROCESS() == false)
{
sd_app_evt_wait();
}
}
int main(void)
{
bool erase_bonds;
// Initialize.
log_init();
timers_init();
application_timers_start();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
peer_manager_init();
services_init();
advertising_init();
conn_params_init();
NRF_LOG_INFO("Template example started.");
advertising_start(erase_bonds);
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
In slightly different code below I attempt to program the DK to only start advertising when button 1 is pressed, but the code still relies on logic structure similar to the code above. So the code below doesn't work either until the above code is fixed. But should calling advertising_start() only in bsp_event_handler() work or is there issues with doing this?
static uint8_t bsp_adv_bool = 1;
static void sleep_mode_enter(void)
{
ret_code_t err_code;
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
// Prepare wakeup buttons.
err_code = bsp_btn_ble_sleep_mode_prepare();
APP_ERROR_CHECK(err_code);
err_code = sd_app_evt_wait();
APP_ERROR_CHECK(err_code);
}
static void bsp_event_handler(bsp_event_t event)
{
ret_code_t err_code;
switch (event)
{
case BSP_EVENT_SLEEP:
if(bsp_adv_bool == 0)
{
bsp_adv_bool = 1;
sleep_mode_enter();
}
else if (bsp_adv_bool == 1)
{
bsp_adv_bool = 0;
bool erase_bonds;
NRF_LOG_INFO("Template example started.");
advertising_start(erase_bonds);
}
break; // BSP_EVENT_SLEEP
case BSP_EVENT_DISCONNECT:
err_code = sd_ble_gap_disconnect(m_conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
if (err_code != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(err_code);
}
break; // BSP_EVENT_DISCONNECT
case BSP_EVENT_WHITELIST_OFF:
if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
{
err_code = ble_advertising_restart_without_whitelist(&m_advertising);
if (err_code != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(err_code);
}
}
break; // BSP_EVENT_KEY_0
default:
break;
}
}
int main(void)
{
bool erase_bonds;
// Initialize.
log_init();
timers_init();
application_timers_start();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
peer_manager_init();
services_init();
conn_params_init();
advertising_init();
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
