aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-08-22 20:00:00 -0500
committerxoviat <[email protected]>2023-08-22 20:00:00 -0500
commit1ea4c58c39d831408d7584be3f37b9f2d880d4ca (patch)
tree934d3c3d402f4fb47c4f86be0911b9925d349e44
parentfaab2d0d53d52f7f311d3958e7e72dd1ee66c3b7 (diff)
stm32: impl. draft cfgr pwr
-rw-r--r--embassy-stm32/src/low_power.rs63
-rw-r--r--embassy-stm32/src/rtc/v2.rs8
2 files changed, 60 insertions, 11 deletions
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 3fe28b9df..7d5093b61 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -1,15 +1,33 @@
1use core::arch::asm; 1use core::arch::asm;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3 3
4use cortex_m::peripheral::SCB;
4use embassy_executor::*; 5use embassy_executor::*;
6use embassy_time::Duration;
7
8use crate::interrupt;
9use crate::interrupt::typelevel::Interrupt;
5 10
6const THREAD_PENDER: usize = usize::MAX; 11const THREAD_PENDER: usize = usize::MAX;
12const THRESHOLD: Duration = Duration::from_millis(500);
7 13
8use crate::rtc::{Rtc, RtcInstant}; 14use crate::rtc::{Rtc, RtcInstant};
9 15
10static mut RTC: Option<&'static Rtc> = None; 16static mut RTC: Option<&'static Rtc> = None;
11 17
18foreach_interrupt! {
19 (RTC, rtc, $block:ident, WKUP, $irq:ident) => {
20 #[interrupt]
21 unsafe fn $irq() {
22 Executor::on_wakeup_irq();
23 }
24 };
25}
26
12pub fn stop_with_rtc(rtc: &'static Rtc) { 27pub fn stop_with_rtc(rtc: &'static Rtc) {
28 crate::interrupt::typelevel::RTC_WKUP::unpend();
29 unsafe { crate::interrupt::typelevel::RTC_WKUP::enable() };
30
13 unsafe { RTC = Some(rtc) }; 31 unsafe { RTC = Some(rtc) };
14} 32}
15 33
@@ -45,8 +63,47 @@ impl Executor {
45 } 63 }
46 } 64 }
47 65
48 fn configure_power(&self) { 66 unsafe fn on_wakeup_irq() {
49 todo!() 67 info!("on wakeup irq");
68
69 cortex_m::asm::bkpt();
70 }
71
72 fn low_power_ready(&self) -> bool {
73 true
74 }
75
76 fn time_until_next_alarm(&self) -> Duration {
77 Duration::from_secs(3)
78 }
79
80 fn get_scb(&self) -> SCB {
81 unsafe { cortex_m::Peripherals::steal() }.SCB
82 }
83
84 fn configure_pwr(&self) {
85 trace!("low power before wfe");
86
87 if !self.low_power_ready() {
88 return;
89 }
90
91 let time_until_next_alarm = self.time_until_next_alarm();
92 if time_until_next_alarm < THRESHOLD {
93 return;
94 }
95
96 trace!("low power stop required");
97
98 critical_section::with(|_| {
99 trace!("executor: set wakeup alarm...");
100
101 start_wakeup_alarm(time_until_next_alarm);
102
103 trace!("low power wait for rtc ready...");
104
105 self.get_scb().set_sleepdeep();
106 });
50 } 107 }
51 108
52 /// Run the executor. 109 /// Run the executor.
@@ -73,7 +130,7 @@ impl Executor {
73 loop { 130 loop {
74 unsafe { 131 unsafe {
75 self.inner.poll(); 132 self.inner.poll();
76 self.configure_power(); 133 self.configure_pwr();
77 asm!("wfe"); 134 asm!("wfe");
78 }; 135 };
79 } 136 }
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs
index f6565a721..e03c7d2a0 100644
--- a/embassy-stm32/src/rtc/v2.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -165,7 +165,6 @@ impl super::Rtc {
165 pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) -> RtcInstant { 165 pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) -> RtcInstant {
166 use embassy_time::{Duration, TICK_HZ}; 166 use embassy_time::{Duration, TICK_HZ};
167 167
168 use crate::interrupt::typelevel::Interrupt;
169 use crate::rcc::get_freqs; 168 use crate::rcc::get_freqs;
170 169
171 let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64; 170 let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64;
@@ -205,9 +204,6 @@ impl super::Rtc {
205 trace!("wakeup timer enabled"); 204 trace!("wakeup timer enabled");
206 } 205 }
207 206
208 crate::interrupt::typelevel::RTC_WKUP::unpend();
209 unsafe { crate::interrupt::typelevel::RTC_WKUP::enable() };
210
211 RtcInstant::now() 207 RtcInstant::now()
212 } 208 }
213 209
@@ -218,10 +214,6 @@ impl super::Rtc {
218 /// note: this api is exposed for testing purposes until low power is implemented. 214 /// note: this api is exposed for testing purposes until low power is implemented.
219 /// it is not intended to be public 215 /// it is not intended to be public
220 pub(crate) fn stop_wakeup_alarm(&self) -> RtcInstant { 216 pub(crate) fn stop_wakeup_alarm(&self) -> RtcInstant {
221 use crate::interrupt::typelevel::Interrupt;
222
223 crate::interrupt::typelevel::RTC_WKUP::disable();
224
225 trace!("disable wakeup timer..."); 217 trace!("disable wakeup timer...");
226 218
227 RTC::regs().cr().modify(|w| { 219 RTC::regs().cr().modify(|w| {