nRF5340 high sleep current with short-duration sleep

I'm looking into the power consumption of our code, and have reached the point where it looks like our application isn't going into sleep mode properly, and is using several hundred microamps more power than it should be.

We want to sample from the SAADC every millisecond, but in testing our board, I've been running some sample code instead. The most basic example is just a while loop that sleeps for 1 ms.

In this case, doing nothing but sleeping in a loop, our board is drawing 671 uA. If I increase the sleep duration to 5 ms then it's drawing 200 uA. If it sleeps for 1000 ms it's drawing something like 23 uA.

I guess some current overhead is expected when waking more frequently, but profiling the current using an otii it looks like the 1ms sleep code doesn't ever drop below about 650 uA. Whereas for longer sleep durations I can see the current drop much lower.

So, my question is - how long does it take the nRF5340 to go into sleep mode? If it's > 1 ms then that would explain what I'm seeing - the chip never gets to sleep as it wakes up before it can turn off the HF clock. If so, is there any way to make it enter sleep faster?

Alternatively, I guess it could be the otii - it's sampling at 4 kHz, so maybe that's just not enough to catch the drop in power in sleep mode.

  • Ignoring all the PPI and SAADC stuff for the moment - this is just a while loop with a k_msleep for 1 millisecond. 

    Is this keeping the HF clock on all the time? Or is my current profiling out somehow?

    I've been using an otii sampling at 4 kHz so it's possible it's smoothing out the current and what looks like a small oscillation around 650 uA is actually a spike up to ~4 mA when the CPU turns on, and a dip down to 20 uA the rest of the time.

    So, when I call k_msleep, how quickly does the CPU turn off, and how quickly does the HF clock turn off?

  • Rory Morrison said:

    Ignoring all the PPI and SAADC stuff for the moment - this is just a while loop with a k_msleep for 1 millisecond. 

    Is this keeping the HF clock on all the time? Or is my current profiling out somehow?

    Just for good measure, could you detail your setup? How is everything connected to your kit?
    For good measure, we've also got this Power Measuring guide for the nRF5340 DK that could be useful to reference in regards to the setup.

    Rory Morrison said:
    So, when I call k_msleep, how quickly does the CPU turn off, and how quickly does the HF clock turn off?

    The HFCLK will not turn of if it is being used / requested by any other peripherals, like the PPI or GPIOTE (for high accuracy events).
    In your minimal application you do not use any such
    However, when you use the k_msleep(1) it would mean that your CPU has to wake up every 1 ms to process the next k_msleep instruction, which likely is skewing your measurements.
    If you have no operations/processing other than the k_msleep happening in your main loop you could instead leave it empty, which will have it go into the sleep thread/SYSTEM_ON sleep, which should give you lower overall power consumption (if you only would like to measure power consumption of a background process anyways, no CPU actions).

    Rory Morrison said:
    I've been using an otii sampling at 4 kHz so it's possible it's smoothing out the current and what looks like a small oscillation around 650 uA is actually a spike up to ~4 mA when the CPU turns on, and a dip down to 20 uA the rest of the time.

    I would think that you would see the spike to ~4mA if this was the case, when sampling with 4 kHz. I unfortunately do not have any personal experience with the otii tools (I primarily use the PPK II myself), but I would not imagine that it would miss the spike of the CPU turning on.

    Best regards,
    Karl

  • It's occurred to me that when I call k_msleep(1) the operating system has to time a 1 ms sleep. It can't accurately do that without using the HF clock, because 32768 clock cycles doesn't divide into 1000. So presumably something in the OS has to decide if it's worth using the LF clock and turning off the HF clock for part of the sleep time, or whether to just to keep the HF clock on throughout.

    So the question is, how does the OS decide that? Is there any way I can get zephyr to turn off the HF clock faster?

  • Hello,

    The system clock is the RTC1, which is a ultra low power clock source - it will not need to keep the HF clock on in order to time the kernel sleeps, so that should not be what you are seeing here.
    I would rather think you are seeing the increased current from having to wake up to process the k_msleep every 1 ms.
    Did you try to keep the loop empty, and measured the power consumption in this case? If you are then seeing the expected levels we would be able to confirm that the excess draw is indeed related to the CPU wakeup to process k_msleep.

    Best regards,
    Karl

  • Possibly, although I don't think that explains all of it. I can measure the CPU wake up and sleep using EVENTS_SLEEPENTER and EVENTS_SLEEPEXIT, and that gives me 80 us awake (sometimes only 40), then 1000 us asleep. A back-of-the-envelope calculation gives me about 320 uA from that, when I'm seeing twice that on the otii.

    However, I've realised that the board I'm testing on (a prototype of our device) has an LDO that drops the voltage going to the nRF module, and I think smooths the current draw. So that would explain why I'm not seeing a big ~4 mA spike when the CPU turns on, and also why I don't necessarily see the full dip in current in sleep mode.

    I'm going to try it on a dev kit hooked up to an oscilloscope to see if I can actually see the spike, and confirm what the idle current is in between.

Related