aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/rtc
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-04 16:35:07 -0600
committerxoviat <[email protected]>2025-11-04 16:35:07 -0600
commitb9559c7713bc7f773cdef0df14f1158840d06d06 (patch)
treed5e126d6c2d891bb47375925353e155177954699 /embassy-stm32/src/rtc
parentd23c027dd1a1c5f7cdf818750dddf6a250658423 (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.rs4
-rw-r--r--embassy-stm32/src/rtc/mod.rs79
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};
4use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; 4use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte};
5use crate::interrupt::typelevel::Interrupt; 5use crate::interrupt::typelevel::Interrupt;
6use crate::peripherals::RTC; 6use crate::peripherals::RTC;
7use crate::rtc::SealedInstance; 7use 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
10pub(super) struct RtcInstant { 10pub(super) struct RtcInstant {
@@ -117,7 +117,7 @@ impl WakeupPrescaler {
117impl Rtc { 117impl 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;
5mod low_power; 5mod low_power;
6 6
7#[cfg(feature = "low-power")] 7#[cfg(feature = "low-power")]
8use core::cell::Cell; 8use core::cell::{Cell, RefCell, RefMut};
9#[cfg(feature = "low-power")]
10use core::ops;
9 11
10#[cfg(feature = "low-power")] 12#[cfg(feature = "low-power")]
11use critical_section::CriticalSection; 13use critical_section::CriticalSection;
@@ -52,9 +54,8 @@ pub struct RtcTimeProvider {
52} 54}
53 55
54impl RtcTimeProvider { 56impl 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.
121pub struct RtcContainer {
122 pub(self) mutex: &'static Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc>>>,
123}
124
125#[cfg(feature = "low-power")]
126impl 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.
143pub struct RtcBorrow<'a> {
144 pub(self) ref_mut: RefMut<'a, Option<Rtc>>,
145}
146
147#[cfg(feature = "low-power")]
148impl<'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")]
157impl<'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.
119pub struct Rtc { 164pub struct Rtc {
120 #[cfg(feature = "low-power")] 165 #[cfg(feature = "low-power")]
@@ -156,8 +201,14 @@ pub enum RtcCalibrationCyclePeriod {
156impl Rtc { 201impl 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();