diff options
| author | xoviat <[email protected]> | 2023-08-27 21:15:57 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-08-27 21:15:57 -0500 |
| commit | e981cd496827c01cba11fd6ba40b2b7ed482e49b (patch) | |
| tree | 7c0676bdb67f803af1165ec63d4318e687daab9a /embassy-stm32/src/rtc | |
| parent | 9f928010a86be9e0f8b5fa4257c3edd70261c0dc (diff) | |
stm32: fix rtc wakeup timing and add dbg
Diffstat (limited to 'embassy-stm32/src/rtc')
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 43 |
2 files changed, 46 insertions, 11 deletions
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"))] | ||
| 51 | impl 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")] |
| 51 | impl core::ops::Sub for RtcInstant { | 63 | impl 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 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; |
| 2 | 2 | ||
| 3 | #[cfg(feature = "low-power")] | ||
| 4 | use super::RtcInstant; | ||
| 5 | use super::{sealed, RtcConfig}; | 3 | use super::{sealed, RtcConfig}; |
| 6 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 7 | use crate::peripherals::RTC; | 5 | use 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)); |
