Too much power consumption in STOP mode using STM32sleep library

Working libraries, libraries being ported and related hardware
ag123
Posts: 775
Joined: Thu Jul 21, 2016 4:24 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by ag123 » Fri May 12, 2017 2:17 pm

i did a little bit of reading in rm0008,
p73 5.3.4 Stop mode
The Stop mode is based on the Cortex®-M3 deepsleep mode combined with peripheral
clock gating. The voltage regulator can be configured either in normal or low-power mode.
In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
oscillators are disabled. SRAM and register contents are preserved.
In the Stop mode, all I/O pins keep the same state as in the Run mode.
it didn't seem to suggest that the peripheral clocks would be stopped automatically, hence you may like to try stopping the clocks

then there is also the standby mode
p75 5.3.5 Standby mode
The Standby mode allows to achieve the lowest power consumption. It is based on the
Cortex®-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
switched off. SRAM and register contents are lost except for registers in the Backup domain
and Standby circuitry (see Figure 4).
I/O states in Standby mode
In Standby mode, all I/O pins are high impedance except:
• Reset pad (still available)
• TAMPER pin if configured for tamper or calibration out
• WKUP pin, if enabled
hence you may like to try standby mode as well

oh and use a *real* LiPo LDO that drop out less than < 0.5v if you need that (e.g. running on 4.2v), that 1 Amp ams1117 is apparently not to reduce power more than its cost effectiveness regulating 5v to 3.3v and gives 1 A output reducing complaints about insufficient power. who knows someone may use blue pill to drive their 3d printer hot end :lol:

just 2 cents, hope it helps

victor_pv
Posts: 1682
Joined: Mon Apr 27, 2015 12:12 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by victor_pv » Fri May 12, 2017 3:19 pm

acobo wrote:
victor_pv wrote:
ag123 wrote:@acobo
the other thing would be about the clocks, i'm not too sure if simply doing stop would turn off the peripheral clocks, i'd guess one way is to stop all the APB1 and APB2 clocks as well and check power consumption

as for precise measurements, i'm thinking the inactive AMS1117 may literally be taking some power. hence for a 'real' test u may need to unsolder that ams1117 and put that back later :lol:
http://www.advanced-monolithic.com/pdf/ds1117.pdf

@ahull
agreed, lipo size is a trouble, that's why all that fuss looking for a 'real' LDO that drop less than < 0.5v :lol:
I'm with AG on the clocks. Has been a while since I read about the different modes, but on some of them to get the lowest consumptoin you had to first disable the clocks, or set the internal power regulator to a different mode. Go over the reference mnual to make sure you are not missing some step.
The thing is that I am using the library STM32sleep that should do all the steps, and apparently, it does, and I suppose many people are using this library. According to the reference manual, the clocks are automatically stopped upon entering the STOP mode, which you configure changing some bits in registers (to activate deepsleep, low-power mode of the internal regulator, and to choose between standby and stop mode) and then executing a "WFI" asm instruction. And that is what the library does. With the code I am using, which is just the example of the library, the author shows in another thread of these forums a power consumption in STOP mode of 13uA. It is a huge difference.
It can't be the regulator of the bluepill because muy custom board has no regulator and current its exactly the same (well not exactly because I am using the mA scale with a resolution of 10uA, but it is very simmilar).

And battery size IS a problem for me, because this circuit will be glued to the shell of living limpets to record its "lifestyle" under the sea. I cannot see these poor creatures carrying a 6000mAH LiPo :D
thanks all for your help,
Adolfo,.
The library has a function for disabling the clocks, I did not see it called when entering any mode. I think you are supposed to call it in your code if you want to stop the clock to all peripherals.
I may have missed the call to that function, if so, please let me know.

acobo
Posts: 8
Joined: Thu May 04, 2017 4:09 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by acobo » Fri May 12, 2017 7:02 pm

