Turning off the timers in BCM20736S

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

For my application, I have an external RTC interrupt that I used to generate my own timing interrupts when desired.

Since I am using this, I have tried to turn off the fine and coarse timers in my application.

I did this by simply not calling the functions to set them up:

bleprofile_regTimerCb(tm_fine_timer_cb, tm_coarse_timer_cb);

and

  bleprofile_StartTimer();

the 'fine timer' value in the ble_profile_cfg structure is 1024.

Although I am not getting any callbacks (since I did not register them), when looking at the current over time I suspect that there is still a wakeup happening, that is separate from my own RTC interrupt and from other things like beacons being transmitted. The spikes only occur when the radio is active (i.e. when advertising or connected).

The following plots show the spikes.  In this plot, the RTC interrupts are marked with red arrows.  The tall blue spikes are advertisement beacons being sent (the device began advertising around 7 seconds in this plot).  The green spikes are the extra spikes I would like to get rid of, that I think might be timer wake ups.  (NOTE: the large DC offset after start of advertising can be ignored - it is caused by an LED running)

This plot is a zoom of the above showing the area near the second pair of arrows.

NOTE also in the first small spike above you can see the RTC interrupt line pull against the GPIO internal pull-up, where there is some slightly higher current draw before the clock turns on (the clock is the 400uA draw before the spike).  There is no equivalent draw in the second spike - i don't think this event is triggered by an external interrupt:

Is there anything else I need to do to prevent the application timers from firing and waking up the system?  This did not happen in the 20732 because the application timers in that version never woke up the system -- they would implicitly synchronize with the beacons or other activity.  Or is there something else that is likely to be happening that wasn't in the 20732?  When a connection is active I register for connection event notifications, but I don't think that should be causing this because it should be de-registered.

I don't know what is causing them, but I do know that the application is quite similar to the version on the 20732, but on the 20736 I get these extra spikes that don't happen on the 20732. This causes a 50% increase in power cost during advertisement.

santol

1 Solution
Anonymous
Not applicable

Hello santol and ldgirod

The 20732 and 20736 should behave in the same fashion.

pastedImage_0.png

The Red portion is the Wakeup.

At the end of your app_create(), do this:

 

int id  = emconinfo_getAppTimerId();

if ( id >= 0 )

        {

            // we are going to stop the timer.

            bleapptimer_stopAppTimer( id );

        }

 

Thanks

JT

View solution in original post

13 Replies
Anonymous
Not applicable

Hello santol and ldgirod

The 20732 and 20736 should behave in the same fashion.

pastedImage_0.png

The Red portion is the Wakeup.

At the end of your app_create(), do this:

 

int id  = emconinfo_getAppTimerId();

if ( id >= 0 )

        {

            // we are going to stop the timer.

            bleapptimer_stopAppTimer( id );

        }

 

Thanks

JT

santol j.t arvinds victorz

Thanks for the suggestion.. it does not really solve the problem, but I think I have been able to figure out what is going on. This situation is indeed worse in the 20736 vs. the 20732 as I explain in detail below. I think this could be fixed by making some changes to the way some of the bleapp features are implemented.

First your suggestion:

At the end of your app_create(), do this:

 

int id  = emconinfo_getAppTimerId();

if ( id >= 0 )

        {

            // we are going to stop the timer.

            bleapptimer_stopAppTimer( id );

        }

This solution works, in principle, but in practice this turns out not to be a good solution.

