Hi,
We have developed a program that responds to button interrupts, similarly to the sleepmode and prox_reporter programs.
In our case, the program never goes to permanent sleep - it always either advertising or has a timer in the background to restart advertising in the future. When a button is pressed, we want to change the advertised payload and stop responding to the button for several seconds (i.e. ignore multiple presses or double-clicks).
We have noticed that sleepmode program has a single callback to respond to button events (user_app_button_press_cb which is set by wkupct_register_callback), but the prox_reporter has 2 callbacks: app_button_press_cb which is set by wkupct_register_callback and app_wakeup_cb which is set by app_easy_wakeup_set.
In the prox_reporter, the app_button_press_cb calls seems to do some low level operations (periph_init, arch_set_sleep_mode, arch_ble_force_wakeup, arch_ble_ext_wakeup_off) and then call app_easy_wakeup, which sends an event that is supposed to initiate app_wakeup_cb which will do the high-level logic.
We assume that the two-callbacks algorithm is required in order to let the system complete its wakeup operations, or to prevent the high-level operations from being called several times in a row. For some reason, our app_wakeup_cb is not being called (we debugged the code and noticed that app_easy_wakeup() is called, but app_wakeup_cb is not called afterwards...).
We then called app_wakeup_cb() directly from user_app_button_press_cb (instead of calling app_easy_wakeup()), but we are not sure if this is safe.
What are the side effects of not using app_easy_wakeup? Are our assumptions correct? Why is it missing from the sleepmode program? Do you have a similar program that responds to a button click only once, i.e. disables the irq after a button was pressed, and re-enables the irq only after several seconds?
We noticed that at the end of app_button_press_cb, it calls app_button_enable() again. In our case, we do not want to immediately restart listening to button events, so we removed this line. May this be our problem that causes app_wakeup_cb not to run?
Thanks,
Oren Zomer
Hi oren,
Both of the examples ble_app_sleepmode and proximity reporter follow the same procedure in order to exit the permanent sleep mode, the ble_app_sleepmode invokes from the app_button_enable() the app_easy_wakeup_set(app_wakeup_cb); and the wkupct_register_callback(app_button_press_cb);. The reason for that is because if a BLE operation is invoked directly from the wkupct callback and the BLE core hasn't been awake yet then the BLE operation wont be executed at all, that is why there is the app_easy_wakeup_set() and app_easy_wakeup() functions in order to ensure that whatever is located in the function registered with the app_easy_wakeup_set() function will be executed while the BLE core is awake. I dont see anything missing from the ble_app_sleepmode, they both register two callback for waking up from an external interrupt. Regarding your issue for not executing the app_easy_wakeup() please make sure that you have enabled the corrsponding module, go the user_modules_config.h file and make sure that the value of the EXCLUDE_DLG_MSG is set to 0 in order for the module to be included.
Thanks MT_dialog