Skip to content
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

Conversation

mprse
Copy link
Contributor

@mprse mprse commented Dec 1, 2017

Description

  1. us ticker driver for NRF_51_DK board:
    According to new ticker standards the following requirements for us ticker are not met on NRF_5xxx boards:
  • has a frequency between 250KHz and 8MHz (currently is driven by 32kHz clock)
  • ticker increments by 1 each tick (currently is scaled to 1 MHz by incrementing counter by ~31)

Since BLE softdevice uses TIMER0 the proposition is to use high speed TIMER1 for us ticker configured as follows:

  • TIMER counter width: 16 bits (max)
  • TIMER frequency: 1MHz
    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.

  1. lp ticker driver for NRF51_DK board:
  • According to NRF51_DK reference manual rtc interrupt cannot be controlled by rtc event. In the previous implementation interrupts were enabled permanently and specific interrupt was enabled/disabled by enabling/disabling the specific event. If event is enabled, then event signal is provided to Programmable Peripheral Interconnect (PPI). If interrupt is enabled, then interrupt signal is provided to Nested Vector Interrupt Controller (NVIC). Disable all events permanently. Enable lp ticker overflow interrupt permanently(needed for RTC), disable lp ticker capture/compare interrupt on init (lp_ticker_init) , enable lp ticker interrupt when lp ticker interrupt is set (lp_ticker_set_interrupt), disable lp ticker interrupt on disable request(lp_ticker_disable_interrupt).
  • Provide lp ticker data for higher level (freq: 32kHz / len: 24 bits),
  • Add the following features to init routine: disable lp ticker interrupt.
  • Make ticker driver to operate on ticks instead of us.
  • Simplify lp ticker read and set interrupt routines (upper layers handles conversion to us and interrupt scheduling).

Status

IN DEVELOPMENT

Migrations

YES

API is not changed, but the behavior of us ticker and deep-sleep mode changes as follows:

  • us ticker is driven by Timer 1 incremented by 1 with frequency 1MHz/16 bits,
  • Timer's Capture/Compare register 0 is used to set interrupt time,
  • Timer's Capture/Compare register 1 is used to get current timer count
  • us ticker init routine disables us ticker interrupt,
  • lp ticker driver operates on ticks,
  • lp ticker init routine disables lp ticker interrupt
  • lp ticker is not scaled to 1MHz

@mprse mprse changed the title NRF_5xxx - adapt us ticker and sleep drivers to the requirements NRF_5xxx - adapt us ticker and sleep drivers to the new standards Dec 1, 2017
pan-
pan- previously requested changes Dec 1, 2017
Copy link
Member

@pan- pan- left a 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
Copy link
Member

bulislaw commented Dec 1, 2017

CC: @c1728p9 @0xc0170

@bulislaw
Copy link
Member

bulislaw commented Dec 1, 2017

@mprse that should probably go to the branch with HAL changes
@pan- any hints how to conform this board to our new HAL APIs without hurting power?

@pan-
Copy link
Member

pan- commented Dec 1, 2017

@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).

@bulislaw
Copy link
Member

bulislaw commented Dec 1, 2017

Is the accuracy of LP good enough?

@pan-
Copy link
Member

pan- commented Dec 1, 2017

The event queue works at the ms scale (1kHz); not the us scale. According to the specification lp tickers should have a reported frequency between 8KHz and 64KHz (see here).

So yes, the lp ticker should be enough for the event queue.
@c1728p9 @geky Could you confirm ?

@geky
Copy link
Contributor

geky commented Dec 1, 2017

👍 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.

@mprse
Copy link
Contributor Author

mprse commented Dec 4, 2017

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:

  1. Cut the PCB track shorting solder bridge SB9 to put P22 in series with the load.
  2. Short solder bridge SB11 (if using coin cell battery) or SB12 (if using external power supply) to
    bypass the protection diode which would otherwise give a voltage drop.

Test scenario:

- init lp, us tickers
- wait - 10 sec
- sleep - 10 sec
- deep-sleep - 10 sec

Test results:

  branch: master branch: nrf5x_use_high_speed_timer_for_us_timer
Normal operation 4 [uA] 558 [uA]
Sleep mode 4 [uA] 558 [uA]
Deep-sleep mode 4 [uA] 4 [uA]

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)?

@pan-
Copy link
Member

pan- commented Dec 4, 2017

@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.

@mprse
Copy link
Contributor Author

mprse commented Dec 4, 2017

@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.

  branch: master branch: nrf5x_use_high_speed_timer_for_us_timer
BLE beacon example (without line 84) 3.5 [mA] 4.4 [mA]

@mprse
Copy link
Contributor Author

mprse commented Dec 4, 2017

I found that typical capacity of CR2032 battery is 240 mAh, so BLE beacon example can be run on battery power:

  • 64,5 h when us ticker uses low power timer (master),
  • 53,5 h when us ticker uses high speed timer (nrf5x_use_high_speed_timer_for_us_timer).

