aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/hsem/mod.rs27
-rw-r--r--embassy-stm32/src/low_power.rs42
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> {
94impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for HardwareSemaphoreInterruptHandler<T> { 94impl<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
121impl<'a, T: Instance> Drop for HardwareSemaphoreMutex<'a, T> { 118impl<'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