Is the PMU keeping things powered on?

We have code that puts the HW to sleep. On a nRF52833.

The pseudo code would be something like this -

<shutdown SD, stop freertos scheduler, stop interrupts, power down all hardware blocks, put GPIOs into low power state (most inputs, some gate our HW>

If at this point we call a NRF_POWER->SYSTEMOFF = 1; we see the board consumption drop to ~6uA (which is about what we expect)

If however we try either a loop around nrf_pwr_mgmt_run(); or a basic

_disableirq(); while(1) { __WFI() }; // as expected this never returns

We see about 1.4mA after the main code has been running, and only 6uA if the sleep code is called immediately after HW init.

The assumption is that PMU is keeping lots of the device powered up and active.

Q. I cannot see any central method of determining the state of the PMU and which peripherals are powered up, is this correct?

To remove any ambiguity on our shutdown code I added in a simple function "force_all" see below

void force_all (void)
{
NRF_UART0->ENABLE = 0;
NRF_UARTE0->ENABLE = 0;
NRF_USBD->ENABLE = 0;
NRF_UARTE1->ENABLE = 0;
NRF_SPI0->ENABLE = 0;
NRF_SPIM0->ENABLE = 0;
NRF_SPIS0->ENABLE = 0;
NRF_SPI1->ENABLE = 0;
NRF_SPIM1->ENABLE = 0;
NRF_SPIS1->ENABLE = 0;
NRF_SAADC->ENABLE = 0;
NRF_PWM0->ENABLE = 0;
NRF_PDM->ENABLE = 0;
NRF_PWM1->ENABLE = 0;
NRF_PWM2->ENABLE = 0;
NRF_SPI2->ENABLE = 0;
NRF_SPIM2->ENABLE = 0;
NRF_SPIS2->ENABLE = 0;
NRF_RTC0->TASKS_STOP = 1;
NRF_RTC1->TASKS_STOP = 1;
NRF_RTC2->TASKS_STOP = 1;
NRF_I2S->ENABLE = 0;
NRF_PWM3->ENABLE = 0;
NRF_SPIM3->ENABLE = 0;
NRF_TIMER1->TASKS_STOP = 1;
NRF_TIMER2->TASKS_STOP = 1;
NRF_TIMER3->TASKS_STOP = 1;
NRF_TIMER4->TASKS_STOP = 1;
NRF_QDEC->ENABLE = 0;
NRF_COMP->ENABLE = 0;
NRF_LPCOMP->ENABLE = 0;
NRF_TWI1->ENABLE = 0;
NRF_TWIM1->ENABLE = 0;
NRF_TWIS1->ENABLE = 0;
NRF_TWI0->ENABLE = 0;
NRF_TWIM0->ENABLE = 0;
NRF_TWIS0->ENABLE = 0;
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
NRF_TIMER0->TASKS_STOP = 1;
NRF_RADIO->TASKS_DISABLE = 1;
NRF_NFCT->TASKS_DISABLE = 1;
NRF_GPIOTE->CONFIG[0] = 0;
NRF_GPIOTE->CONFIG[1] = 0;
NRF_GPIOTE->CONFIG[2] = 0;
NRF_GPIOTE->CONFIG[3] = 0;
NRF_GPIOTE->CONFIG[4] = 0;
NRF_GPIOTE->CONFIG[5] = 0;
NRF_GPIOTE->CONFIG[6] = 0;
NRF_GPIOTE->CONFIG[7] = 0;
NRF_NVMC->CONFIG=0;
NRF_MWU->REGIONENSET = 1;
NRF_TEMP->TASKS_STOP=1;
NRF_RNG->TASKS_STOP=1;
NRF_ECB->TASKS_STOPECB=1;
NRF_AAR->TASKS_STOP = 1;
NRF_EGU0->INTENCLR = 1;
NRF_EGU1->INTENCLR = 1;
NRF_EGU2->INTENCLR = 1;
NRF_EGU3->INTENCLR = 1;
NRF_EGU4->INTENCLR = 1;
NRF_EGU5->INTENCLR = 1;
NRF_EGU0->INTEN=0;
NRF_EGU1->INTEN=0;
NRF_EGU2->INTEN=0;
NRF_EGU3->INTEN=0;
NRF_EGU4->INTEN=0;
NRF_EGU5->INTEN=0;
NRF_CCM->TASKS_STOP;
NRF_PPI->TASKS_CHG[0].DIS = 1;
NRF_PPI->TASKS_CHG[1].DIS = 1;
NRF_PPI->TASKS_CHG[2].DIS = 1;
NRF_PPI->TASKS_CHG[3].DIS = 1;
NRF_PPI->TASKS_CHG[4].DIS = 1;
NRF_PPI->TASKS_CHG[5].DIS = 1;
NRF_PPI->CHEN = 0;
NRF_POWER->TASKS_LOWPWR=1;
}

and called it before the sleep, it had no effect.

So, to recap, if the power down code is called after all the HW is initialized we see the expect 6uA (with either a WFI() loop or a complete core shutdown) - if we call it after the application has been running we see 1.4mA on the WFI() loop and 6uA on the shutdown. Therefore I assume the issue is something still running on the device.

I assume there is a hole in my shutdown logic, or something is somehow being determined as "ON" by the PMU and is keeping everything else on. And 1.4mA is fairly large as things go.

I've been diving the forums for a few hours, and other that "check your peripherals are all off" (see force_all() above) there it not a huge amount of advice on debugging the PMU to see where the power is going. The FW has vanished into a WFI() and (according to the Segger has never returned - after all, all interrupts are disabled).

it would not be possible to recreate all of this as an example, but I can certainly include shutdown code.

I know the Segger being attached powers up a large amount of the core via the SWD - so I remove it when not checking if the WFI() is returning and I see a drop of about ~30uA only.

The intention is that once I have solved this power issue I'll re-enable a single RTC via the LFCLK to allow it to make decisions and come out of sleep.

Any advice welcome.


Parents Reply Children
No Data
Related