So the difference is 11 h (performance decreased by 17%).

@pan-
Copy link
Member

pan- commented Dec 4, 2017

@mprse I'm a bit surprised by the current results; did you compile with the release profile or develop profile ?

Note that MBED_TICKLESS is enabled on the NRF51 and one of the first thing done by the RtosTimer is to enable the us_ticker.

@mprse
Copy link
Contributor Author

mprse commented Dec 4, 2017

@mprse I'm a bit surprised by the current results; did you compile with the release profile or develop profile ?

With the default profile:
mbed test -t GCC_ARM -m NRF51_DK -n tests-mbed_hal-ble --compile -v -c

@bulislaw
Copy link
Member

bulislaw commented Dec 5, 2017

@pan- what do you think?

@pan-
Copy link
Member

pan- commented Dec 5, 2017

@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.

@mprse mprse force-pushed the nrf5x_use_high_speed_timer_for_us_timer branch from 5e62b60 to 1c96df6 Compare December 6, 2017 11:49
@mprse
Copy link
Contributor Author

mprse commented Dec 7, 2017

@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 sd_softdevice_enable system call returns 4097 error code which does not tell me much. It looks like these changes have influence on BLE drivers. Maybe someone who is familiar with BLE driver can provide some hint?

@pan-
Copy link
Member

pan- commented Dec 7, 2017

@mprse The error return is NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION; it means that the softsevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.

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).

@mprse mprse force-pushed the nrf5x_use_high_speed_timer_for_us_timer branch from 1c96df6 to 2776316 Compare December 7, 2017 13:30
@mprse
Copy link
Contributor Author

mprse commented Dec 7, 2017

@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.
Unfortunately I still get the same error in the Beacon example program.

@mprse
Copy link
Contributor Author

mprse commented Dec 8, 2017

It looks like enabling TIMER0 irq (nrf_drv_common_irq_enable(TIMER0_IRQn, <priority>)) regardless of irq priority which is requested causes that BLE initialisation (sd_softdevice_enable()) fails with the NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION error code. If TIMER0 interrupt is disabled, then BLE initialisation is successful.

@pan-
Copy link
Member

pan- commented Dec 8, 2017

@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.

@mprse mprse force-pushed the nrf5x_use_high_speed_timer_for_us_timer branch from 2776316 to 29a588d Compare December 12, 2017 08:50
@mprse
Copy link
Contributor Author

mprse commented Dec 12, 2017

@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.
Updated PR description.

@mprse
Copy link
Contributor Author

mprse commented Dec 12, 2017

Current measurement results on NRF51_DK:

  wait() hal_sleep() hal_deepsleep() BLE beacon example (without line 84)
master ~4.3 [mA] ~4 [uA] ~3 [uA] ~4.5 [mA]
this branch ~4.5 [mA] ~555 [uA] ~4 [uA] ~4.5 [mA]

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:
mbed test -t GCC_ARM -m NRF51_DK -n tests-mbed_hal-ble --compile -v -c --profile release.

@bulislaw
Copy link
Member

I think that's fair enough, @pan- what do you think?

@bulislaw
Copy link
Member

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.
@mprse mprse force-pushed the nrf5x_use_high_speed_timer_for_us_timer branch from 345c8b1 to de4bcba Compare April 23, 2018 09:33
@mprse
Copy link
Contributor Author

mprse commented Apr 23, 2018

Added fix for lp ticker driver (setting interrupt - min value written to cc register must be now + 2 ticks) and re-enabled sleep support for NRF51_DK.

@mprse
Copy link
Contributor Author

mprse commented Apr 23, 2018

@0xc0170 Can we run morph after last updates?

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 23, 2018

@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).

@cmonr
Copy link
Contributor

cmonr commented Apr 23, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Apr 23, 2018

Build : SUCCESS

Build number : 1826
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5629/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Apr 24, 2018

@mbed-ci
Copy link

mbed-ci commented Apr 24, 2018

Exporter Build : FAILURE

Build number : 1470
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/exporter/5629/

@cmonr
Copy link
Contributor

cmonr commented Apr 24, 2018

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.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 24, 2018

/morph export-build

@mbed-ci
Copy link

mbed-ci commented Apr 24, 2018

@cmonr
Copy link
Contributor

cmonr commented Apr 24, 2018

@pan- @donatieng Are y'all happy with this PR?

@donatieng
Copy link
Contributor

Everything good from my point of view. @c1728p9 can you confirm you're happy with the new tolerance definitions?

@c1728p9
Copy link
Contributor

c1728p9 commented Apr 26, 2018

The tolerance definitions look good to me.

@0xc0170 0xc0170 dismissed pan-’s stale review April 27, 2018 09:56

The PR was updated

Copy link
Contributor

@donatieng donatieng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff, approved!

@0xc0170 0xc0170 merged commit 50f87a5 into ARMmbed:feature-hal-spec-ticker Apr 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet