What is the purpose of arch_ble_ext_wakeup_on?

7 posts / 0 new
Last post
oren.
Offline
Last seen:1 year 6 months ago
Expert
Joined:2014-06-28 22:03
What is the purpose of arch_ble_ext_wakeup_on?

Hi,
We are using SDK 5.0.4 and I was looking at the user_sleepmode example.
It looks like the program listens to button-click interrupts in two cases.

The first case is during a connection. To begin listening,user_app_set_button_eventis called and executes:

wkupct_register_callback(user_app_button_press_cb);
wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN),
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, next_event), // polarity
1, // 1 event
10);

and the listening is stopped byuser_app_disable_buttonwhich callswkupct_disable_irq();.
The listening callback (user_app_button_press_cb) also callsuser_app_set_button_eventto keep listening to button clicks (actually it listens to switches in the button-mode, by choosing the right "next_event").

The second case is when the program stops advertising (after 10 seconds). Whenuser_app_adv_undirect_complete被称为状态GAP_ERR_CANCELED(i.e. it's a deliberate adv-stop) it calls:

arch_ble_ext_wakeup_on();
// Configure wakeup button
app_button_enable();

The purpose ofarch_ble_ext_wakeup_onis:"Puts the BLE core to permanent sleep. Only an external event can wake it up.". It simply sets an internal flag to true.
Then,app_button_enablecalls:

app_easy_wakeup_set(app_wakeup_cb);
wkupct_register_callback(app_button_press_cb);
wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // select pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low
1, // 1 event
40);

i.e. it savesapp_wakeup_cbaside to be called in the future byapp_easy_wakeup,并对第一种情况运行类似的代码,以便开始侦听按钮中断。
When the interrupt occurs,app_button_press_cbis called and executes:

if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
periph_init();
}
...

If I understand correctly, this code must be called in external wakeup during deep-sleep (Is it harmful to call it when using extended sleep?).
Then, the app_button_press_cb continues by calling:

if (arch_ble_ext_wakeup_get())
{
arch_set_sleep_mode(app_default_sleep_mode);
arch_ble_force_wakeup();
arch_ble_ext_wakeup_off();
app_easy_wakeup();
}

i.e. it checks that the external-wakeup-flag is on, initializes the sleep-mode (app_default_sleep_mode is deep-sleep), wakes up the BLE, turn off the external-wakeup flag (i.e. timers and BLE events can now wake up too) and callsapp_easy_wakeup()(which callsapp_wakeup_cbas I explained before).

What are the advantages of the mechanism in the second case? We could avoid callingarch_ble_ext_wakeup_on()and then we won't have to re-configure the sleep mode and re-wake the BLE. What's the point of callingarch_ble_ext_wakeup_on()if the program doesn't have any timers and doesn't advertise (i.e. timers and BLE events cannot wake up the programanyways- so only an external-wakeup can).

Will the program consume less power during deep-sleep if we usearch_ble_ext_wakeup_on?

How comes the second case never callswkupct_disable_irq()? Does going to sleep afterarch_ble_ext_wakeup_onmeans that you don't have to callwkupct_disable_irq()after you wake up?

Thanks,
Oren Zomer

Device:
LC_Dialog
Offline
Last seen:2 weeks 2 days ago
Staff
Joined:2016-09-19 23:20
Hello Oren,

Hello Oren,

I apologize for the delay in answering your questions...

For your first question,
No. You can use this for extended sleep also. Only the default waking up option is set by the user. The SDK takes care of the rest of the process on how to wake up all the modules.
For the second set of questions,
Even though the system is in deep sleep, the system stack wakes up at regular intevals (defined in CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS). This is to poll the UART (which is a side effect for operating over GTL interface of SDK) to check for any exisiting data. The arch_ble_ext_wakeup_on() in user_app_undirect_complete() will supress this process of waking up during these intervals to save the power.
Note: You can notice this in Smart Snippets by disabling this function
For third question,
For Interrupts, In the first case user is setting up the button to listen for the button press and later disabling it. However, the second case sleep is being handled by the sdk and would need the interrupts to be active for waking up the system everytime it is kept to sleep.
Note: For more information on sleep and wakeup modes, refer to these following documents.
Thank you for contacting us. Let us know if you have any further questions. We will be happy to help!
LC_Dialog
oren.
Offline
Last seen:1 year 6 months ago
Expert
Joined:2014-06-28 22:03
Hi LC,

