diff options
| author | xoviat <[email protected]> | 2025-12-16 10:55:54 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-12-16 10:55:54 -0600 |
| commit | 8fd8ba633a6d8113e136f2f46b1accfe9fb9f1f0 (patch) | |
| tree | f21ce64335ec1d453ddf57cc47136c9b9b45ce2c /embassy-stm32/src | |
| parent | cf2bbdd9138430fe401a3bcef1a3c9afef851652 (diff) | |
stm32: fix wb stop entry and hsem logic
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/hsem/mod.rs | 27 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 42 |
2 files changed, 57 insertions, 12 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..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 | ||
