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
  • 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.

    Hmm, Is there any possible that you are testing this in the BLE with the softdevice being flashed before the application and softdevice enabled?

    • We have seen issues with the application trying to go to low power mode when using the sd_app_evt_wait.  
    • We have seen some issues in the FPU handling in a way that the application tries to control everything manually but forgets to handle the FPU exception which can keep the core awake due to the unhandled pending bit set in the NVIC register. This can be fixed by clearing the pending bits in the FPU status register and the pending bit in the interrupt register
      __set_FPSCR(__get_FPSCR()  & ~(FPU_EXCEPTION_MASK));
      (void) __get_FPSCR();
      NVIC_ClearPendingIRQ(FPU_IRQn);

    If the above two things are not the reason you see this difference, then it is worth exploring the reason by trying to debug this. One manual approach I can suggest to do is to see all the peripheral registers if they have actually disabled.

  • For the first point - the SD is disabled, I have already traced through the nrf_pwr_mgmnt_run() and seen that the check

    if (nrf_sdh_is_enabled())
    {
    ret_code_t ret_code = sd_app_evt_wait();

    means that sd_app_evt_wait() is not being called.

    For the second point I'll have a play with the debugger now.

    If that fails then I will look at all the peripheral registers one by one to see if any of them are still on - that might take a while.

    Thank you for your help/advice - I'll try and find more information.

Reply
  • For the first point - the SD is disabled, I have already traced through the nrf_pwr_mgmnt_run() and seen that the check

    if (nrf_sdh_is_enabled())
    {
    ret_code_t ret_code = sd_app_evt_wait();

    means that sd_app_evt_wait() is not being called.

    For the second point I'll have a play with the debugger now.

    If that fails then I will look at all the peripheral registers one by one to see if any of them are still on - that might take a while.

    Thank you for your help/advice - I'll try and find more information.

Children
No Data
Related