Unusual current draw during connection using BCM20732S

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

I am seeing a very unusual current draw pattern in my application. 

I have set my connection interval to about .5 seconds to achieve low power, and the system is generally sleeping between intervals.  My application sends 4 notifications per second on average. 

When I measure the current used by the application, I can clearly see the connection times, and usually between those times the current is very low.  However, sometimes, it burns about 2mA between the two intervals.

Here are some plots showing the pattern:

unusual current draw.png

The x axis is seconds and the Y axis is microamps.  The current sampling rate is 5KHz. The baseline is close to 0; the peaks during transmit are around 25mA (this is using TX power level of 2dB).  The weird times it has a new baseline of 2mA minimum.

unusual current draw-zoom.png

Here is a zoomed in view.  You can see other stuff going on at 10Hz, and then when this weird thing happens...

unusual current draw-zoom2.png

You can see some periodicity to the observed current.

This looks a little bit similar to problems we had in the past with the PMU clock warmup time.  We have the value set to 5000 currently.

This is using the TN1337 lot code.

0 Likes
1 Solution

> I'm using SDK 1.1....Will your suggestion work for SDK 1.1?

Yes, it will, and like SDK 2.0, you don't want to go lower than about 1200.

> Some fraction of the time when I would try to enter HIDoff, it would appear to go to sleep, but instead of going down to 3 microamps, would rise to a permanent high level of 2500 microamps!!.....but it clearly goes haywire trying to get to the idle state and instead spends the time in a very BAD state.. This is eating up 10x the power it should!

The 2.5mA you see is not really a bad state. Since sleep is disabled during this interval (we will get to why in a bit below) the device is in and out of CPU active and pause. Ideally, it would be in pause, but when connected, the CPU also needs to take the bluetooth slot interrupts every 625uS and those are the smaller spikes you see on top of the ~2.5mA.

> do you think this might prevent it from getting into these failed sleep situations, or would this reduce the added cost of waking the processor up early?

This will reduce the chances of it getting into the failed sleep situations. If you zoom into the 20+ mA peak right before the failed sleep, I bet you'll see a single peak compared to two peaks in a 'good' case (one for RX and another for TX). This single peak corresponds to just the RX and the TX is missing because the device did not see the sync/preamble bits. This could happen due to a number of reasons - interference is generally the primary contributor, antenna gain (if it is not optimal), range, relative clock drift on both sides (when connection intervals are longer, the (LPO) clocks drift further apart in the time in between). The FW is designed a bit conservatively and it always assumes that a missed sync is due to larger than expected (LPO) clock drift on the device's side and so disables sleep till the next connection event (when awake/in pause, the xtal is used which is never more than ~20 ppm drift).

With the drift rate parameter of bleapputils_changeLPOSource(), what you are setting is the worst case drift of the LPO. The FW uses this to calculate the wake time and also the instant at which it should open its receive window and setting a larger drift rate will mean the receive window will be a bit larger. So the probability to getting the preamble bits is much higher.

View solution in original post

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

Update: I tried doubling the PMU time to 10000, and it might have helped.  Testing it had fewer of these problems but still happened occasionally.  But I don't know for certain that it wasn't some other factor responsible for the improvement. 

Is there an upper limit on this PMU clock setting?  What is the downside of too high a setting?

0 Likes

> I tried doubling the PMU time to 10000, and it might have helped.

I guess you mean xtal warmup time in the .cgs file.

> Is there an upper limit on this PMU clock setting?

If true, this is a 16 bit value (in uS), so the max is ~65.5mS. But....

> What is the downside of too high a setting?

This basically means the device has to program the HW to wake up so many milliseconds ahead of the scheduled time. If you want the average current to be as low as possible, this must be set to the smallest number possible for the xtal you are using. With the current S modules, we see that this needs to be ~5mS (a HW fix in the S modules which will require under 3mS is coming some time in the future); but 10mS may be a bit too much.

One other thing you could try is to use a slightly larger LPO accuracy instead. At the end of your application_create function, add:

/// Switch LPO source. Use MIA_LPO (the name of the internal LPO), allow use when master (FALSE because master needs higher accuracy), 3000 ppm drift.

bleapputils_changeLPOSource(LPO_MIA_LPO, FALSE, 3000);

See how low you can go on the drift rate parameter (to lower average current) before you start seeing this issue again. With SDK 2.0, you don't want to go lower than about 1200 ppm. With the upcoming SDK 2.1, it should be possible to go lower still (and the FW will do all this for you by default).

0 Likes

> I tried doubling the PMU time to 10000, and it might have helped.

I guess you mean xtal warmup time in the .cgs file.

Correct.  I adjusted this to 5000 from the default of 2800 previously after encountering a problem attempting to enter HIDoff mode.  Some fraction of the time when I would try to enter HIDoff, it would appear to go to sleep, but instead of going down to 3 microamps, would rise to a permanent high level of 2500 microamps!!  Not really what I was looking for.  Shawn suggested adjusting the xtal warmup and it worked (it appeared to anyway).  So I interpreted from this that this setting being too low was preventing it from going to sleep correctly, and getting it stuck in some bad state.  This seems to be exactly the same symptom as I see now with these inter-connection times.  The chip is supposed to be in an idle state waiting for the next connection interval, but it clearly goes haywire trying to get to the idle state and instead spends the time in a very BAD state.. This is eating up 10x the power it should!

But based on your explanation below I'm perplexed as to why changing this parameter would have fixed the problem before, as it seems to be more about coming out of sleep mode than going into it.

> Is there an upper limit on this PMU clock setting?

If true, this is a 16 bit value (in uS), so the max is ~65.5mS. But....

> What is the downside of too high a setting?

This basically means the device has to program the HW to wake up so many milliseconds ahead of the scheduled time. If you want the average current to be as low as possible, this must be set to the smallest number possible for the xtal you are using. With the current S modules, we see that this needs to be ~5mS (a HW fix in the S modules which will require under 3mS is coming some time in the future); but 10mS may be a bit too much.

It's odd to me that this fixed the problem before, although perhaps it has to do with internal details that I don't know about.

In my current log data I can see the system wake up about 5 milliseconds ahead of time (with the 5ms setting of the PMU), as you say.. it rises from 32 microamps to 400 microamps, stays there for 5ms, and then transmits.

If setting it to 15ms fixed the problem, for my application it would still be a huge win because running at 400 microamps for 15ms twice a second will cost half as much as a 1% chance of spending half a second at 2500 microamps.

But in any event -- i'm not sure about this solution.  Changing the PMU seems to help - but it doesn't make much sense to me.

One other thing you could try is to use a slightly larger LPO accuracy instead. At the end of your application_create function, add:

/// Switch LPO source. Use MIA_LPO (the name of the internal LPO), allow use when master (FALSE because master needs higher accuracy), 3000 ppm drift.

bleapputils_changeLPOSource(LPO_MIA_LPO, FALSE, 3000);

I am confused - do you think this might prevent it from getting into these failed sleep situations, or would this reduce the added cost of waking the processor up early?

See how low you can go on the drift rate parameter (to lower average current) before you start seeing this issue again. With SDK 2.0, you don't want to go lower than about 1200 ppm. With the upcoming SDK 2.1, it should be possible to go lower still (and the FW will do all this for you by default).

I'm using SDK 1.1, because I was under the impression that the newer ones were incompatible with the 20732S.  Is that not the case?  Will your suggestion work for SDK 1.1?

0 Likes

> I'm using SDK 1.1....Will your suggestion work for SDK 1.1?

Yes, it will, and like SDK 2.0, you don't want to go lower than about 1200.

> Some fraction of the time when I would try to enter HIDoff, it would appear to go to sleep, but instead of going down to 3 microamps, would rise to a permanent high level of 2500 microamps!!.....but it clearly goes haywire trying to get to the idle state and instead spends the time in a very BAD state.. This is eating up 10x the power it should!

The 2.5mA you see is not really a bad state. Since sleep is disabled during this interval (we will get to why in a bit below) the device is in and out of CPU active and pause. Ideally, it would be in pause, but when connected, the CPU also needs to take the bluetooth slot interrupts every 625uS and those are the smaller spikes you see on top of the ~2.5mA.

> do you think this might prevent it from getting into these failed sleep situations, or would this reduce the added cost of waking the processor up early?

This will reduce the chances of it getting into the failed sleep situations. If you zoom into the 20+ mA peak right before the failed sleep, I bet you'll see a single peak compared to two peaks in a 'good' case (one for RX and another for TX). This single peak corresponds to just the RX and the TX is missing because the device did not see the sync/preamble bits. This could happen due to a number of reasons - interference is generally the primary contributor, antenna gain (if it is not optimal), range, relative clock drift on both sides (when connection intervals are longer, the (LPO) clocks drift further apart in the time in between). The FW is designed a bit conservatively and it always assumes that a missed sync is due to larger than expected (LPO) clock drift on the device's side and so disables sleep till the next connection event (when awake/in pause, the xtal is used which is never more than ~20 ppm drift).

