nRF5340 SAADC power consumption

I'm profiling the current consumption of our device, on an nRF5340 module, at SDK 2.1.0.

So far as I can tell, the ADC is using approximately 1000 uA. It's sampling via PPI, and is triggered from an external clock signal at 1 kH.

The current consumption figures for the SAADC here show typical current consumption based on different configuration options. It looks like ~1000 uA is on the high end of what is expected, and that setting LPOP=LowPower would save us a considerable amount of current.

However I can't find anything about LPOP or LowPower anywhere else, either in the SAADC documentation or in the SDK.

Any tips as to where This can be enabled? I've seen this for an old version of the SDK, but it seems to come down to setting saadc_config.low_power_mode = true; which isn't part of the config struct in the current SDK.

Parents
  • Okay, I had the wrong idea a couple of days ago - in the sample button code, it sleeps for 1 ms in a while loop, and if I make that 1000 ms instead, the current consumption drops massively. I think that whole reply can be safely ignored!

    I've now copied over our interrupt code, so I can test it in isolation from the rest of our code. If I initialise the interrupt using a spare unconnected pin, I get current consumption of ~90 uA, and this is with the sense set to NRF_GPIOTE_POLARITY_HITOLO, which I suspect means we're doing edge detection, which adds some extra current. So that's encouraging.

    If I go back to using our external 1000 Hz RTC signal, I get just over 1 mA consumption. But I can set the prescaler on our external RTC to give different interrupt frequencies, and this is where things get weird...

    The pink line is 1000 Hz interrupts, and just over 1 mA current. The blue line is 250 Hz interrupts, and about 220 uA. The purple line is 500 Hz and oscillates between ~90 uA and ~220 uA.

    (The low power at the beginning is 2.5 seconds of sleep, the code to set up our external RTC over spi, and then 2.5 seconds of sleep again)

    All I can think is that the timing of the MCU going to sleep somehow requires > 1 ms for it to kick in, and so at 1000 Hz interrupts, we never get there. Or rather, I guess the idle current still has the HF oscillator on for ~1 ms?

    This is the config/init code I'm using - so the interrupt is disabled, and so button_pressed shouldn't be being executed. And I've done nothing to initialise the ADC or PPI.

        static const nrfx_gpiote_in_config_t pin_interrupt_config = {
            .sense = NRF_GPIOTE_POLARITY_HITOLO,
            .pull = NRF_GPIO_PIN_PULLUP,
            .is_watcher = false,
            .hi_accuracy = true,
            .skip_gpio_setup = false,
        };

        nrfx_gpiote_in_init(pin, &pin_interrupt_config, button_pressed);
        nrfx_gpiote_in_event_enable(pin, false);
  • Hi,

    Have you checked how long the execution time of the interrupt is? You can use GPIO toggling in the interrupt handler to check that, or toggle a GPIO at the end of the handler and compare this to the GPIO input. It is also possible to use DPPI and GPIOTE to toggle a GPIO from the POWER->EVENTS_SLEEPENTER and EVENTS_SLEEPEXIT to see when the CPU is actually in sleep.

    If for instance the interrupt takes 250us to complete, the ~1mA avereage current makes sense as it will make the Application CPU running about 25% of the time. This also makes sense for the 250Hz current. The 500Hz current does not make sense, but there could be some other error with this. Have you checked that the interrupt actually happens at 500Hz with this configuration? Is there anything in your application that corresponds with the rate that it toggles between high and low current consumption?

    Best regards,
    Jørgen

  • Hi Jørgen,

    That's encouraging, in a way. So far I haven't managed to get a sensible-looking current measurement out of the DK board at all. I'm trying to use a scope across a 10 ohm resistor as described in the infocenter documentation, but I get even higher curent consumption than I do when I measure our own boards.

    It looks like something on the DK stays powered even when I've set it to only power the nRF53 - can you walk me through exactly how it needs to be powered and how to set the microswitches to measure just the nRF53?

    Alternatively it might just be easier to use the nordic PPK - I'll see if we can order one.

    Other than that I just want to double check what SDK you used? I've been using 2.1.0. That's the only thing I can think of apart from the hardware or my measuring setup that could be different.

    Thanks,

    Rory

    EDIT - the scope I'm using is a RIGOL DS1054Z which doesn't have a differential input mode, so I'm relying on the math function to get the difference between two channels. It seems like I can either have low resolution on the two channels, meaning the measurement noise is larger than the <1 mV signal I'm trying to measure, or I can have higher resolution, and the current measurement pins being at ~3V mean they're both off the scale so I get no signal at all. We've ordered a PPK so hopefully I can get a measurement with that in a couple of days.

  • Ok, I now have a PPK II which makes measuring current a lot easier.

    I can confirm that on our hardware I still see ~1 mA of current with the RTC at 1000 Hz. But at 500 Hz I get about 90 uA with occasional large spikes... 

    Those spikes, closeup, look like this

      or sometimes this 

    So it looks like *something* turns on with the big spike, then triggers one or more times before turning off again.

    The 1000 Hz RTC version looks like this

    Which seems to just be the 3 mA spikes, at 2 kHz.

    At this point it looks like it must be our hardware doing this, except I can get sort of similar behaviour on my dev kit, by sleeping in a loop for a few milliseconds. Sleeping 1 ms in a loop looks like this

    Those small sawtooth peaks are at about 1000 Hz, so correspond to the CPU waking up and immediately sleeping. Those bigger 3 mA spikes look similar to what I get on our board though, seemingly at random intervals...

    I don't have a signal generator to hand, so will try the dev kit on Monday to see if I can reproduce the 1000 Hz behaviour on the dev kit.

    In the mean time - any idea what those 3 mA spikes might be? Particularly on the Dev kit current profile?

  • I've now got the dev kit attached to a function generator, and I'm getting similar current consumption to yours, although not exactly the same. But it seems to be in the region of 100 to 150 uA depending on the frequency.

    I've discovered that the RTC chip we use on our own board is powered from the VCC output of the nRF chip at 1.8 V. To do this we're using the chip in high voltage mode. It also seems like it defaults to using the DCDC converters for voltage regulation instead of the LDO, which is not what it says here.

    But if I add 

    CONFIG_BOARD_ENABLE_DCDC_APP=n
    CONFIG_BOARD_ENABLE_DCDC_NET=n
    CONFIG_BOARD_ENABLE_DCDC_HV=n
    to the prj.conf file, I get very different looking current consumption - and about 445uA on the dev board and 485 uA on our own board.
    Any idea why it's defaulting to using the DCDC? Or why (apparently) using the VCC output to power the RTC that triggers the interrupt might cause problems when the DCDC converters are on? 
    I did also notice that the config for the interrupt pin included a pullup - I've now changed this to nopull and that seems to have made a small difference. But I'm still seeing 930 uA on our board, vs ~140 uA on the dev kit.
  • Hi again - I've found another key bit of information.

    Our board powers the nRF5340 in High Voltage mode, whereas the dev kit is in low voltage mode. We're then powering some of our peripherals off the chip's VDD at 1.8 V.

    Even with all the external chips removed, and putting in a clock signal from the signal generator into our board, I'm still getting hundreds of uA more than I do on the dev kit.

    However, by connecting the PPK directly to VDD and bypassing the HVREG entirely, I get dramatically lower current - comparable to the dev kit.

    So it seems either we've done something very wrong in how we've powered the board for HV mode, or the HV regulator is doing something very wrong.

    As I understand it, all we need to do to be in HV mode is power the chip through the VDDH pin, is that correct?

  • Hi,

    Have you tried running the DK in high-voltage mode (through nRF_USB or external supply), to see if you see the same current consumption there? See nRF5340 power source.

    I will check with our current experts if they have seen something like this. Could you share your schematics for reference? 

    Best regards,
    Jørgen

