nRF5340, enter low-power/sleep while timer enabled

I'm working on optimizing power consumption in my project (using nRF5340DK; as well as Power Profiler Kit 2 which is connected to DK's VDD measurement point as an ampere meter). After trial and error, I've narrowed down the timer (set up similarly to the timer example at NCS v2.5.0, modules/hal/nordic/nrfx/samples/src/nrfx_timer/timer/) as having the biggest impact towards power. When initializing the timer, I got an average current draw of almost 1mA; when it's not initialized, I see about 0.2mA.

Several questions:

  1. Is it expected to see that amount of additional current draw due to just simply setting up the timer?
  2. What are my options for bringing the current down as low as possible, while still being able to have the timer running?
    1. It appears possible when I was using k_sleep() in my main loop, as mentioned here. Though this seems to put the thread to sleep, but not the CPU.
    2. But I just recently discovered using sys_poweroff() as mentioned in this sample, which seems to put the entire CPU to sleep if I'm not mistaken. I'm investigating at the moment on my end too but I'm not sure if the timer can be used to wake the CPU back up.
  3. Are there any other methods of setting up timers that lend itself better to low power applications?

I'd appreciate any feedback for this. Thank you!

  • Hi, 
    The TIMER requires the 32MHz oscillator to run and that's the main reason you are seeing higher current draw. 
    Do you have a reason why you want to keep a TIMER running ? If you simply want to keeping the time and doesn't have high requirement on the accuracy you should use the RTC instead. It draws much less current. The k_sleep() function in Zephyr also use RTC. 
    When you call k_sleep() and when you don't have any other task running you should see about 2-4 uA current consumption (not 0.2mA) 
    Could you try to test with the periphreal_lbs sample (use prj_minimal.conf) and measure the current consumption with the PPK2 ? 

  • We are using the timer to read data w/ SPI as quickly as every 0.5ms, so the accuracy is a high requirement.

    I will try out the k_sleep() in a separate project momentarily. The 0.2mA I measured is from my project, which hasn't been fully optimized yet.

    I tested that LBS sample (NCS v2.5.0, nrf/samples/bluetooth/peripheral_lbs/) and got about 461uA when sleeping, with roughly 5mA spikes every 100ms.

  • Hi, 
    Have you made sure you use the prj_minimal.conf when testing with lbs ? 
    Please send us your PPK2 log. You should see only about 2-4uA sleeping with lbs minimal configuration. 

    If you need a timer for event every 0.5ms I don't see a problem with RTC. If you have a 32kHz crystal, the accuracy can be 20ppm , meaning you have a tolerance of 0.00001ms. Or if you use RC the accuracy is 500ppm, it will be 0.00025ms. 
    But instead of  using k_sleep you should set up a timer  . It will use the RTC. 

  • I am fairly confident that I'm using prj_minimal.conf. For context, I use VS Code; when adding the build configuration I select board target as 'nrf5340dk_nrf5340_cpuapp' and base configuration files as 'prj_minimal.conf'.

    I've attached the PPK2 log; before log started, board was already flashed with firmware and I have not done anything with it i.e., I haven't connected to it using nRF Connect for Mobile.

    ppk2_log_verbose_2024-10-14T21_13_10.988Z-log.txt

    We were originally more worried about the resolution of 30us, rather than the accuracy. But, after discussing with my team, that may be fine.

    A timer like that would be great. We'll take a look; thanks!

  • Hi, 
    How did you use the PPK2 ? If you us the nRF Connect for Desktop -> Power profile app, you can click Save/export and save a .ppk2 file. 

    I assume you are measuring the current consumption on a DK ? Please let us know how did you do that, did you cut SB40. 

    Also, since you are measuring on the nRF53, please pay extra extension that you should turn off UART log on the network core. 
    you should set CONFIG_SERIAL=n on the child image project configuration. I think that's most likely the reason why you see high current consumption with lbs minimal project. 

Related