The issue is why the timer was running -- recall that the timer wake ups were not happening when my app first started running, because I had timers off already (and turning them off again at the end of the create() function won't make any difference). The timer wakeup did not appear until after I started advertising -- and this I gather is because inside the bleapp library it's using bleapptimer to decide when to change or stop the advertisement. 

This would mean that the only way to turn off that wakeup would be to stop the timers later, after I start advertising. But then I would need to implement my own functionality to stop the advertisements, etc.  I tested this, and this code snippet will indeed turn off the timer after I start advertising, but then the advertisements never time out. 

The bottom line is that the bleapp library uses application timers in various ways to provide its functionality and it's not going to be a good solution to try to stop them all.

The 20732 and 20736 should behave in the same fashion.

Perhaps they should, but when it comes to timers I have discovered that they do not, see the related thread here

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

In this particular instance, the behavior of 20732 was probably better.

In SDK 1.x, timers are much more likely to be synchronized with an previously scheduled wakeup, even if the timing of the wakeup is not really very close to the requested timing.  Fine timers do not fire at all when there are no otherwise scheduled wake ups. So, in SDK 1.x, if you are advertising or connected, the coarse timer will fire when the device wakes up anyway to transmit or receive, and fine timers may sometimes fire as well.

In SDK 2.x, timers have a higher priority and they will wake up the system to fire at more or less the correct time, and fine timers also always fire.  However, this means that the application coarse timer will wake up the system in many cases where in 1.x it did not.  In some of these cases precise timing is not necessary and not worth the wake ups --  and advertisement shutoff is probably a case where it's not worth it.

The following two plots show the distinction; the first is a plot of hello sensor running on the 20732 and the second is of hello sensor running on the 20736.  You can see that in the first case, the coarse timer is synchronized with the advertisement transmits (and thus is not visible), whereas in the second case, it is not synchronized and shows up as a separate spike.  You also can see that the advertisements are not even close to the same frequency as the coarse timer 'should' be (i.e. they are not very close to multiples of 1 second) but the coarse timer still does not fire; but in the 20736 the coarse timer is coming in very close to 1Hz.

As discussed in the referenced thread, this could be considered a bug or a feature.  It is definitely going to cost more power to beacon in the new SDK, and it's not really practical to turn this timer off because it's used by parts of the bleapp library, in particular for the advertisement timers.  Switching the implementation inside the SDK to avoid these extra wake ups might be useful -- it's going to be impossible for an app developer to work around this.  A possible solution would be to provide some kind of opportunistic wakeup (like the callback on connection interval) and then implement functions like advertisement shutoff timers and connection idle timers etc. using that facility, since these functions do not need precise timing to work correctly.

On the other hand, for my application I had resorted to using an external RTC interrupt to time things for precisely the reason that the coarse timers did not keep time well, and so in my case I can simply stop using that external RTC interrupt, and pay no additional overhead relative to my application on the 20732.

0 Likes

I checked with the developers and they explained that one potential solution would be to provide some kind of opportunistic wakeup (like the callback on connection interval) and then implement functions like advertisement shutoff timers and connection idle timers etc. using that facility, since these functions do not need precise timing to work correctly.

They believe that this already exists within additional_advertisement_control.h, bleprofile_notifyAdvPacketTransmissions().

Apparently, if you already know the adv interval, then you can count the number of times the registered callback is invoked and then disable adv when done.

santol j.t

0 Likes

They believe that this already exists within additional_advertisement_control.h, bleprofile_notifyAdvPacketTransmissions().

Yes, I noticed this after writing my previous response.  This would probably work to implement what I had in mind, although IMO it is still worth considering patching the library, as most users would probably want this behavior.

0 Likes
Anonymous
Not applicable

Hi, ldgirod,

You mentioned that "The timer wakeup did not appear until after I started advertising".

But my observation is that the fine timer will always fires even i did not start the adv and call bleprofile_KillTimer().

[20736]Fine timer fires during sleep ?

Have you ever met this?

0 Likes

You mentioned that "The timer wakeup did not appear until after I started advertising".

But my observation is that the fine timer will always fires even i did not start the adv and call bleprofile_KillTimer().

Yes, I have seen this too.  The only way I've found to stop the fine timer from firing is to set the duration to 1000 and also never call

  bleprofile_regTimerCb()

It may still work to call regTimerCb() if you are interested in running the coarse timer, but unfortunately setting the rate to 1000 makes it impossible to know whether or not the fine timer is actually firing, if the coarse timer is going.  It is probably better to use the bleapptimer_* API to get a coarse timer if you do not want the fine timer, because I could find no way to shut it off.

What I wanted to be able to do in my app is to turn the fine timer on and off using bleapptimer_startFineTimer() and stopFineTimer() but as far as I can tell, after staring it, the timer runs even if you call the stop function.   It's possible that calling start again with a long duration would work -- I spent a bunch of time trying different things and basically gave up on the fine and coarse timers entirely and used the bluetooth clock timer interface instead, which seems to work reliably.  That's an optional library:

  Wiced-Smart/tier2/brcm/libraries/inc/bt_clock_based_timer.h

You also have to add the corresponding .a to the build to link it in.

The only possible disadvantage to that is it may consume slightly more power, my app appeared to be using about 5 more uA on average during advertisement and connection, but I'm not 100% sure if this is the cause.

UPDATE: I now believe the extra 5uA was due to having the serial port connected for tracing.

If you want to do an experiment with the fine timers, you might try calling bleapptimer_start() with a longer duration and see whether that stops them.. that was something that occurred to me might work but I never tried it.  I thought it might work because setting the default rate to 1000 seemed to allow them to shut down.  I suppose setting it to a very long duration would at least reduce the overhead of the timer firing as well, even if it did not shut them down.

Anonymous
Not applicable

thanks for your detailed explanation:-)