victor_pv wrote:
acobo wrote:
victor_pv wrote: The library has a function for disabling the clocks, I did not see it called when entering any mode. I think you are supposed to call it in your code if you want to stop the clock to all peripherals.
I may have missed the call to that function, if so, please let me know.
Thankyou Victor for your reply. I understand that this call to disable all clocks is needed only if you want to reduce power in the RUN mode (it is stated so in the comments of the library code) as clocks are automatically disabled when entering the STOP or STANDBY mode. In any case, I have already tried to call it before going into STOP mode. At first, it didn't work, I think that some clocks cannot be disabled if you want the code to keep running (such as the clock for DMA, SRAM..). So I disabled most clocks but a few that seemed to me "important":

Code: Select all

  rcc_clk_disable(RCC_ADC1);
    rcc_clk_disable(RCC_ADC2);
    rcc_clk_disable(RCC_ADC3);
    //rcc_clk_disable(RCC_AFIO);
    //rcc_clk_disable(RCC_BKP);
    rcc_clk_disable(RCC_CRC);
    rcc_clk_disable(RCC_DAC);
    //rcc_clk_disable(RCC_DMA1);
    //rcc_clk_disable(RCC_DMA2);
    //rcc_clk_disable(RCC_FLITF);
    //rcc_clk_disable(RCC_FSMC);
    rcc_clk_disable(RCC_GPIOA);
    rcc_clk_disable(RCC_GPIOB);
    rcc_clk_disable(RCC_GPIOC);
    rcc_clk_disable(RCC_GPIOD);
    rcc_clk_disable(RCC_GPIOE);
    rcc_clk_disable(RCC_GPIOF);
    rcc_clk_disable(RCC_GPIOG);
    rcc_clk_disable(RCC_I2C1);
    rcc_clk_disable(RCC_I2C2);
    //rcc_clk_disable(RCC_PWR);
    //rcc_clk_disable(RCC_SDIO);
    rcc_clk_disable(RCC_SPI1);
    rcc_clk_disable(RCC_SPI2);
    rcc_clk_disable(RCC_SPI3);
    //rcc_clk_disable(RCC_SRAM);
    rcc_clk_disable(RCC_TIMER1);
    rcc_clk_disable(RCC_TIMER2);
    rcc_clk_disable(RCC_TIMER3);
    rcc_clk_disable(RCC_TIMER4);
    rcc_clk_disable(RCC_TIMER5);
    rcc_clk_disable(RCC_TIMER6);
    rcc_clk_disable(RCC_TIMER7);
    rcc_clk_disable(RCC_TIMER8);
    rcc_clk_disable(RCC_TIMER9);
    rcc_clk_disable(RCC_TIMER10);
    rcc_clk_disable(RCC_TIMER11);
    rcc_clk_disable(RCC_TIMER12);
    rcc_clk_disable(RCC_TIMER13);
    rcc_clk_disable(RCC_TIMER14);
    rcc_clk_disable(RCC_USART1);
    rcc_clk_disable(RCC_USART2);
    rcc_clk_disable(RCC_USART3);
    rcc_clk_disable(RCC_UART4);
    rcc_clk_disable(RCC_UART5);
    rcc_clk_disable(RCC_USB);
   sleepAndWakeUp(STOP, &rt, alarmDelay);
  // sleeping in stop mode for 5 seconds
  ...
and with all those clocks disabled, the current in STOP remained exactly the same, so it could confirm my theory that clocks are automatically disabled for STOP and STANDBY modes.
I am about to throw the towel and switch to STANDBY mode, the only problem is that I need to save the state between resets and using the eeprom emulation library draw a huge amount of current for writing and erasing the flash, I think,
Thank you again for your help,
Adolfo.

victor_pv
Posts: 1682
Joined: Mon Apr 27, 2015 12:12 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by victor_pv » Fri May 12, 2017 7:09 pm

acobo wrote:
victor_pv wrote:
acobo wrote:
Thankyou Victor for your reply. I understand that this call to disable all clocks is needed only if you want to reduce power in the RUN mode (it is stated so in the comments of the library code) as clocks are automatically disabled when entering the STOP or STANDBY mode. In any case, I have already tried to call it before going into STOP mode. At first, it didn't work, I think that some clocks cannot be disabled if you want the code to keep running (such as the clock for DMA, SRAM..). So I disabled most clocks but a few that seemed to me "important":

