From 4d4f018f22a0a9814e675a232b1c4239572bdd9a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 18 Jun 2019 13:02:51 -0700 Subject: [PATCH] altos/micropeak-v2.0: Go into standby mode after landing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is the lowest power state we can reach, and consumes about 15µA or less. Signed-off-by: Keith Packard --- src/micropeak-v2.0/ao_micropeak.c | 1 + src/stmf0/ao_arch_funcs.h | 25 +++++++++++++++++++++++++ src/stmf0/stm32f0.h | 10 +++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/micropeak-v2.0/ao_micropeak.c b/src/micropeak-v2.0/ao_micropeak.c index 0e3a9005..c3f06207 100644 --- a/src/micropeak-v2.0/ao_micropeak.c +++ b/src/micropeak-v2.0/ao_micropeak.c @@ -194,6 +194,7 @@ ao_micropeak(void) ao_compute_height(); ao_report_altitude(); + ao_sleep_mode(); ao_sleep(&ao_on_battery); } diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index 9233f044..a0c6e088 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -447,6 +447,31 @@ static inline void ao_arch_restore_stack(void) { asm("pop {r0-r7,pc}\n"); } +static inline void ao_sleep_mode(void) { + + /* + WFI (Wait for Interrupt) or WFE (Wait for Event) while: + – Set SLEEPDEEP in Cortex ® -M0 System Control register + – Set PDDS bit in Power Control register (PWR_CR) + – Clear WUF bit in Power Control/Status register (PWR_CSR) + */ + + ao_arch_block_interrupts(); + + stm_scb.scr |= (1 << STM_SCB_SCR_SLEEPDEEP); + ao_arch_nop(); + stm_pwr.cr |= (1 << STM_PWR_CR_PDDS) | (1 << STM_PWR_CR_LPDS); + ao_arch_nop(); + stm_pwr.cr |= (1 << STM_PWR_CR_CWUF); + ao_arch_nop(); + ao_arch_nop(); + ao_arch_nop(); + ao_arch_nop(); + ao_arch_nop(); + asm("wfi"); + ao_arch_nop(); +} + #ifndef HAS_SAMPLE_PROFILE #define HAS_SAMPLE_PROFILE 0 #endif diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index fb815966..075fd6a9 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -568,6 +568,8 @@ struct stm_pwr { extern struct stm_pwr stm_pwr; +#define stm_pwr (*(struct stm_pwr *) 0x40007000) + #define STM_PWR_CR_DBP (8) #define STM_PWR_CR_PLS (5) @@ -585,7 +587,7 @@ extern struct stm_pwr stm_pwr; #define STM_PWR_CR_CSBF (3) #define STM_PWR_CR_CWUF (2) #define STM_PWR_CR_PDDS (1) -#define STM_PWR_CR_LPSDSR (0) +#define STM_PWR_CR_LPDS (0) #define STM_PWR_CSR_EWUP3 (10) #define STM_PWR_CSR_EWUP2 (9) @@ -746,6 +748,8 @@ struct stm_scb { extern struct stm_scb stm_scb; +#define stm_scb (*(struct stm_scb *) 0xe000ed00) + #define STM_SCB_AIRCR_VECTKEY 16 #define STM_SCB_AIRCR_VECTKEY_KEY 0x05fa #define STM_SCB_AIRCR_PRIGROUP 8 @@ -753,6 +757,10 @@ extern struct stm_scb stm_scb; #define STM_SCB_AIRCR_VECTCLRACTIVE 1 #define STM_SCB_AIRCR_VECTRESET 0 +#define STM_SCB_SCR_SEVONPEND 4 +#define STM_SCB_SCR_SLEEPDEEP 2 +#define STM_SCB_SCR_SLEEPONEXIT 1 + #define STM_ISR_WWDG_POS 0 #define STM_ISR_PVD_VDDIO2_POS 1 #define STM_ISR_RTC_POS 2 -- 2.30.2