New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NRF_51_DK - adapt lp/us ticker drivers to the new standards #5629
NRF_51_DK - adapt lp/us ticker drivers to the new standards #5629
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change looks good however it will have a massive impact on power consumption: The timer will stay on during sleep for BLE applications because they generally use the event queue which internally use a Timer object.
On NRF52, the Internal HFCLK consume 60uA while the external one consume 250uA; on top of that power consumption of the timer peripheral must be added: 5uA @ 1MHz.
On NRF52 power consumption during sleep is less than 6uA; if this patch is applied the result would be a power consumption an order of magnitude higher during sleep. That is not acceptable for battery powered devices.
Could you investigate the impact on power consumption of this patch ?
@bulislaw I think the situation could be better if the event queue used a Timer object with an lp_ticker rather than the a us_ticker (note that this trap is not documented in the header, the default constructor documentation is empty). |
Is the accuracy of LP good enough? |
👍 Yep, 1ms resolution is all that's needed, we just haven't defaulted to LowPowerTickers since it's not clearly defined what resolution garuntees there are. |
Power consumption tests were performed on NRF51_DK board (battery powered). Board has been modified according to the NRF51_DK user guide (chapter 6.7.1 - link) as follows:
Test scenario:
Test results:
I have additionally checked power consumption before us ticker init routine is called and it was equal to 558 [uA]. I'm a little confused, how this is possible (us ticker should be disabled before init)? |
@mprse Thank you for the analysis, that is really helpful. Could you do the power analysis with a BLE application like the BLE beacon example ? To avoid initialization of the UART peripheral, please remove line 84. |
|
I found that typical capacity of CR2032 battery is 240 mAh, so
So the difference is 11 h (performance decreased by 17%). |
With the default profile: |
@pan- what do you think? |
@bulislaw @mprse I'm really surprised by the numbers. On The NRF52; if I disable the trace that print the MAC address and compile with the release profile then the power consumption of the Beacon example is very low with master: ~20uA. The Beacon example doesn't work, on NRF52, with that PR however. |
5e62b60
to
1c96df6
Compare
@pan- I noticed that the Beacon example doesn't work on NRF51 on this branch neither, so the provided power consumption tests are invalid. The Beacon example generates exception during BLE initialisation in the following line. I observed that |
@mprse The error return is In our case it is an illegal priority level of the us_ticker IRQ. Please use the lowest priority for the us ticker interrupt (see lp_ticker). |
1c96df6
to
2776316
Compare
@pan- Thanks for the provided explanation of the problem. I have provided a fix to us_ticker_init routine in order to enable TIMER0 irq with the lowest priority. |
It looks like enabling TIMER0 irq ( |
@mprse Looking at the product specification of the softdevice, TIMER0 is used by the softdevice and shouldn't be used by application code while the softdevice is active. TIMER1 and TIMER2 are free however. My comment on priority stands. |
2776316
to
29a588d
Compare
@pan- Thanks. This was the problem. I used TIMER1 instead of TIMER0 and Beacon example runs now on NRF51_DK board. Unfortunately TIMER1 and TIMER2 are 8 or 16 bits wide, so I had to slightly modify us ticker driver. In current version us ticker has 16 bits and its frequency is 250 KHz. Checked that HAL tests for for us/lp ticker and sleep passes on this branch. |
Current measurement results on NRF51_DK:
It looks like the results are very close. Main difference is between sleep mode on both branches. This is because on master sleep and deep-sleep modes are the same and high frequency timer is not used for us ticker. On this branch in sleep mode high frequency timer - TIMER1 counts, but in deep-sleep mode TIMER1 is stopped. BLE beacon example has been compiled using the following command: |
I think that's fair enough, @pan- what do you think? |
That should be on the new ticker hal api branch I think. |
Since this change concerns new ticker driver for NRF51_DK it goas on ticker feature branch. On master NRF51_DK Ticker driver uses 32kHz RTC for lp and us ticker. Test uses us ticker to measure lp ticker interrupt scheduling (LowPowerTicker.attach), but since the same hardware is used for both tickers the measurement error is constant. On this branch us ticker uses 1 MHz higher precision clock and the results are different - measurement error grows linearly and shows inaccuracy of the RTC. Test implements constant delta for measured time equal to 2000 us. Change delta so it depends on lp ticker tested timeout value: 500us for measurement inaccuracy + 5% tolerance for LowPowerTicker
Since this change concerns new ticker driver for NRF51_DK it goas on ticker feature branch. On this branch us ticker is based on 1 MHz higher precision counter (on master is based on 32kHz RTC). As a result of using higher precision counter measurement error increased: :485::FAIL: Expected 1.060000 Was 1.070478 For delay 1060 ms we measured ~1070 ms so we have about ~1% measurement error which is not bed for this board. To make it work with 1MHz us ticker increase test tolerance. Define tolerance as follows: tolerance = 500us + 0.02 * delay.
For NR51_DK US_TICKER_OV_LIMIT needs to be increased since if test is run few times in row sometimes fails. This is because NR51_DK is a slow board (16 MHz) with fast and short us ticker counter 1 MHz/16 bits.
345c8b1
to
de4bcba
Compare
Added fix for lp ticker driver (setting interrupt - min value written to cc register must be |
@0xc0170 Can we run morph after last updates? |
Will label this as needs: CI (still howeve waiting for all request changes to approved!). At the moment , release candidate is under test (+ one fix that needs to get in there). |
/morph build |
Build : SUCCESSBuild number : 1826 Triggering tests/morph test |
Test : SUCCESSBuild number : 1632 |
Exporter Build : FAILUREBuild number : 1470 |
Going on a hunch that a Jenkins machine left too soon. Will leave for @0xc0170 to confirm and restart, since the build artifacts contain more than just the usual PASS directory. |
/morph export-build |
Exporter Build : SUCCESSBuild number : 1478 |
@pan- @donatieng Are y'all happy with this PR? |
Everything good from my point of view. @c1728p9 can you confirm you're happy with the new tolerance definitions? |
The tolerance definitions look good to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff, approved!
Description
According to new ticker standards the following requirements for us ticker are not met on NRF_5xxx boards:
Since BLE softdevice uses TIMER0 the proposition is to use high speed TIMER1 for us ticker configured as follows:
This solution also uses Timer's capture/compare register 0 to specify interrupt time and Timer's capture/compare register 1 to read current timer value.
2. sleep/deep-sleep driver for NRF_5xxx boards: According to new sleep mode standards the following requirement is not met on NRF_5xxx boards: - High-speed clocks are turned off in deep-sleep mode. Additionally when ticker resolution is 31 us, then it is hard to verify that wake-up time does not exceeds 10 us (fix for us ticker solve this problem).The proposition is to stop timer used by us ticker before going to deep-sleep and enable it after wake-up. This operation should result in disabling Timer clock sources in deep-sleep mode.
According to documentation:
If the system does not require any of the clocks provided by the HFCLK clock controller, the HFCLK
controller may enter a power saving mode automatically and switch off the selected clock source. This
occurs if all peripherals that require either PCLK1M, PCLK16M are appropriately stopped or disabled, and
the CPU is sleeping and thereby no longer requesting HCLK.
Status
IN DEVELOPMENT
Migrations
YES
API is not changed, but the behavior of us ticker and deep-sleep mode changes as follows: