Change in fine timer behavior from 1.x to 2.x SDK

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
legic_1490776
Level 5
Level 5
25 likes received 10 likes received First like received

In the 1.x SDK using the 20732S, I found that even if I sent a fine timer rate at something quite high, it would only actually fire when the device was awake anyway - that is, the fine timer itself was not sufficient to wake up the device.

So for example, I could set the timer at 25ms rate, and a 500ms connection interval.  The timer would only fire when the device woke up to service the connection interval -- thus even though I asked for a 25ms timer it would in reality be more like 500ms.

As first I thought of this as a bug, but I worked around it and ultimately it turns out to be sort of handy because now I have a timer that fires fast, but only when the device is awake, thus not causing much additional overhead.  In fact it also represented a clever way to tell whether or not the device was awake, based on the timer latency.

Fast forward to the 20736S and SDK 2.0....

Now it appears the "bug" has been fixed.  When I set a timer of 25ms I get 25ms.

Is there any way to get something similar to the original functionality -- a timer that fires at a given rate but doesn't actually cause the system to wake up -- only fires if it is awake for some other reason?

0 Likes
1 Solution
legic_1490776
Level 5
Level 5
25 likes received 10 likes received First like received

Actually, the best way to get this sort of effect is to use the connection event notification API referenced here:

Re: Connection Event Callback API

This allows you to configure a callback to trigger whenever a connection event occurs, and therefore at times when the device is awaken and working.  Using this callback in place of the fine timer callback achieves similar behavior to the 1.x SDK in this regard.

View solution in original post

11 Replies
MichaelF_56
Moderator
Moderator
Moderator
250 sign-ins 25 comments on blog 10 comments on blog

I will need to look into this with the developers and determine if there is similar finctionality available within SDK 2.x


santol

0 Likes

I checked with the developers and unfortunately, there is no known workaround for this issue.

They feel that the simplest thing to do is to turn off the two timers when they are not required and then turn on when they are using Use bleprofile_StartTimer() and bleprofile_KillTimer().

santol

0 Likes
legic_1490776
Level 5
Level 5
25 likes received 10 likes received First like received

Actually, the best way to get this sort of effect is to use the connection event notification API referenced here:

Re: Connection Event Callback API

This allows you to configure a callback to trigger whenever a connection event occurs, and therefore at times when the device is awaken and working.  Using this callback in place of the fine timer callback achieves similar behavior to the 1.x SDK in this regard.

Anonymous
Not applicable

I am a bit confused: if I see the FW code, it looks to me: it can go to sleep, e.g. without an established connection. To bring it back needs a press on wakeup button. The only way to bring out the WICED Sense from a deep sleep (wakeup event) seems to be a button press, not a timer.

What I have also realized: if connection is established - all fine.

If connection was not there - or connection was lost - the device goes to deep sleep. And in this state - you MUST press the button. So, you cannot use unattended (already mentioned and complained about). The device will never send Advertisements when it has lost connection or was sleeping. Very strange design, to be honest:

I should wakeup itself, periodically, e.g. every few minutes. It should send short Advertisement so that a client around can discover and decide to connect. But it is not the case: the major feature on device is the Wakeup button and a person pressing it.

I have not seen any wakekup timer event configured, just button events in code.

0 Likes

When the system is in deep sleep, the the CPU is not running and the RAM is not powered, so it's a different situation than a timer interrupt during operation.  It is more similar to a PC in 'suspend' or 'hibernate' mode.

It is possible to wake from deep sleep after a set time, by enabling wakeup from the low power oscillator which can still run during deep sleep:

   devLpmConfig.disconnectedLowPowerMode = LOW_POWER_MODE_POLL_TYPE_POWER_OFF;

   devLpmConfig.wakeFromHidoffInMs = 20000;   // set wake time in milliseconds

   devLpmConfig.wakeFromHidoffRefClk = HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ;

   devlpm_enterLowPowerMode();

I think the above was using SDK 1.x but it is probably similar if not identical in SDK 2.x

Anonymous
Not applicable

Thank you, I see.

(I am a bit familiar with the issues - have written a power manager, CPM, for multicore ARM V8 SoCs).

I am aware of the differences anetweem "suspend/hibernate, sleep, deep sleep" etc..

I am just concerned about: deep sleep with retention flops (e.g. UART registers are retained or not) or MCU sleep (just clock stopped). I have assumed, a Deep Sleep is done. And if Deep Sleep: just the SRAM content will be retained. But all MCU registers, states, including peripherals are lost. A wakeup from Deep Sleep is really like a "hibernate" = reconfigure all the devices plus their states (we might not have really a hibernate here because the status image is not written to non-volatile memory and read back ...).

So, I still guess, the MCU is just in "power saving mode, in sleep mode" (as: all clocks off but not power off or power not below retention level).

I was thinking: is it possible to bring MCU on a connection, e.g. between sensor cycles/Notification really to deep sleep? (stopping the clock is easy, works on all SDKs and MCUs, but a real Deep Sleep without CPU and Peripheral retentained, power really off - is very tricky and potentially not implemented here, right?)

0 Likes

