diff options
| author | xoviat <[email protected]> | 2025-11-04 16:35:07 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-11-04 16:35:07 -0600 |
| commit | b9559c7713bc7f773cdef0df14f1158840d06d06 (patch) | |
| tree | d5e126d6c2d891bb47375925353e155177954699 /embassy-stm32/src/rtc | |
| parent | d23c027dd1a1c5f7cdf818750dddf6a250658423 (diff) | |
rtc: use consistent api between stop and non-stop
Diffstat (limited to 'embassy-stm32/src/rtc')
| -rw-r--r-- | embassy-stm32/src/rtc/low_power.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 79 |
2 files changed, 60 insertions, 23 deletions
diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs index e09d5afb0..e5bf30927 100644 --- a/embassy-stm32/src/rtc/low_power.rs +++ b/embassy-stm32/src/rtc/low_power.rs | |||
| @@ -4,7 +4,7 @@ use embassy_time::{Duration, TICK_HZ}; | |||
| 4 | use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; | 4 | use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; |
| 5 | use crate::interrupt::typelevel::Interrupt; | 5 | use crate::interrupt::typelevel::Interrupt; |
| 6 | use crate::peripherals::RTC; | 6 | use crate::peripherals::RTC; |
| 7 | use crate::rtc::SealedInstance; | 7 | use crate::rtc::{RtcTimeProvider, SealedInstance}; |
| 8 | 8 | ||
| 9 | /// Represents an instant in time that can be substracted to compute a duration | 9 | /// Represents an instant in time that can be substracted to compute a duration |
| 10 | pub(super) struct RtcInstant { | 10 | pub(super) struct RtcInstant { |
| @@ -117,7 +117,7 @@ impl WakeupPrescaler { | |||
| 117 | impl Rtc { | 117 | impl Rtc { |
| 118 | /// Return the current instant. | 118 | /// Return the current instant. |
| 119 | fn instant(&self) -> Result<RtcInstant, RtcError> { | 119 | fn instant(&self) -> Result<RtcInstant, RtcError> { |
| 120 | self.time_provider().read(|_, tr, ss| { | 120 | RtcTimeProvider::new().read(|_, tr, ss| { |
| 121 | let second = bcd2_to_byte((tr.st(), tr.su())); | 121 | let second = bcd2_to_byte((tr.st(), tr.su())); |
| 122 | 122 | ||
| 123 | RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) | 123 | RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) |
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index fa5b45e3c..cbb904fd3 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -5,7 +5,9 @@ mod datetime; | |||
| 5 | mod low_power; | 5 | mod low_power; |
| 6 | 6 | ||
| 7 | #[cfg(feature = "low-power")] | 7 | #[cfg(feature = "low-power")] |
| 8 | use core::cell::Cell; | 8 | use core::cell::{Cell, RefCell, RefMut}; |
| 9 | #[cfg(feature = "low-power")] | ||
| 10 | use core::ops; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature = "low-power")] | 12 | #[cfg(feature = "low-power")] |
| 11 | use critical_section::CriticalSection; | 13 | use critical_section::CriticalSection; |
| @@ -52,9 +54,8 @@ pub struct RtcTimeProvider { | |||
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | impl RtcTimeProvider { | 56 | impl RtcTimeProvider { |
| 55 | #[cfg(feature = "low-power")] | ||
| 56 | /// Create a new RTC time provider instance. | 57 | /// Create a new RTC time provider instance. |
| 57 | pub fn new(_rtc: Peri<'static, RTC>) -> Self { | 58 | pub(self) const fn new() -> Self { |
| 58 | Self { _private: () } | 59 | Self { _private: () } |
| 59 | } | 60 | } |
| 60 | 61 | ||
| @@ -115,6 +116,50 @@ impl RtcTimeProvider { | |||
| 115 | } | 116 | } |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 119 | #[cfg(feature = "low-power")] | ||
| 120 | /// Contains an RTC driver. | ||
| 121 | pub struct RtcContainer { | ||
| 122 | pub(self) mutex: &'static Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc>>>, | ||
| 123 | } | ||
| 124 | |||
| 125 | #[cfg(feature = "low-power")] | ||
| 126 | impl RtcContainer { | ||
| 127 | pub(self) const fn new() -> Self { | ||
| 128 | Self { | ||
| 129 | mutex: &crate::time_driver::get_driver().rtc, | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | /// Acquire an RTC borrow. | ||
| 134 | pub fn borrow_mut<'a>(&self, cs: CriticalSection<'a>) -> RtcBorrow<'a> { | ||
| 135 | RtcBorrow { | ||
| 136 | ref_mut: self.mutex.borrow(cs).borrow_mut(), | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | #[cfg(feature = "low-power")] | ||
| 142 | /// Contains an RTC borrow. | ||
| 143 | pub struct RtcBorrow<'a> { | ||
| 144 | pub(self) ref_mut: RefMut<'a, Option<Rtc>>, | ||
| 145 | } | ||
| 146 | |||
| 147 | #[cfg(feature = "low-power")] | ||
| 148 | impl<'a> ops::Deref for RtcBorrow<'a> { | ||
| 149 | type Target = Rtc; | ||
| 150 | |||
| 151 | fn deref(&self) -> &Self::Target { | ||
| 152 | self.ref_mut.as_ref().unwrap() | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | #[cfg(feature = "low-power")] | ||
| 157 | impl<'a> ops::DerefMut for RtcBorrow<'a> { | ||
| 158 | fn deref_mut(&mut self) -> &mut Self::Target { | ||
| 159 | self.ref_mut.as_mut().unwrap() | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 118 | /// RTC driver. | 163 | /// RTC driver. |
| 119 | pub struct Rtc { | 164 | pub struct Rtc { |
| 120 | #[cfg(feature = "low-power")] | 165 | #[cfg(feature = "low-power")] |
| @@ -156,8 +201,14 @@ pub enum RtcCalibrationCyclePeriod { | |||
| 156 | impl Rtc { | 201 | impl Rtc { |
| 157 | #[cfg(not(feature = "low-power"))] | 202 | #[cfg(not(feature = "low-power"))] |
| 158 | /// Create a new RTC instance. | 203 | /// Create a new RTC instance. |
| 159 | pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> Self { | 204 | pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> (Self, RtcTimeProvider) { |
| 160 | Self::new_inner(rtc_config) | 205 | (Self::new_inner(rtc_config), RtcTimeProvider::new()) |
| 206 | } | ||
| 207 | |||
| 208 | #[cfg(feature = "low-power")] | ||
| 209 | /// Create a new RTC instance. | ||
| 210 | pub fn new(_rtc: Peri<'static, RTC>) -> (RtcContainer, RtcTimeProvider) { | ||
| 211 | (RtcContainer::new(), RtcTimeProvider::new()) | ||
| 161 | } | 212 | } |
| 162 | 213 | ||
| 163 | pub(self) fn new_inner(rtc_config: RtcConfig) -> Self { | 214 | pub(self) fn new_inner(rtc_config: RtcConfig) -> Self { |
| @@ -179,8 +230,8 @@ impl Rtc { | |||
| 179 | // Wait for the clock to update after initialization | 230 | // Wait for the clock to update after initialization |
| 180 | #[cfg(not(rtc_v2_f2))] | 231 | #[cfg(not(rtc_v2_f2))] |
| 181 | { | 232 | { |
| 182 | let now = this.time_provider().read(|_, _, ss| Ok(ss)).unwrap(); | 233 | let now = RtcTimeProvider::new().read(|_, _, ss| Ok(ss)).unwrap(); |
| 183 | while now == this.time_provider().read(|_, _, ss| Ok(ss)).unwrap() {} | 234 | while now == RtcTimeProvider::new().read(|_, _, ss| Ok(ss)).unwrap() {} |
| 184 | } | 235 | } |
| 185 | 236 | ||
| 186 | #[cfg(feature = "low-power")] | 237 | #[cfg(feature = "low-power")] |
| @@ -194,11 +245,6 @@ impl Rtc { | |||
| 194 | freqs.rtc.to_hertz().unwrap() | 245 | freqs.rtc.to_hertz().unwrap() |
| 195 | } | 246 | } |
| 196 | 247 | ||
| 197 | /// Acquire a [`RtcTimeProvider`] instance. | ||
| 198 | pub const fn time_provider(&self) -> RtcTimeProvider { | ||
| 199 | RtcTimeProvider { _private: () } | ||
| 200 | } | ||
| 201 | |||
| 202 | /// Set the datetime to a new value. | 248 | /// Set the datetime to a new value. |
| 203 | /// | 249 | /// |
| 204 | /// # Errors | 250 | /// # Errors |
| @@ -242,15 +288,6 @@ impl Rtc { | |||
| 242 | Ok(()) | 288 | Ok(()) |
| 243 | } | 289 | } |
| 244 | 290 | ||
| 245 | /// Return the current datetime. | ||
| 246 | /// | ||
| 247 | /// # Errors | ||
| 248 | /// | ||
| 249 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. | ||
| 250 | pub fn now(&self) -> Result<DateTime, RtcError> { | ||
| 251 | self.time_provider().now() | ||
| 252 | } | ||
| 253 | |||
| 254 | /// Check if daylight savings time is active. | 291 | /// Check if daylight savings time is active. |
| 255 | pub fn get_daylight_savings(&self) -> bool { | 292 | pub fn get_daylight_savings(&self) -> bool { |
| 256 | let cr = RTC::regs().cr().read(); | 293 | let cr = RTC::regs().cr().read(); |
