aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-10-26 00:11:21 +0000
committerGitHub <[email protected]>2023-10-26 00:11:21 +0000
commitb98a279367b9cfec0f40952379de61907a87fd77 (patch)
treef1322c8ed0e9261ab712bcc108e164d8ec419cf1 /embassy-stm32/src
parent0cc3e18db65dd2d6ae173e94014973741f14e2ee (diff)
parente8a3cfaed6b3e0ee9e77e16caf51d4479c89090f (diff)
Merge pull request #2116 from xoviat/rtc-2
stm32/low-power: refactor refcount
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/lib.rs6
-rw-r--r--embassy-stm32/src/low_power.rs18
-rw-r--r--embassy-stm32/src/rcc/mod.rs24
-rw-r--r--embassy-stm32/src/rtc/mod.rs4
4 files changed, 23 insertions, 29 deletions
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 372246f87..5c7067d2d 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -226,9 +226,9 @@ pub fn init(config: Config) -> Peripherals {
226 time_driver::init(cs); 226 time_driver::init(cs);
227 227
228 #[cfg(feature = "low-power")] 228 #[cfg(feature = "low-power")]
229 while !crate::rcc::low_power_ready() { 229 {
230 crate::rcc::clock_refcount_sub(cs); 230 crate::rcc::REFCOUNT_STOP2 = 0
231 } 231 };
232 } 232 }
233 233
234 p 234 p
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 861a59d7b..d5846f530 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -6,7 +6,6 @@ use cortex_m::peripheral::SCB;
6use embassy_executor::*; 6use embassy_executor::*;
7 7
8use crate::interrupt; 8use crate::interrupt;
9use crate::rcc::low_power_ready;
10use crate::time_driver::{get_driver, RtcDriver}; 9use crate::time_driver::{get_driver, RtcDriver};
11 10
12const THREAD_PENDER: usize = usize::MAX; 11const THREAD_PENDER: usize = usize::MAX;
@@ -33,6 +32,15 @@ pub fn stop_with_rtc(rtc: &'static Rtc) {
33 unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) 32 unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc)
34} 33}
35 34
35pub fn stop_ready(stop_mode: StopMode) -> bool {
36 unsafe { EXECUTOR.as_mut().unwrap() }.stop_ready(stop_mode)
37}
38
39#[non_exhaustive]
40pub enum StopMode {
41 Stop2,
42}
43
36/// Thread mode executor, using WFE/SEV. 44/// Thread mode executor, using WFE/SEV.
37/// 45///
38/// This is the simplest and most common kind of executor. It runs on 46/// This is the simplest and most common kind of executor. It runs on
@@ -80,12 +88,18 @@ impl Executor {
80 trace!("low power: stop with rtc configured"); 88 trace!("low power: stop with rtc configured");
81 } 89 }
82 90
91 fn stop_ready(&self, stop_mode: StopMode) -> bool {
92 match stop_mode {
93 StopMode::Stop2 => unsafe { crate::rcc::REFCOUNT_STOP2 == 0 },
94 }
95 }
96
83 fn configure_pwr(&mut self) { 97 fn configure_pwr(&mut self) {
84 self.scb.clear_sleepdeep(); 98 self.scb.clear_sleepdeep();
85 99
86 compiler_fence(Ordering::SeqCst); 100 compiler_fence(Ordering::SeqCst);
87 101
88 if !low_power_ready() { 102 if !self.stop_ready(StopMode::Stop2) {
89 trace!("low power: not ready to stop"); 103 trace!("low power: not ready to stop");
90 } else if self.time_driver.pause_time().is_err() { 104 } else if self.time_driver.pause_time().is_err() {
91 trace!("low power: failed to pause time"); 105 trace!("low power: failed to pause time");
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 8cf2d6ab0..3b19e4b95 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -23,8 +23,6 @@ pub use mco::*;
23#[cfg_attr(rcc_u5, path = "u5.rs")] 23#[cfg_attr(rcc_u5, path = "u5.rs")]
24#[cfg_attr(rcc_wba, path = "wba.rs")] 24#[cfg_attr(rcc_wba, path = "wba.rs")]
25mod _version; 25mod _version;
26#[cfg(feature = "low-power")]
27use core::sync::atomic::{AtomicU32, Ordering};
28 26
29pub use _version::*; 27pub use _version::*;
30 28
@@ -183,27 +181,7 @@ pub struct Clocks {
183} 181}
184 182
185#[cfg(feature = "low-power")] 183#[cfg(feature = "low-power")]
186static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0); 184pub(crate) static mut REFCOUNT_STOP2: u32 = 0;
187
188#[cfg(feature = "low-power")]
189pub fn low_power_ready() -> bool {
190 // trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst));
191 CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0
192}
193
194#[cfg(feature = "low-power")]
195pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) {
196 // We don't check for overflow because constructing more than u32 peripherals is unlikely
197 let n = CLOCK_REFCOUNT.load(Ordering::Relaxed);
198 CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed);
199}
200
201#[cfg(feature = "low-power")]
202pub(crate) fn clock_refcount_sub(_cs: critical_section::CriticalSection) {
203 let n = CLOCK_REFCOUNT.load(Ordering::Relaxed);
204 assert!(n != 0);
205 CLOCK_REFCOUNT.store(n - 1, Ordering::Relaxed);
206}
207 185
208/// Frozen clock frequencies 186/// Frozen clock frequencies
209/// 187///
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index d77443a9c..3334262f9 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -187,7 +187,9 @@ impl Rtc {
187 critical_section::with(|cs| { 187 critical_section::with(|cs| {
188 <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(cs); 188 <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(cs);
189 #[cfg(feature = "low-power")] 189 #[cfg(feature = "low-power")]
190 crate::rcc::clock_refcount_sub(cs); 190 unsafe {
191 crate::rcc::REFCOUNT_STOP2 -= 1
192 };
191 }); 193 });
192 194
193 let mut this = Self { 195 let mut this = Self {