I am just concerned about: deep sleep with retention flops (e.g. UART registers are retained or not) or MCU sleep (just clock stopped). I have assumed, a Deep Sleep is done. And if Deep Sleep: just the SRAM content will be retained. But all MCU registers, states, including peripherals are lost.

As I understand it (note that i'm just a user, not BRCM staff -- so i'm working off the docs and my experiences) only a very limited amount of the configuration of the chip is retained in deep sleep.  The chip wakes as if from reboot, so all of the same initialization code is run just as if it were booting from a reset.  During deep sleep

* it is optionally possible to keep the LPO running to do a timed wakeup

* the system can wake from interrupts on GPIO lines that are configured before going to sleep

* the output state of the GPIO lines is supposed to be retained during deep sleep, although it appears at the moment that this is not the case - but I think this may be a bug (see BCM20736S HIDOFF problem )

Apart from that, the chip is turned off.

Note also that by my measurements, waking up from deep sleep costs roughly 6500 micro-amp-seconds during the boot up process, so it's not something to be done lightly.  Given that the "normal" sleep draw (i.e. SRAM retained) is roughly 40 uA, going to deep sleep for less than 3 minutes or so is not going to save energy.  (These measurements are based on my custom board but most of the cost is from the '732 in my case)

A wakeup from Deep Sleep is really like a "hibernate" = reconfigure all the devices plus their states (we might not have really a hibernate here because the status image is not written to non-volatile memory and read back ...).

Yes, more like hibernate, but you have to implement your own code to restore any state you had previously since SRAM is cleared.

I was thinking: is it possible to bring MCU on a connection, e.g. between sensor cycles/Notification really to deep sleep?

(stopping the clock is easy, works on all SDKs and MCUs, but a real Deep Sleep without CPU andPeripheral retentained, power really off - is very tricky and potentially not implemented here, right?)

This is what the HIDoff mode is - everything power off and wake up on pre-set timer or GPIO interrupt.

If you're referring specifically to the WICED sense firmware, I am not familiar with the details of that - only of the capabilities of the 2073x processor that it uses.  The SDK definitely allows for deep sleep. My board draws around 5 uA when in this mode, vs about 40 uA when the system is in sleep / low power mode with SRAM retained.   

Anonymous
Not applicable

Thank you,

very great thoughts and info. 

0 Likes
Anonymous
Not applicable

BTW:

I think the ARM CM3 goes just to "standby mode", e.g using WFI. I would not compare power states as known from other CPUs (e.g. Intel, with P and S states) here on ARM based devices (different terms and approaches).

"Standby" : clock is off, but power still there. WFI and any interrupt can continue, all retained, including CPU states/registers. I think this mode is used here (obvious, easy and the mode which is simply controlled by CPU instructions, nothing else).

"Sleep" : clock off but power down to retention level, all remains retained (maybe not CPU registers) but all peripherals are retained, incl. SRAM (retention flops). Before CPU can continue, the power has to be increased again (needs small HW support. a power manager, CPM, MCP ...).

"Deep Sleep" : clock off and power below retention level or completely off.

Nothing kept, similar to "hybernate". But now on wakeup a reconfig of all devices is needed. I do not see such a power manager in FW. Part of SRAM might be retained where states are stored and can survive (for "hybernate"). So, a "System Deep Sleep" might be there as well where also SRAM will fade away.

"System Deep Sleep" (hybernate):

Even SRAM power is off. It needs a non-volatile memory to store, including SRAM content (e.g. global variables), or a system reboot with smart recovery states from other devices (e.g.a flash written before power down). Do we have here?

Anyway, I am still thinking the MCU is just in :"Standby" mode, still ways to improve ("just" the system latency is an issue for "Deep Sleep" to enter and wakup from).

0 Likes

Glad to help

It took me a while to figure this out as the docs are spotty but the forum support from BRCM staff has been really helpful.

For the most part, the power management (selection of sleep modes as you document) is handled automatically within the SDK's OS.  The OS will automatically go into "sleep" mode whenever there is nothing to do for the next 5+ milliseconds.  Wakeup from sleep mode takes 5 milliseconds to allow for the high frequency clock to settle (this number varies depending on whether you are using the modular package for which this is 5 mS - or your own clock design, which could be faster).  This time value is set in the CGS file as the PMU crystal warmup time:

ENTRY "PMU Crystal Warm up Time"

{

   "Crystal warm up time" = 5000       

}


In normal operation it is only out of "sleep" mode when it's receiving or transmitting on a slot, servicing a timer interrupt, GPIO interrupt, or peripheral interrupt like serial, etc.  After it's done working the OS will put it back into sleep mode.  I believe the LPO runs at 128khz, and that is always running and is the source for the RTC etc.

You can also go into a mode like deep sleep or hibernate (HIDoff) by commanding it to do so using SDK functions, with the caveats previously mentioned.

Thanks for all of the expert feedback Lewis.

Note that while documentation for this feature is limited, there are a couple of resources below that users have found useful:

Source Code: deep sleep enablement and the associated clock source handling: Source Code: deep sleep enablement and the associated clock source handling...

j.t Deep Sleep Blog: WICED Smart Video BLOG: Experts Interview - Sleep Deep_Sleep and Advertising (1st in series)