Unfortunately, when i changed the fine timer interval to 1000ms and also call bleprofile_KillTimer(), i still can see current spikes with 1000ms interval. Below is the setting based on hello sensor app:

1, fine_timer_interval = 1000

2, call KillTimer(0 and comment out regTimerCb() and StartTimer()

    bleprofile_KillTimer();

//    bleprofile_regTimerCb(hello_sensor_fine_timeout, hello_sensor_timeout);

//    bleprofile_StartTimer();

3, Comment out bleprofile_Discoverable()

Even i set the fine_timer_interval to 2000, i got the same result. So, the max acceptable value is 1000ms~~

thanks.

current_spikes.PNG

0 Likes

Roger -

Thanks for trying that.. too bad it does not work!

Sounds to me like the fine timer just doesn't work the way it is supposed to.

I would recommend using the bt clock - please follow up if you have any trouble - it should be straightforward to use.

It's been working fine for me.

Anonymous
Not applicable

I can verify that the current consumption using the fine timer is dramatically higher than with the bt_clock_timer.  The fine timer keeps firing even when it is supposedly 'killed'. 

I am using it to drive a state machine for my spi interface @ 12.5ms and am measuring more than 500uA difference between the timers (they are only enabled when SPI is active).  This is on a 20736, SDK 2.1 and adv @ 1s with no connection active.  With the bt_clock_timer, my sleep current is now much, much closer to my HIDOff current.


With the bt_clock_timer, my sleep current is now much, much closer to my HIDOff current.

Just for reference, my system's sleep current is around 50 uA while hidOFF current is 4.5 uA.  1Hz advertisement is an average current draw of about 100uA

Each timer wakeup consumes about 9 uAS so multiply that by Hz to get the current load due to wakeup.  If the timer is at 12.5ms I would expect approximately 720 uA from running that timer.  I have not noticed a big difference in the wakeup cost with bt clock timers (when they are running) but the fact that fine timers can't be turned off is a non-starter ...

Are these numbers consistent with your observations?

Note that my numbers are from the 20736S module, for which the built in crystal takes longer to stabilize, which contributes about 3uAS to the wakeup cost.  For the non-modular version, this would come out to 480 uA on top of 50uA sleep cost for the 12.5ms timer.

Anonymous
Not applicable

I haven't fully debugged our board for power so I can't give you hard numbers for the BCM side of things (we have another micro that's running the show).  I'm just eyeballing the DMM for my numbers and your calculations match my expectations and observations.

For comparisons sake, I was seeing an average draw of 1.3mA when using the fine timer and am down to .45mA with the bt_clock_timer.  My HIDOff current is .38 mA(ish).  I know for low power that's a huge difference but at least I'm in the ballpark now.

Anonymous
Not applicable

hi, ldgirod,

I'll try to use bt clock instead.

I just want to stop fine time since i don't need it if i use bt clock.

But the current problem is that i even can not stop it after many tries.

Neither killtimer or StopFineTimer will actually stop it.

0 Likes

Yes.. I found that the only way was to not start it by not calling regTimerCb() or StartTimers(). 

It appears you can still use bleapptimer_startAppTimer() if you need a coarse timer callback, and this does not start the fine timer