2018-12-30 01:30 AM
I've been trying to get an STM32L031 to periodically wakeup with minimal power consumption. The specs say it can standby at under 0.5 µA, which I can confirm, but also that it can wake up within 65 µs, which I cannot reproduce. I'm seeing a 1.6 ms delay with 300..400 µA current consumption. This seems to indicate that the µC is waiting for Vrefint to stabilise, even though I have the FWU bit set. Below is a minimal example which still does not wake up in 65 µs:
#include <jee.h>
int main() {
MMIO32(Periph::iwdg+0x00) = 0x5555; // unlock PR
MMIO32(Periph::iwdg+0x04) = 1; // max timeout is 800ms
MMIO32(Periph::iwdg+0x00) = 0xCCCC; // start watchdog
constexpr uint32_t scr = 0xE000ED10;
MMIO32(scr) |= (1<<2); // set SLEEPDEEP
MMIO32(Periph::rcc+0x38) |= (1<<28); // PWREN
MMIO32(Periph::pwr) |= (1<<10) | (1<<9) | (1<<1); // FWU, ULP, PDDS
__asm("wfi");
}
I changed the option byte to disable BOR, but it did not make a difference. My write-up about this issue can be found here: https://jeelabs.org/2018/low-power-l031/
What am I missing?
2018-12-30 02:09 AM
Not a speclalist in low power mode, however, if the clock is stopped, How is the clock generated? If it comes from PLL it probably needs time to stabilize before the SW can actually continue running? There should be some low power modes application note somewhere.
2018-12-30 06:18 AM
The L031 starts up with the MSI @ 2.1 MHz, which takes only a few cycles, I think.
2018-12-30 07:26 AM
What tools?
Sure you don't have code in SystemInit() running prior to main(). Review code executing in startup.s
2018-12-30 08:12 AM
Aha, thanks! Will investigate. Using PlatformIO w/ gcc, stm32cube as runtime.
2018-12-30 08:23 AM
Hi jcw
Could you explain your method for wake up measurement ?
Are you sure FWU is enabed ?
usually, when mcu is in low power mode, we trigger (with oscilloscope) the duration between rising edge on Wakeup-Pin and a GPIO toggle written into CMSIS System_init() function or into Reset_Handler (in assembly)
Important Note: You must check the Reset Flag status if the reset cause is from a hard reset or from Standby return. And clear it properly. Do that early in your code.
BR
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2018-12-30 10:44 AM
Method: I measure current, and trigger on its leading flank.
FWU: yes, see code snippet above.
There's no external wakeup, I'm using the independent watchdog.
2018-12-30 10:46 AM
Ehm, why should I check and reset the reset-cause flags? I'm not interested in this status information - at least not in the simple example I gave.
2018-12-30 10:50 AM
New results, and frankly, I'm not sure how to interpret them - I now get more like 180 µs delay, much closer to the expected 65 µs, and a good deal better than the 1.6 ms reported earlier.
Here is the new code, with an LED attached to PA1, so I can see when the main code starts:
int main() {
PinA<1> led;
led.mode(Pinmode::out);
MMIO32(Periph::iwdg+0x00) = 0x5555; // unlock PR
MMIO32(Periph::iwdg+0x04) = 1; // max timeout is 800ms
MMIO32(Periph::iwdg+0x00) = 0xCCCC; // start watchdog
constexpr uint32_t scr = 0xE000ED10;
MMIO32(scr) |= (1<<2); // set SLEEPDEEP
MMIO32(Periph::rcc+0x38) |= (1<<28); // PWREN
MMIO32(Periph::pwr) |= (1<<10) | (1<<9) | (1<<1); // FWU, ULP, PDDS
__asm("wfi");
}
2018-12-30 10:52 AM
And here's the matching scope shot with the current consumption readings: