diff options
| -rw-r--r-- | embassy-stm32/src/hsem/mod.rs | 27 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 46 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 4 |
3 files changed, 61 insertions, 16 deletions
diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs index b5fa3c897..e5c68acbd 100644 --- a/embassy-stm32/src/hsem/mod.rs +++ b/embassy-stm32/src/hsem/mod.rs | |||
| @@ -94,17 +94,14 @@ pub struct HardwareSemaphoreInterruptHandler<T: Instance> { | |||
| 94 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for HardwareSemaphoreInterruptHandler<T> { | 94 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for HardwareSemaphoreInterruptHandler<T> { |
| 95 | unsafe fn on_interrupt() { | 95 | unsafe fn on_interrupt() { |
| 96 | let core_id = CoreId::current(); | 96 | let core_id = CoreId::current(); |
| 97 | let isr = T::regs().isr(core_id.to_index()).read(); | ||
| 97 | 98 | ||
| 98 | for number in 0..5 { | 99 | for number in 0..5 { |
| 99 | if T::regs().isr(core_id.to_index()).read().isf(number as usize) { | 100 | if isr.isf(number as usize) { |
| 100 | T::regs() | 101 | T::regs() |
| 101 | .icr(core_id.to_index()) | 102 | .icr(core_id.to_index()) |
| 102 | .write(|w| w.set_isc(number as usize, true)); | 103 | .write(|w| w.set_isc(number as usize, true)); |
| 103 | 104 | ||
| 104 | T::regs() | ||
| 105 | .ier(core_id.to_index()) | ||
| 106 | .modify(|w| w.set_ise(number as usize, false)); | ||
| 107 | |||
| 108 | T::state().waker_for(number).wake(); | 105 | T::state().waker_for(number).wake(); |
| 109 | } | 106 | } |
| 110 | } | 107 | } |
| @@ -120,6 +117,18 @@ pub struct HardwareSemaphoreMutex<'a, T: Instance> { | |||
| 120 | 117 | ||
| 121 | impl<'a, T: Instance> Drop for HardwareSemaphoreMutex<'a, T> { | 118 | impl<'a, T: Instance> Drop for HardwareSemaphoreMutex<'a, T> { |
| 122 | fn drop(&mut self) { | 119 | fn drop(&mut self) { |
| 120 | let core_id = CoreId::current(); | ||
| 121 | |||
| 122 | T::regs() | ||
| 123 | .icr(core_id.to_index()) | ||
| 124 | .write(|w| w.set_isc(self.index as usize, true)); | ||
| 125 | |||
| 126 | critical_section::with(|_| { | ||
| 127 | T::regs() | ||
| 128 | .ier(core_id.to_index()) | ||
| 129 | .modify(|w| w.set_ise(self.index as usize, false)); | ||
| 130 | }); | ||
| 131 | |||
| 123 | HardwareSemaphoreChannel::<'a, T> { | 132 | HardwareSemaphoreChannel::<'a, T> { |
| 124 | index: self.index, | 133 | index: self.index, |
| 125 | _lifetime: PhantomData, | 134 | _lifetime: PhantomData, |
| @@ -156,9 +165,11 @@ impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { | |||
| 156 | 165 | ||
| 157 | compiler_fence(Ordering::SeqCst); | 166 | compiler_fence(Ordering::SeqCst); |
| 158 | 167 | ||
| 159 | T::regs() | 168 | critical_section::with(|_| { |
| 160 | .ier(core_id.to_index()) | 169 | T::regs() |
| 161 | .modify(|w| w.set_ise(self.index as usize, true)); | 170 | .ier(core_id.to_index()) |
| 171 | .modify(|w| w.set_ise(self.index as usize, true)); | ||
| 172 | }); | ||
| 162 | 173 | ||
| 163 | match self.try_lock(process_id) { | 174 | match self.try_lock(process_id) { |
| 164 | Some(mutex) => Poll::Ready(mutex), | 175 | Some(mutex) => Poll::Ready(mutex), |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 2388abe3c..0cdd7789e 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -124,9 +124,9 @@ impl Into<Lpms> for StopMode { | |||
| 124 | fn into(self) -> Lpms { | 124 | fn into(self) -> Lpms { |
| 125 | match self { | 125 | match self { |
| 126 | StopMode::Stop1 => Lpms::STOP1, | 126 | StopMode::Stop1 => Lpms::STOP1, |
| 127 | #[cfg(not(any(stm32wb, stm32wba)))] | 127 | #[cfg(not(stm32wba))] |
| 128 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP2, | 128 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP2, |
| 129 | #[cfg(any(stm32wb, stm32wba))] | 129 | #[cfg(stm32wba)] |
| 130 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? | 130 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| @@ -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 | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index d25c922d8..753ee1290 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -313,7 +313,7 @@ impl RccInfo { | |||
| 313 | 313 | ||
| 314 | #[allow(dead_code)] | 314 | #[allow(dead_code)] |
| 315 | fn increment_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { | 315 | fn increment_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { |
| 316 | #[cfg(all(stm32wlex, feature = "low-power"))] | 316 | #[cfg(all(any(stm32wlex, stm32wb), feature = "low-power"))] |
| 317 | match self.stop_mode { | 317 | match self.stop_mode { |
| 318 | StopMode::Stop1 | StopMode::Stop2 => increment_stop_refcount(_cs, StopMode::Stop2), | 318 | StopMode::Stop1 | StopMode::Stop2 => increment_stop_refcount(_cs, StopMode::Stop2), |
| 319 | _ => {} | 319 | _ => {} |
| @@ -334,7 +334,7 @@ impl RccInfo { | |||
| 334 | 334 | ||
| 335 | #[allow(dead_code)] | 335 | #[allow(dead_code)] |
| 336 | fn decrement_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { | 336 | fn decrement_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { |
| 337 | #[cfg(all(stm32wlex, feature = "low-power"))] | 337 | #[cfg(all(any(stm32wlex, stm32wb), feature = "low-power"))] |
| 338 | match self.stop_mode { | 338 | match self.stop_mode { |
| 339 | StopMode::Stop1 | StopMode::Stop2 => decrement_stop_refcount(_cs, StopMode::Stop2), | 339 | StopMode::Stop1 | StopMode::Stop2 => decrement_stop_refcount(_cs, StopMode::Stop2), |
| 340 | _ => {} | 340 | _ => {} |
