apache / mynewt-core

An OS to build, deploy and securely manage billions of devices
https://mynewt.apache.org/
Apache License 2.0
813 stars 365 forks source link

Low power with nRF52 #2393

Open danielkucera opened 3 years ago

danielkucera commented 3 years ago

Hi,

I'm tuning the low power consumption with nRF52832. I was able to get to 170uA in System On mode with no modifications to mynewt-core.

But to get to 1.9uA I had to add following patch:

diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c b/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
index bca24c440..10bc94967 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
@@ -154,6 +154,7 @@ os_tick_idle(os_time_t ticks)
         nrf52_os_tick_set_ocmp(ocmp);
     }

+    NRF_CLOCK->TASKS_HFCLKSTOP = 1;
     __DSB();
     __WFI();

AFAIK, HFCLK is managed by softdevice but since mynewt is not using it, it has to manage HFCLK by itself.

Would you consider adding this to the codebase or is there something I am missing?

andrzej-kaczmarek commented 3 years ago

there's nrf52_clock_hfxo_request function which is used to start HFXO and refcount its users, so it may be just that some code requested HFXO but did not release it. for sure you should not stop it as above.

danielkucera commented 3 years ago

In whole mynewt-core there is not a single call to nrf52_clock_hfxo_request or nrf52_clock_hfxo_release. Am I missing something?

danielkucera commented 3 years ago

Okay, I've put

NRF_CLOCK->TASKS_HFCLKSTOP = 1;

into my app main() and it has the same effect - power usage drops. Is it possible that it's on by default or enabled during mcuboot? Should it be handled in SystemInit() ?

andrzej-kaczmarek commented 3 years ago

I recall two other places where HFXO can be started:

So in case mcuboot uses some timer, then it is possible that such timer started HFXO and it is not stopped. In such case I guess it would be reasonable to explicitly stop HFXO in hal_system_clock_start - so you can check if this helps and if so, patches are welcome :)

danielkucera commented 3 years ago

following seems to fix the issue with latest master

diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_system.c b/hw/mcu/nordic/nrf52xxx/src/hal_system.c
index bc390883b..8157e092d 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_system.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_system.c
@@ -69,6 +69,7 @@ hal_debugger_connected(void)
 void
 hal_system_clock_start(void)
 {
+    NRF_CLOCK->TASKS_HFCLKSTOP=1;
 #if MYNEWT_VAL(MCU_LFCLK_SOURCE)
     uint32_t regmsk;
     uint32_t regval;
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_timer.c b/hw/mcu/nordic/nrf52xxx/src/hal_timer.c
index b3730f0e5..5ae77adcf 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_timer.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_timer.c
@@ -652,6 +652,7 @@ hal_timer_config(int timer_num, uint32_t freq_hz)

 #if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFXO)
     /* Make sure HFXO is started */
+    /*
     if ((NRF_CLOCK->HFCLKSTAT &
          (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) !=
         (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) {
@@ -663,6 +664,7 @@ hal_timer_config(int timer_num, uint32_t freq_hz)
             }
         }
     }
+    */
 #endif
     hwtimer = bsptimer->tmr_reg;
ncasaril commented 3 years ago

I may have been a bit too quick to tag this issue in my PR. Whilst it's relevant, I suspect that this issue has a haltimer enabled in the bootloader which in turn enables the HFXO before the main application starts. I.e. check what TIMER* are set to one for the bootloader.

manuhrao commented 3 years ago

Hi,

I'm tuning the low power consumption with nRF52832. I was able to get to 170uA in System On mode with no modifications to mynewt-core.

But to get to 1.9uA I had to add following patch:

@danielkucera , I have a favor to ask. I have a project defined with no purpose other than to test low power in system on, and I am unable to drop below 480uA.( I already have the HCLK off, automatically, which frankly I can't explain given your findings). Are you able to share your project (or at least the syscfg.yml and the pkg.yml, along with the functions that put you in the lowest power state? Much appreciated. manu@culvertengineering.com

danielkucera commented 3 years ago

This is my test app for sleep: https://github.com/danielkucera/mynewt-blinky-sleep-nrf52 I was able to achieve ~2uA in sleep.

navan93 commented 3 years ago

Hi,

I am facing a strange issue of periodic increase in power consumption. I have a custom board based on NRF52811 and to test the sleep current I have configured a basic app without any additional tasks, with the bare minimum main function.

Initially after power up the current is ~3uA , which is acceptable.It stays like this for ~2mins before the current increases to ~300uA which again stays for another 2 mins before returning back to a consumption of ~3uA. Is there some periodic maintenance in the OS itself which is causing this?

Any help is appreciated.

UPDATE: This was a PCB issue and not a software one.

sjanc commented 2 years ago

is this stil an issue?