diff options
Diffstat (limited to 'embassy-stm32/src/low_power.rs')
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 2388abe3c..ce3ee6a03 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -170,24 +170,44 @@ impl Executor { | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | critical_section::with(|cs| { | 172 | critical_section::with(|cs| { |
| 173 | #[cfg(stm32wlex)] | 173 | #[cfg(any(stm32wlex, stm32wb))] |
| 174 | { | 174 | { |
| 175 | let es = crate::pac::PWR.extscr().read(); | 175 | let es = crate::pac::PWR.extscr().read(); |
| 176 | #[cfg(stm32wlex)] | ||
| 176 | match (es.c1stopf(), es.c1stop2f()) { | 177 | match (es.c1stopf(), es.c1stop2f()) { |
| 177 | (true, false) => debug!("low power: wake from STOP1"), | 178 | (true, false) => debug!("low power: wake from STOP1"), |
| 178 | (false, true) => debug!("low power: wake from STOP2"), | 179 | (false, true) => debug!("low power: wake from STOP2"), |
| 179 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), | 180 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), |
| 180 | (false, false) => trace!("low power: stop mode not entered"), | 181 | (false, false) => trace!("low power: stop mode not entered"), |
| 181 | }; | 182 | }; |
| 183 | |||
| 184 | #[cfg(stm32wb)] | ||
| 185 | match (es.c1stopf(), es.c2stopf()) { | ||
| 186 | (true, false) => debug!("low power: cpu1 wake from STOP"), | ||
| 187 | (false, true) => debug!("low power: cpu2 wake from STOP"), | ||
| 188 | (true, true) => debug!("low power: cpu1 and cpu2 wake from STOP"), | ||
| 189 | (false, false) => trace!("low power: stop mode not entered"), | ||
| 190 | }; | ||
| 182 | crate::pac::PWR.extscr().modify(|w| { | 191 | crate::pac::PWR.extscr().modify(|w| { |
| 183 | w.set_c1cssf(false); | 192 | w.set_c1cssf(false); |
| 184 | }); | 193 | }); |
| 185 | 194 | ||
| 186 | if es.c1stop2f() || es.c1stopf() { | 195 | let has_stopped2 = { |
| 196 | #[cfg(stm32wb)] | ||
| 197 | { | ||
| 198 | es.c2stopf() | ||
| 199 | } | ||
| 200 | |||
| 201 | #[cfg(stm32wlex)] | ||
| 202 | { | ||
| 203 | es.c1stop2f() | ||
| 204 | } | ||
| 205 | }; | ||
| 206 | |||
| 207 | if es.c1stopf() || has_stopped2 { | ||
| 187 | // when we wake from any stop mode we need to re-initialize the rcc | 208 | // when we wake from any stop mode we need to re-initialize the rcc |
| 188 | crate::rcc::init(RCC_CONFIG.unwrap()); | 209 | crate::rcc::init(RCC_CONFIG.unwrap()); |
| 189 | 210 | if has_stopped2 { | |
| 190 | if es.c1stop2f() { | ||
| 191 | // when we wake from STOP2, we need to re-initialize the time driver | 211 | // when we wake from STOP2, we need to re-initialize the time driver |
| 192 | get_driver().init_timer(cs); | 212 | get_driver().init_timer(cs); |
| 193 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) | 213 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) |
| @@ -276,6 +296,20 @@ impl Executor { | |||
| 276 | 296 | ||
| 277 | drop(sem3_mutex); | 297 | drop(sem3_mutex); |
| 278 | 298 | ||
| 299 | // on PWR | ||
| 300 | RCC.apb1enr1().modify(|r| r.0 |= 1 << 28); | ||
| 301 | cortex_m::asm::dsb(); | ||
| 302 | |||
| 303 | // off SMPS, on Bypass | ||
| 304 | PWR.cr5().modify(|r| { | ||
| 305 | let mut val = r.0; | ||
| 306 | val &= !(1 << 15); // sdeb = 0 (off SMPS) | ||
| 307 | val |= 1 << 14; // sdben = 1 (on Bypass) | ||
| 308 | r.0 = val | ||
| 309 | }); | ||
| 310 | |||
| 311 | cortex_m::asm::delay(1000); | ||
| 312 | |||
| 279 | Ok(()) | 313 | Ok(()) |
| 280 | } | 314 | } |
| 281 | 315 | ||