With the drift rate parameter of bleapputils_changeLPOSource(), what you are setting is the worst case drift of the LPO. The FW uses this to calculate the wake time and also the instant at which it should open its receive window and setting a larger drift rate will mean the receive window will be a bit larger. So the probability to getting the preamble bits is much higher.

0 Likes

AH..

Thank you so much for the explanation.  I'll give this a try and see how it goes.

I gather that the problem entering HIDoff is probably a different issue?

A somewhat related question: 

Our board has an external real time clock, and part of our manufacturing self test runs a 1 second RTC interrupt and measures the time between ticks according to the internal clock of the BCM20732S.

As a general rule one second seems to correspond to about 1024 ticks, but some boards have higher values, as high as 1064.  I am not sure which clock is right, but figured it probably was not going to make much difference for our application.  Now I wonder whether, if we assumed for the moment that the RTC was more accurate, would that level of error in the '732 clock would pose any problems like this where it performs poorly in terms of energy usage?

Unfortunately I don't have direct access to the 'bad' board as it is at our customer's site, but I might be able to get it to test.  I could determine which clock was bad in that case.

0 Likes

OK, I tested with setting the ppm to 3000, and i think it helped somewhat, but not as much as increasing the xtal warmup time.

Would it make sense to increase the parameter beyond 3000?

0 Likes

> I gather that the problem entering HIDoff is probably a different issue?

Likely to be, can you give me some more details if you have any?

> ...and measures the time between ticks according to the internal clock of the BCM20732S.

Are you generating an interrupt from the external RTC and then taking a snapshot of a clock? Which internal clock? 1024 ticks/second is almost a millisecond timer and as far as I recall, there is no timer that ticks at ~1mS.

> OK, I tested with setting the ppm to 3000, and i think it helped somewhat, but not as much as increasing the xtal warmup time. Would it make sense to increase the parameter beyond 3000?

Probably not. You could go up to say 5000, but the worst case drift of the internal LPO we have see is ~4000 ppm, and this only at very high temperatures and on specific test chips. Chips that ship are nominal parts and these should have about 1200 worst case.

0 Likes

> I gather that the problem entering HIDoff is probably a different issue?

Likely to be, can you give me some more details if you have any?

I referred to it above but I had observed that sometimes when trying to enter HIDoff, it would fail to go to sleep and stick in the 2.5mA mode.  The solution was to increase the xtal warmup time from 2800 to 5000.  In both cases the system failed to go to sleep I guess.  As far as I can tell this problem has been fixed.

EDIT: Actually I looked back in my notes and the HIDoff problem was due to a race condition having to do with using P0 for GPIO - apparently there was a problem with some internal 'keyscan' driver.  This would cause the sleep to fail going into HIDoff.  The fix was not related to the xtal warm up time.

> ...and measures the time between ticks according to the internal clock of the BCM20732S.

Are you generating an interrupt from the external RTC and then taking a snapshot of a clock? Which internal clock? 1024 ticks/second is almost a millisecond timer and as far as I recall, there is no timer that ticks at ~1mS.

Correct - when i handle the interrupt I read the "rtc" using rtc_getRTCRawClock();

This seems to tick at roughly 128Khz; I shift right by 7 to get 1/1024ths

> OK, I tested with setting the ppm to 3000, and i think it helped somewhat, but not as much as increasing the xtal warmup time. Would it make sense to increase the parameter beyond 3000?

Probably not. You could go up to say 5000, but the worst case drift of the internal LPO we have see is ~4000 ppm, and this only at very high temperatures and on specific test chips. Chips that ship are nominal parts and these should have about 1200 worst case.

So, is there any way to cut down on the cost of these cases where it fails to go to sleep?

As things stand it's raising the overall power cost by a factor of 10, and mostly eliminating the benefit of a slow connection interval, because the times when this fails are so expensive (whereas with a faster connect rate it 'recovers' sooner.  Is there a way to always sleep?

0 Likes

I've kind of concluded that this is caused by interference and there is no

way to do anything about it.

However it would be really useful to know when/how often this happens. Is

there any way to detect it or be notified or her a count of occurrence?

This way we can better understand how much power is used from our battery.

0 Likes

There is no app visible count of the occurrence of these with SDK 1.x and 2.0. With SDK 2.1, these higher current occurrences should be fewer and unfortunately, we cannot patch a similar change into 1.x because the 20732 firmware is a bit different in this regard.

0 Likes

Glad to hear this is improved in later versions of the chip.  For this production run we can't change at this stage but we will try using the '736 in future revisions.

I also found a work-around to detect when this happens.  I have a fine timer set at 50ms, which fires very infrequently when the system is using long connection intervals.  (i.e. average of 2x per second).  If the rate suddenly increases then I know that the sleep is suspended.