altos/micropeak-v2.0: Go into standby mode after landing
authorKeith Packard <keithp@keithp.com>
Tue, 18 Jun 2019 20:02:51 +0000 (13:02 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 18 Jun 2019 20:02:51 +0000 (13:02 -0700)
This is the lowest power state we can reach, and consumes about 15µA
or less.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/micropeak-v2.0/ao_micropeak.c
src/stmf0/ao_arch_funcs.h
src/stmf0/stm32f0.h

index 0e3a900..c3f0620 100644 (file)
@@ -194,6 +194,7 @@ ao_micropeak(void)
        ao_compute_height();
        ao_report_altitude();
 
+       ao_sleep_mode();
        ao_sleep(&ao_on_battery);
 }
 
index 9233f04..a0c6e08 100644 (file)
@@ -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
index fb81596..075fd6a 100644 (file)
@@ -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