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(); } }