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 10:56 AM
Another small step, I've added an empty "SystemInit()" definition, and can see that it overrides the default since the resulting code is smaller. And the wakeup delay goes to 165 µs. Baby steps ...
UPDATE - code size is as follows now:
text data bss dec hex filename
664 8 1564 2236 8bc .pioenvs/l031/firmware.elf
The BSS size matches the default 512+1024 bytes min heap and stack. So one way to explain the remaining 100 µs startup overhead, is that the C runtime is clearing ≈ 1500 bytes of memory.
Although I don't understand why those areas would need be cleared on power-up.
2018-12-30 11:30 AM
Is it possible to start with HSI (16MHz?) instead of MSI (and switch later)
MSI has to probably calibrate and lock from LSI/LSE...
2018-12-30 11:52 AM
MSI takes 5 µs to start up, and 2 µs to stabilise (I don't have an LSE, and AFAIK, LSI is not accurate enough to assist MSI). HSI startup time is 3.7 µs. All values are "typical", not max.
2018-12-30 12:16 PM
Thanks again. A dummy SystemInit() shaves 15 µs off the startup time (see my other comments). I've also examined the "startup_stm32l011xx.s" and "startup_stm32l031xx.s" files, which differ in a small but surprising detail: checking for flash mapping, and remapping it to address 0 (not sure why L011 and L031 differ). As I also mentioned elsewhere, the startup time I now see is 165 µs. It may be a bit extreme to try and reduce this further, but it'd be nice to at least understand where it's coming from. At 2.1 Mhz, I'd expect at least a hundred instructions to take this amount of time.
2018-12-31 03:33 AM
Here my results by using my method (PA0 as external wake-up pin on PA5 toggle into system_init()) but it should be the same by using iwdg reset. I will check it.
I capture 73µs @ VDD=3.3V with Fast wakeup enabled. And maybe need to take the code added into System_Init() to configure PA5 clock, and IO register. Maybe 20 cycles to remove at 2.1MHz. 9µs to substract ie 73-9 = 64µs
void SystemInit (void)
{
/* GPIO PA5 Toogle sequence to trigger Wakeup Time measurement from Standby mode
Sequence is coded in LL to reduce cycle number. Here 20 cycles.
Wakeup Time is mesured by substract Wakeup Pin Rising Edge and PA5 toogle Rising Egde
GPIOA Ports Clock Enable */
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
/* 0xEBFFFCFF is default value for GPIOA_MODER,
PA5 is set as Push Pull, all other GPIO Analog */
GPIOA->MODER = ((0xEBFFFCFF & ~0x0C00) | 0x0400);
/* Toggle Trig GPIO PA5 */
GPIOA->BSRR = GPIO_Pin_5;
GPIOA->BRR = GPIO_Pin_5;
.......
Check and Clear Standby-Flag at the start of main.
I do not use STM32 libopen lib. I use CMSIS direct register access.
Let me know.
Good luck.
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-31 04:16 AM
Great to see this, many thanks. You're doing the work in "SystemInit()" which I have in "main()". I also do not use libopen, but my own code, and it also uses direct register access. The differences, as far as I can tell, should be at most a few instruction cycles - I'll investigate further. Then again, 100 µs is not much @ 2.1 MHz, so maybe the remaining 100 µs I'm chasing should just be treated as "startup overhead".
2018-12-31 04:32 AM
To clarify: my reason for getting the standby cycle as fast and low-power as possible, is because I want to understand how much energy is needed to power up an STM32L0. The project this is for has preciously little spare energy on startup, and needs to overcome the initial "power consumption hump" before the µC can initialise the rest of the circuit and put itself into stop mode with periodic wake-up.
2018-12-31 05:54 AM
Ok, I''ve got the startup time to toggling an I/O pin in main down to 85 µs. Did this by removing most of the code in the startup.s file for L031, not calling SystemInit, and not even initialising BSS (just as a test). My demo is cycling nicely at 0.8s, with standby and the IWDG waking it up again.
My conclusion is that the remaining 20 µs are down purely to the few remaining instructions needed to set up the stack and I/O pin (and some variation in that 65 µs spec). So all is well - this is indeed the amount of time it takes to get an L031 out of standby. All conform to specs.
My sincere thanks to everyone who offered tips, comments, sample code, and screen shots. All of these became little nudges to keep going and figure this all out. What a nice way to end 2018 =)
2018-12-31 08:50 AM
Have you considered the use of STOP mode in place of the Standby for a compromise consumption / speed of wake ?
Current consumption less than 800nA
Wake-up less than 8μs
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-31 11:50 AM
"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. " ==> This 65 us in the spec is based on 2.1MHz MSI?
If start time is more important than consumption, HSI will run the instructions in shorter time?...