Code: Select all

  rcc_clk_disable(RCC_ADC1);
    rcc_clk_disable(RCC_ADC2);
    rcc_clk_disable(RCC_ADC3);
    //rcc_clk_disable(RCC_AFIO);
    //rcc_clk_disable(RCC_BKP);
    rcc_clk_disable(RCC_CRC);
    rcc_clk_disable(RCC_DAC);
    //rcc_clk_disable(RCC_DMA1);
    //rcc_clk_disable(RCC_DMA2);
    //rcc_clk_disable(RCC_FLITF);
    //rcc_clk_disable(RCC_FSMC);
    rcc_clk_disable(RCC_GPIOA);
    rcc_clk_disable(RCC_GPIOB);
    rcc_clk_disable(RCC_GPIOC);
    rcc_clk_disable(RCC_GPIOD);
    rcc_clk_disable(RCC_GPIOE);
    rcc_clk_disable(RCC_GPIOF);
    rcc_clk_disable(RCC_GPIOG);
    rcc_clk_disable(RCC_I2C1);
    rcc_clk_disable(RCC_I2C2);
    //rcc_clk_disable(RCC_PWR);
    //rcc_clk_disable(RCC_SDIO);
    rcc_clk_disable(RCC_SPI1);
    rcc_clk_disable(RCC_SPI2);
    rcc_clk_disable(RCC_SPI3);
    //rcc_clk_disable(RCC_SRAM);
    rcc_clk_disable(RCC_TIMER1);
    rcc_clk_disable(RCC_TIMER2);
    rcc_clk_disable(RCC_TIMER3);
    rcc_clk_disable(RCC_TIMER4);
    rcc_clk_disable(RCC_TIMER5);
    rcc_clk_disable(RCC_TIMER6);
    rcc_clk_disable(RCC_TIMER7);
    rcc_clk_disable(RCC_TIMER8);
    rcc_clk_disable(RCC_TIMER9);
    rcc_clk_disable(RCC_TIMER10);
    rcc_clk_disable(RCC_TIMER11);
    rcc_clk_disable(RCC_TIMER12);
    rcc_clk_disable(RCC_TIMER13);
    rcc_clk_disable(RCC_TIMER14);
    rcc_clk_disable(RCC_USART1);
    rcc_clk_disable(RCC_USART2);
    rcc_clk_disable(RCC_USART3);
    rcc_clk_disable(RCC_UART4);
    rcc_clk_disable(RCC_UART5);
    rcc_clk_disable(RCC_USB);
   sleepAndWakeUp(STOP, &rt, alarmDelay);
  // sleeping in stop mode for 5 seconds
  ...
and with all those clocks disabled, the current in STOP remained exactly the same, so it could confirm my theory that clocks are automatically disabled for STOP and STANDBY modes.
I am about to throw the towel and switch to STANDBY mode, the only problem is that I need to save the state between resets and using the eeprom emulation library draw a huge amount of current for writing and erasing the flash, I think,
Thank you again for your help,
Adolfo.
Hmm, anything else in the reference manual? I remember about an internal regulator that can be set to different power modes to reduce comsumption. I think there was a flag so when entering stop mode the regulator goes in a low power mode, but that disabled something else.

ag123
Posts: 775
Joined: Thu Jul 21, 2016 4:24 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by ag123 » Fri May 12, 2017 7:53 pm

i think rm0008 p80 6 backup registers discussed backup registers (16 registers making up 84 bytes)

another way though in the STOP mode, you may try to put all the pins that you don't use (e.g. the led pin) into tristate mode or even all of them into tristate mode (depending on the context)

Code: Select all

pinMode(pin, INPUT_FLOATING);
but you would need to restore the original pinmode once you exit STOP mode

i've a strange feeling that otherwise some of the pins set in *output* may otherwise be *sinking* or *sourcing* current, it may take some trouble to figure out which is the pin causing it. but finding that out may help avoid having to do standby in which all the state is lost

if you are using those 4.2v LiPo batteries. i'd think u'd need to be a little careful about the internal drain, it seem some LiPo batteries may literally drain even if the load is not consuming current, otherwise the battery may run flat way soon before anyone knows it

just 2 cents,
hope it helps

User avatar
ahull
Posts: 1631
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Too much power consumption in STOP mode using STM32sleep library

Post by ahull » Fri May 12, 2017 10:46 pm

If you use name brand LiPo or LiIon cells then the self discharge rate will be in the datasheet. Typical values can be inferred from the information here. http://batteryuniversity.com/learn/arti ... _discharge

If you use cheap off brand "Chinesium" cells, your on your own.
- Andy Hull -

victor_pv
Posts: 1682
Joined: Mon Apr 27, 2015 12:12 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by victor_pv » Sat May 13, 2017 2:25 am

Just checked with the STM Cube MX tool, in stop mode is supposed to take about 46uA with voltage regulator in ON mode, and 38uA with regulator in LP mode.

Are you sure there is nothing else that may be draining some of that current, and also that whatever you use to measure the current is completely accurate?

EDIT:
And out of curiosity I checked a couple other power modes. Sleep mode with HSI at 8Mhz is 800uA. I suspect the library may be getting you in SLEEP mode rather than STOP mode.

stylon
Posts: 1
Joined: Tue May 16, 2017 11:53 am

Re: Too much power consumption in STOP mode using STM32sleep library

Post by stylon » Tue May 16, 2017 12:30 pm

Some time ago I came across this useful thread on the ChibiOS forum: http://www.chibios.com/forum/viewtopic. ... 9&start=10. User barthess seems to be very experienced in low-power modes and he hints at the fact that the STM32 DEBUG mode prevents FCLK or HCLK to be turned off at all. You must disable DEBUG mode to be able to do so. Explanations how to do that are also there (in reply by user saraben).

ag123
Posts: 775
Joined: Thu Jul 21, 2016 4:24 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by ag123 » Thu May 25, 2017 9:32 am

on a side note, i noted that the systick interrupt
https://github.com/rogerclarkmelbourne/ ... /systick.c
http://docs.leaflabs.com/static.leaflab ... le-systick

runs every millisecond, it does something 'important', it updates the systick_uptime_millis system uptime counter;
this is where millis() and micros() provides values from.

hence the processor may be actually awake as "wfi" (wait for interrupt) and "wfe" (wait for event) would wakeup with the systick interrupt.
hence to conserve power it may be necessary to
1) configure the systick interrupt to a lower priority so that "wfi" or "wfe" won't wake it up
or
2) systick_disable();

there's also something from usb side which i'm not too familar if usb fires interrupts. i think usb do have a 'start of frame' interrupt that fires every millisecond. but i'm not sure if it sof interrupt is enabled or say disconnecting usb would stop that

ag123
Posts: 775
Joined: Thu Jul 21, 2016 4:24 pm

Re: Too much power consumption in STOP mode using STM32sleep library

Post by ag123 » Sat Jun 03, 2017 5:43 pm

the main trouble with systick is *it keeps the mcu awake*
the systick interrupt mainly updates systick_uptime_millis
https://github.com/rogerclarkmelbourne/ ... tick.c#L84
i think this is used by the functions millis(), micros(), and you may be caught off guard but delay() uses millis()
so if you have codes that do

Code: Select all

delay(100) //delay 100ms
you would need to rewrite that not to use delay(),
otherwise once you disable systick interrupt it would run an infinite loop that never exit i.e. infinite delay

doing things the 'tickless' way is the epitome of low power embedded programming, but doing it 'tickless' could mean you need elaborate finite state machines and the whole setup becomes a state-transition based program. e.g. instead of delay(1000) to wait one second, you would need to set a timer interrupt to fire in 1 sec and *call back* your function.
programming changes from call this function to do that
to
don't call us, we'd call you, if there is anything needing your attention
i.e. the system is always asleep, instructions halted except when it is woken up to handle an interrupt
:lol:

in code snippets i've got this 'round robin scheduler' which for now is still pretty much dependent on systick, but of course you could change the systick interval so as to reduce the number of systick interrupts. and of course the ultimate is you simply "WFI" wait for interrupt and that interrupt that you are waiting for is *not systick* (i.e. no systicks) :lol:
http://www.stm32duino.com/viewtopic.php?f=18&t=2117

Post Reply