This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 low power current consumption

Hello everyone,

I am currently using a nRF52832. I've been trying to use the low power mode with little success. I have been seeing a current draw of about 3.5mA. I would expect to see number much lower than this. If i turn on SYSTEMOFF, the current draw can flow as low as 2uA. I thought there could have been an issue with some of the peripherals i was using, so i removed everything from the code apart from the code to put it into low power with an infinite for loop after. Nothing changed.

I am not using the softdevice.

Any suggestions how to get better current consumption?

The I'm using is below.

void main(void)
{ 

   static const uint32_t RAM_BLOCK_OFF = 0UL;
   static const uint8_t NUM_RAM_BLOCKS = 8U;


   /* ALlow memory to turn off to save power */   
   for(uint8_t i = 0U; i < NUM_RAM_BLOCKS; i++)
   {
      /* [15] POWER: RAM[x].POWERSET/CLR read as zero */
      NRF_POWER->RAM[i].POWERSET = RAM_BLOCK_OFF;
   }

   /* I thought I'd try calling the old functions to turn the ram of to see if anything happened. */
   NRF_POWER->RAMON = RAM_BLOCK_OFF;
   NRF_POWER->RAMONB = RAM_BLOCK_OFF;

  NRF_POWER->DCDCEN = 0U;
   
  NRF_CLOCK->TASKS_HFCLKSTART = (uint32_t)0U;
  NRF_CLOCK->TASKS_HFCLKSTOP = (uint32_t)1U;
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0u;
  __DSB();
  while (NRF_CLOCK->EVENTS_HFCLKSTARTED != 0){}
  
  NRF_POWER->TASKS_CONSTLAT = 0;
  NRF_POWER->TASKS_LOWPWR = 1u;
  __DSB();

  for(;;){}

}

Thanks, James

Parents
  • You are not putting the chip to sleep, therefore the current consumption is high. You put the chip to sleep (SYSTEM ON sleep mode) with the __WFE() function. There are a number of posts on this forum describing how this works, see for example this or this. The __WFE() function should be placed in the for(;;){...} loop.

    Another thing to mention is that tasks only triggers when you write a '1' to them, they will not trigger when you write a '0', so writing a '0' is unnecessary. When the chip starts up it will run from the RC oscillator. If you want to run it from the crystal this have to be started. This means that it is not necessary to do anything unless you started the crystal with NRF_CLOCK->TASKS_HFCLKSTART = 1, in that case stop it with the stop task (will happen immediately). If you want to start the crystal the correct procedure is:

    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    
    //wait for HFCLK to start
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0){}
    

    Other points:

    • DCDC is disabled when the chip starts, no need to set the register to zero. Also turning it off will not save power in sleep as it is automatically turned on/off when the current draw is high enough for it to be efficient.
    • No need to call the low power task unless you have set it to constant latency mode. Low power mode is the default configuration
Reply
  • You are not putting the chip to sleep, therefore the current consumption is high. You put the chip to sleep (SYSTEM ON sleep mode) with the __WFE() function. There are a number of posts on this forum describing how this works, see for example this or this. The __WFE() function should be placed in the for(;;){...} loop.

    Another thing to mention is that tasks only triggers when you write a '1' to them, they will not trigger when you write a '0', so writing a '0' is unnecessary. When the chip starts up it will run from the RC oscillator. If you want to run it from the crystal this have to be started. This means that it is not necessary to do anything unless you started the crystal with NRF_CLOCK->TASKS_HFCLKSTART = 1, in that case stop it with the stop task (will happen immediately). If you want to start the crystal the correct procedure is:

    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    
    //wait for HFCLK to start
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0){}
    

    Other points:

    • DCDC is disabled when the chip starts, no need to set the register to zero. Also turning it off will not save power in sleep as it is automatically turned on/off when the current draw is high enough for it to be efficient.
    • No need to call the low power task unless you have set it to constant latency mode. Low power mode is the default configuration
Children
  • Thanks for getting back to me quickly. I looked through the forum but i obviously missed the posts.

    It would be good if this was explained in the datasheet under the power section. From how it is worded in the Datasheet, i assumed since the system can detect when it should sleep, being in an empty for loop, would be a prime time to sleep.

    I've added in the __WFE() command and it works perfectly. Thanks again.

Related