Reply Children
  • Can you talk me through how to measure the power consumption via the external supply? So far the only way I've managed to get sensible current measurements off the Dev Kit is using the PPK in source meter mode, and powering the nRF chip via the current measurement pin following this method.

    If I want to use the PPK in Source Meter mode to measure High Voltage mode, it looks like I can just connect VOut on the PPK to + and GND to - on the external voltage pins, but then I'm not sure what to do with the nRF POWER SOURCE switch, the POWER on/off switch, and the two micro-switches on the bottom of the dev kit (VEXT->nRF and nRF ONLYDEFAULT).

    I'm getting more-or-less what I expect if I set VEXT->nRF to off, and nRF ONLYDEFAULT to what I think is on (switch is to the left, where the dot is). Then power and power source don't seem to make any difference, and I get ~3.5 uA when the CPU is in sleep mode (as in, the main function exits, no tasks or interrupts configured).

    Does that sound right? If so, I can try again with different test code and see if I can reproduce the same ~900 uA current draw.

  • Hi,

    I have not done much current measurements in high voltage mode, but what worked for me was to put the "nRF power source" switch in USB position, cut SB41 (VDD_HV) on the DK, then connect Vout from PPK2 to the upper pin of VDD_HV, the GND pin from PPK2 to "-" pin of external supply, then set the PPK2 application in source meter mode. All other switches are in default positions.

    Could you check if this works on your end as well? It could be beneficial to program a BLE example or similar to the board until you get the current measurements working correctly, then you can see the spikes when the radio is active (for instance at the advertising or connection interval).

    Best regards,
    Jørgen

  • Thanks Jørgen, that's really helpful.

    I've tried my interrupt test code on the dev kit, and now get something like I was getting on our custom hardware.

    Without the Signal Generator connected, I get ~18 uA with a spike every second when the CPU wakes up and immediately goes back to sleep. That's pretty much what I expect, although I'll double check the current figure.

    With the sig gen connected and at 1000 Hz, I get about 580 uA, with the same sort of 3 mA spikes as I was getting before - except these are at 1 kHz, which matches the sig gen.

    Zoomed in it looks like this

    So it looks like I get similar behaviour on the dev kit to what I get on our own board. But the spikes are at a lower frequency, so the overall current consumption is a bit lower.

    ETA: current consumption increases even more if I change the gpiote interrupt config - In my test code I had set the pullup to NRF_GPIO_PIN_NOPULL and hi_accuracy to false while trying to get to the bottom of the current draw.

    Setting the pull back to NRF_GPIO_PIN_PULLUP I'm now getting just under 650 uA, and setting high accuracy mode to true it jumps to 1.4 mA.

    One thing I want to check with you though - I've now cut both SB 40 and SB 41, I assume I need to put a jumper across whichever one I'm not using to power the nRF53?

Related