aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-08-27 21:15:57 -0500
committerxoviat <[email protected]>2023-08-27 21:15:57 -0500
commite981cd496827c01cba11fd6ba40b2b7ed482e49b (patch)
tree7c0676bdb67f803af1165ec63d4318e687daab9a /embassy-stm32/src
parent9f928010a86be9e0f8b5fa4257c3edd70261c0dc (diff)
stm32: fix rtc wakeup timing and add dbg
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/low_power.rs7
-rw-r--r--embassy-stm32/src/rcc/f4.rs2
-rw-r--r--embassy-stm32/src/rtc/mod.rs14
-rw-r--r--embassy-stm32/src/rtc/v2.rs43
-rw-r--r--embassy-stm32/src/time_driver.rs2
5 files changed, 56 insertions, 12 deletions
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 65b93f8a4..f9b5fde91 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -89,6 +89,9 @@ impl Executor {
89 89
90 self.time_driver.resume_time(); 90 self.time_driver.resume_time();
91 trace!("low power: resume time"); 91 trace!("low power: resume time");
92
93 #[cfg(feature = "rtc-debug")]
94 cortex_m::asm::bkpt();
92 } 95 }
93 96
94 pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { 97 pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) {
@@ -118,6 +121,7 @@ impl Executor {
118 } 121 }
119 122
120 trace!("low power: enter stop..."); 123 trace!("low power: enter stop...");
124 #[cfg(not(feature = "rtc-debug"))]
121 self.scb.set_sleepdeep(); 125 self.scb.set_sleepdeep();
122 } 126 }
123 127
@@ -140,6 +144,9 @@ impl Executor {
140 /// 144 ///
141 /// This function never returns. 145 /// This function never returns.
142 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { 146 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
147 #[cfg(feature = "rtc-debug")]
148 trace!("low power: rtc debug enabled");
149
143 init(unsafe { EXECUTOR.as_mut().unwrap() }.inner.spawner()); 150 init(unsafe { EXECUTOR.as_mut().unwrap() }.inner.spawner());
144 151
145 loop { 152 loop {
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index 10d3322aa..d8b689e41 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -17,7 +17,7 @@ use crate::{peripherals, Peripheral};
17pub const HSI_FREQ: Hertz = Hertz(16_000_000); 17pub const HSI_FREQ: Hertz = Hertz(16_000_000);
18 18
19/// LSI speed 19/// LSI speed
20pub const LSI_FREQ: Hertz = Hertz(32_000); 20pub const LSI_FREQ: Hertz = Hertz(32_768);
21 21
22/// Clocks configuration 22/// Clocks configuration
23#[non_exhaustive] 23#[non_exhaustive]
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 8bda0926e..496ad5c1e 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -47,6 +47,18 @@ struct RtcInstant {
47 subsecond: u16, 47 subsecond: u16,
48} 48}
49 49
50#[cfg(all(feature = "low-power", feature = "defmt"))]
51impl defmt::Format for RtcInstant {
52 fn format(&self, fmt: defmt::Formatter) {
53 defmt::write!(
54 fmt,
55 "{}:{}",
56 self.second,
57 RTC::regs().prer().read().prediv_s() - self.subsecond,
58 )
59 }
60}
61
50#[cfg(feature = "low-power")] 62#[cfg(feature = "low-power")]
51impl core::ops::Sub for RtcInstant { 63impl core::ops::Sub for RtcInstant {
52 type Output = embassy_time::Duration; 64 type Output = embassy_time::Duration;
@@ -174,7 +186,7 @@ impl Rtc {
174 let second = bcd2_to_byte((tr.st(), tr.su())); 186 let second = bcd2_to_byte((tr.st(), tr.su()));
175 187
176 // Unlock the registers 188 // Unlock the registers
177 r.dr(); 189 r.dr().read();
178 190
179 RtcInstant { second, subsecond } 191 RtcInstant { second, subsecond }
180 } 192 }
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs
index 62b398689..7eb8a96c4 100644
--- a/embassy-stm32/src/rtc/v2.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -1,7 +1,5 @@
1use stm32_metapac::rtc::vals::{Init, Osel, Pol}; 1use stm32_metapac::rtc::vals::{Init, Osel, Pol};
2 2
3#[cfg(feature = "low-power")]
4use super::RtcInstant;
5use super::{sealed, RtcConfig}; 3use super::{sealed, RtcConfig};
6use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
7use crate::peripherals::RTC; 5use crate::peripherals::RTC;
@@ -77,6 +75,21 @@ impl super::Rtc {
77 /// start the wakeup alarm and wtih a duration that is as close to but less than 75 /// start the wakeup alarm and wtih a duration that is as close to but less than
78 /// the requested duration, and record the instant the wakeup alarm was started 76 /// the requested duration, and record the instant the wakeup alarm was started
79 pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) { 77 pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) {
78 #[cfg(feature = "rtc-debug")]
79 if critical_section::with(|cs| {
80 if let Some(instant) = self.stop_time.borrow(cs).take() {
81 self.stop_time.borrow(cs).replace(Some(instant));
82
83 Some(())
84 } else {
85 None
86 }
87 })
88 .is_some()
89 {
90 return;
91 }
92
80 use embassy_time::{Duration, TICK_HZ}; 93 use embassy_time::{Duration, TICK_HZ};
81 94
82 use crate::rcc::get_freqs; 95 use crate::rcc::get_freqs;
@@ -86,17 +99,14 @@ impl super::Rtc {
86 let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ; 99 let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ;
87 let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); 100 let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32);
88 101
89 // adjust the rtc ticks to the prescaler 102 // adjust the rtc ticks to the prescaler and subtract one rtc tick
90 let rtc_ticks = rtc_ticks / (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64); 103 let rtc_ticks = rtc_ticks / (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64);
91 let rtc_ticks = if rtc_ticks >= u16::MAX as u64 { 104 let rtc_ticks = if rtc_ticks >= u16::MAX as u64 {
92 u16::MAX - 1 105 u16::MAX - 1
93 } else { 106 } else {
94 rtc_ticks as u16 107 rtc_ticks as u16
95 }; 108 }
96 109 .saturating_sub(1);
97 let duration = Duration::from_ticks(
98 rtc_ticks as u64 * TICK_HZ * (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64) / rtc_hz,
99 );
100 110
101 self.write(false, |regs| { 111 self.write(false, |regs| {
102 regs.cr().modify(|w| w.set_wute(false)); 112 regs.cr().modify(|w| w.set_wute(false));
@@ -104,11 +114,21 @@ impl super::Rtc {
104 while !regs.isr().read().wutwf() {} 114 while !regs.isr().read().wutwf() {}
105 115
106 regs.cr().modify(|w| w.set_wucksel(prescaler.into())); 116 regs.cr().modify(|w| w.set_wucksel(prescaler.into()));
117 regs.wutr().write(|w| w.set_wut(rtc_ticks));
107 regs.cr().modify(|w| w.set_wute(true)); 118 regs.cr().modify(|w| w.set_wute(true));
108 regs.cr().modify(|w| w.set_wutie(true)); 119 regs.cr().modify(|w| w.set_wutie(true));
109 }); 120 });
110 121
111 trace!("rtc: start wakeup alarm for {} ms", duration.as_millis()); 122 trace!(
123 "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
124 Duration::from_ticks(
125 rtc_ticks as u64 * TICK_HZ * (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64) / rtc_hz,
126 )
127 .as_millis(),
128 <WakeupPrescaler as Into<u32>>::into(prescaler),
129 rtc_ticks,
130 self.instant(),
131 );
112 132
113 critical_section::with(|cs| assert!(self.stop_time.borrow(cs).replace(Some(self.instant())).is_none())) 133 critical_section::with(|cs| assert!(self.stop_time.borrow(cs).replace(Some(self.instant())).is_none()))
114 } 134 }
@@ -119,7 +139,10 @@ impl super::Rtc {
119 pub(crate) fn stop_wakeup_alarm(&self) -> Option<embassy_time::Duration> { 139 pub(crate) fn stop_wakeup_alarm(&self) -> Option<embassy_time::Duration> {
120 use crate::interrupt::typelevel::Interrupt; 140 use crate::interrupt::typelevel::Interrupt;
121 141
122 trace!("rtc: stop wakeup alarm..."); 142 trace!("rtc: stop wakeup alarm at {}", self.instant());
143
144 #[cfg(feature = "rtc-debug")]
145 return None;
123 146
124 self.write(false, |regs| { 147 self.write(false, |regs| {
125 regs.cr().modify(|w| w.set_wutie(false)); 148 regs.cr().modify(|w| w.set_wutie(false));
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 99d423d08..d4442c231 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -363,6 +363,7 @@ impl RtcDriver {
363 .start_wakeup_alarm(time_until_next_alarm); 363 .start_wakeup_alarm(time_until_next_alarm);
364 }); 364 });
365 365
366 #[cfg(not(feature = "rtc-debug"))]
366 T::regs_gp16().cr1().modify(|w| w.set_cen(false)); 367 T::regs_gp16().cr1().modify(|w| w.set_cen(false));
367 368
368 Ok(()) 369 Ok(())
@@ -374,6 +375,7 @@ impl RtcDriver {
374 pub(crate) fn resume_time(&self) { 375 pub(crate) fn resume_time(&self) {
375 self.stop_wakeup_alarm(); 376 self.stop_wakeup_alarm();
376 377
378 #[cfg(not(feature = "rtc-debug"))]
377 T::regs_gp16().cr1().modify(|w| w.set_cen(true)); 379 T::regs_gp16().cr1().modify(|w| w.set_cen(true));
378 } 380 }
379} 381}