Hello:

Low power timer support for the nordic platforms (both nrf51 and nrf52) was 
just committed to develop. Here is a basic explanation of the changes and how 
to turn it on/off. Note that while a reasonable amount of testing was done on 
this code a bit more needs to be done to verify that the timing is correct. 
Next step is to do some current consumption profiling for 
advertising/scanning/connections so that we can fine tune the code.

The basics:

The nordic chips support two basic timers: RTC timers and non-RTC timers (which 
I will simply to refer to as timers hereafter). The RTC timers are lower power 
than timers so it desirable to use them instead of the other timers in the 
chip. The initial controller version used a timer set to count at 1MHz. This 
was done because it made the code quite simple to convert bluetooth timing to 
timer ticks (microseconds to ticks and ticks to microseconds was a no-op). The 
RTC timers only count at 32.768 kHz (well, I guess you could put a different 
crystal but typically 32.768 kHz crystals are used). Another change associated 
with the low power timer code is to turn on the HFXO (high-frequency crystal 
oscillator) only when needed. Actually, this gives you the largest current 
consumption gain as the difference between a RTC timer and timer is about 10uA 
and the HFXO is about 250 uA (if I am recalling the chip specification 
correctly).

A note about the usecs to ticks conversion routine:

The routine I decided to use is one where there is no need to do a divide. This 
is not perfectly accurate however and can be off by 1 full tick for certain 
values as the code does not add in the residual to correct for this. The 
routine takes about 10usecs on the nrf51 and if you add the residual it takes 
16 usecs. This routine calculates a “floor” value, so if you care about the 
remainder you can either modify the routine to get that remainder or you can 
convert back to microseconds and subtract it from the microsecond value you 
converted into ticks. The controller does this for connection event timing as 
it needs to be more accurate than one 32.768 tick. After adding this code I 
have been debating having two different routines (one that is faster and one 
that is more exact) but for now there is only the one routine. And btw, the 
routine to do it exactly takes a long time on the nrf51 and based on how the 
controller was written there was not enough time to use the more exact routine 
(the controller needs to do things within the 150 usec IFS time).

How to enable/disable:

We decided to add the code in such a manner that the old way of doing things is 
still in the code. This allows the least amount of disruption while also 
allowing folks to give this code a spin. To enable the code you will need to do 
set the following syscfg variables. Note that you can do this in your target or 
BSP:

1) Set the crystal frequency to 32768.
OS_CPUTIME_FREQ: 32768

2) Set the crystal setting time. This is going to be crystal/board dependent 
and is something you will have to characterize for your product. I need to do a 
bit more research to get the correct number to use for the nordic development 
kits. I chose 1500 usecs (1.5 msecs) as the default. This number cannot be zero!
BLE_XTAL_SETTLE_TIME: 1500

3) Change the timer used for CPUTIME, disable the old timer and enable the RTC 
timer

NRF52:
OS_CPUTIME_TIMER_NUM: 5
TIMER_0: 0
TIMER_5: 1

NRF51:
OS_CPUTIME_TIMER_NUM: 3
TIMER_0: 0
TIMER_3: 1

Here are some sample target excerpts:

Sample nrf51 target:
syscfg.vals:
    BLE_XTAL_SETTLE_TIME: 1500
    OS_CPUTIME_FREQ: 32768
    OS_CPUTIME_TIMER_NUM: 3
    TIMER_0: 0
    TIMER_3: 1

Sample nrf52 target:
 syscfg.vals:
   BLE_XTAL_SETTLE_TIME: 1500
   OS_CPUTIME_FREQ: 32768
   OS_CPUTIME_TIMER_NUM: 5
   TIMER_0: 0
   TIMER_5: 1

Further improvements:
1) The nordic chips allow for a faster RXEN/TXEN time. This was not added to 
this version of code but could be added in the future to improve power 
consumption.
2) The old code which uses 1 usec timing could also include the code to turn 
on/off the HFXO. This was not added as we wanted to keep the old code 
unchanged. The basic idea here is this though: if you want more accurate timing 
and you have a device that is not battery operated, you are better off using 
the 1MHz timer. I think this makes for a smaller code footprint as well 
although I have not characterized this.
3) Determine the actual settling time on the development boards.

Comments/suggestions are always welcome.


Reply via email to