You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by will sanfilippo <wi...@runtime.io> on 2017/03/30 22:57:28 UTC

Commit of low power timer support (for nordic platforms)

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.