Hi LC,
Thank you for the informative response.
我们现在注意到CFG_MAX_SLEEP_DOURATION_EXTERNAL_WAKEUP_MS参数 - 该rwip_sleep()function is very complicated, but we understand you explanation.
We want the module to stay in deep sleep as long as possible and not wake up every 10 seconds. We don't care about polling the UART - in our use-case, once the module is burned, it will never be connected to a UART.
Is it possible to increase the CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS parameter? If so, what is the maximal value?
I suppose we should usearch_ble_ext_wakeup_onwhen we want to deep-sleep until external wakeup. However, in some cases we just want to deep-sleep for long periods of time (hours, days) - we do it by creating a periodic-timer ofKE_TIMER_DELAY_MAX-1and a counter. We are OK with waking up every 300 seconds, but don't want to wake up every 10 seconds...

问候,
Oren Zomer

P.S.
We don't care much about imprecise timings - if we set a timer for 1 hour we don't care if it will wake up after 50 minutes or 70 minutes. 20% accuracy is good enough for our use-case.

LC_Dialog
Offline
Last seen:2 weeks 2 days ago
Staff
Joined:2016-09-19 23:20
Hello Oren,

Hello Oren,

Yes, you can modify the value ofCFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MSfrom 1sec upto a maximum of 23.3Hrs (value to be assinged in seconds). When thearch_ble_ext_wakeup_on调用将会抑制这个值吗BLE into permanent sleep which is the same for any value on the sleep duration. However, if thearch_ble_ext_wakeup_offis invoked then the value on sleep_duration will come into effect.

For your second requirement, I haven't fully understood the use case. Can you elaborate the scenario.

However, you can extend the sleep duration by changing the above mentioned define. which will control the wakeup period for the BLE. However, this can be supressed by invoking thearch_ble_ext_wake_on()to wake up on an external event (Or) you can also use a timer as a wakeup mechanism instead of an external event.

Note: The sleep process for BLE events (assuming 10s) is managed by an intelligent algorithm that will decide to put the BLE to sleep or not. When we wakeup the BLE at some random time, this algorithm will check to see if it is efficient to go back to sleep or stay awake for the next normal event (say advertising) and based on the decision, this may consume more energy than we expect. Please consider this when scheduling the wakeup

问候,

LC

oren.
Offline
Last seen:1 year 6 months ago
Expert
Joined:2014-06-28 22:03
Hello LC,

Hello LC,
The second requirement is, for example, when we have a sensor (button) and we want to deep-sleep until an external event happens or until 1-hour passed (since we began sleeping).

We must not callarch_ble_ext_wakeup_onin this case because we need to have a timer to wake up after 1-hour if no external event happens...

app_easy_timershould not be called with values aboveKE_TIMER_DELAY_MAX-1(5 minutes) so we use a timer ofKE_TIMER_DELAY_MAX-1and a countdown counter that is initialized to 12.
When the timer-callback is called we reduce the counter by 1 and then:
- If the counter is above 0 we recreate the timer (with a delay ofKE_TIMER_DELAY_MAX-1, i.e. 5 minutes).
- If the counter is 0, we know that 12*5min = 1hour has passed.
If an external event happened in between, we cancel the timer.

I actually think this trick should be a built-in feature inapp_easy_timerin case large delays are used (in v5.0.4 the implementation ofapp_easy_timercallsASSERT_ERROR(delay < KE_TIMER_DELAY_MAX), i.e. large delays are simply not allowed).

Do you know if the default 10-seconds wakeup (due toCFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS) also happened in previous SDK versions? To be specific, I want to know about versions 3.0.4 and 3.0.8. We will increase the value to 23.3 hours, but we already have lots of modules that were already burned with previous SDKs.

问候,
Oren Zomer

oren.
Offline
Last seen:1 year 6 months ago
Expert
Joined:2014-06-28 22:03
Hi LC,

Hi LC,
23小时为82800000毫秒。
MAX_SLEEP_DURATION_EXTERNAL_WAKEUPis defined to beMS_TO_SLOTS_CONVERT(CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS)and theMS_TO_SLOTS_CONVERT(x)macro gives((int)((1000 * x) / 625)).
The multiplication by 1000 creates a compilation warning: "integer operation result is out of range" warning (although the final value, after dividing by 625, is in the range).
A quick fix could be to change the macro to:((int)((1000 *(很久)x) / 625)).

Just wanted to let you know...

问候,
Oren Zomer

LC_Dialog
Offline
Last seen:2 weeks 2 days ago
Staff
Joined:2016-09-19 23:20
Hello Oren,

Hello Oren,

截至目前,我们建议的是使用计时器并重新启动时间,直到您达到所需的时间。因为这是最好的方法,也有助于您的调试。

注意:我们不建议更改值MAX_SLEEP_DURATION_EXTERNAL_WAKEUPas it is effectively changing the SDK implementation. It is also the same in the previous version 3.0.4 and 3.0.8.

We would consider your suggestion for making it a default option in theapp_easy_timer.But, as of now it is not available as a default feature.

Also, thank you for the suggestion to change the macro. I will check it out and escalate to make the correction.

问候,

Leepeng