aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-09-17 17:32:56 +0000
committerGitHub <[email protected]>2023-09-17 17:32:56 +0000
commitcd128c20faaecc685771997cb4a31f2da4722b17 (patch)
tree72c4fa0fad638fb0b9cd01a374a58fdebabf6bc1
parent75cae09e79cbc0d494240235edda13f81e098e18 (diff)
parent087ef918bf9444b41d1260be5f2b475d3499f640 (diff)
Merge pull request #1920 from MabezDev/rtc-time-provider
stm32: Add RtcTimeProvider struct to Rtc module
-rw-r--r--embassy-stm32/src/rtc/mod.rs51
1 files changed, 36 insertions, 15 deletions
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 3ecf477db..a588c8b18 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -82,12 +82,42 @@ impl core::ops::Sub for RtcInstant {
82 } 82 }
83} 83}
84 84
85#[non_exhaustive]
86pub struct RtcTimeProvider;
87
88impl RtcTimeProvider {
89 /// Return the current datetime.
90 ///
91 /// # Errors
92 ///
93 /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`].
94 pub fn now(&self) -> Result<DateTime, RtcError> {
95 let r = RTC::regs();
96 let tr = r.tr().read();
97 let second = bcd2_to_byte((tr.st(), tr.su()));
98 let minute = bcd2_to_byte((tr.mnt(), tr.mnu()));
99 let hour = bcd2_to_byte((tr.ht(), tr.hu()));
100 // Reading either RTC_SSR or RTC_TR locks the values in the higher-order
101 // calendar shadow registers until RTC_DR is read.
102 let dr = r.dr().read();
103
104 let weekday = dr.wdu();
105 let day = bcd2_to_byte((dr.dt(), dr.du()));
106 let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
107 let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
108
109 self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
110 }
111}
112
113#[non_exhaustive]
85/// RTC Abstraction 114/// RTC Abstraction
86pub struct Rtc { 115pub struct Rtc {
87 #[cfg(feature = "low-power")] 116 #[cfg(feature = "low-power")]
88 stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, 117 stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>,
89} 118}
90 119
120#[non_exhaustive]
91#[derive(Copy, Clone, PartialEq)] 121#[derive(Copy, Clone, PartialEq)]
92pub struct RtcConfig { 122pub struct RtcConfig {
93 /// The subsecond counter frequency; default is 256 123 /// The subsecond counter frequency; default is 256
@@ -155,6 +185,11 @@ impl Rtc {
155 Hertz(32_768) 185 Hertz(32_768)
156 } 186 }
157 187
188 /// Acquire a [`RtcTimeProvider`] instance.
189 pub fn time_provider(&self) -> RtcTimeProvider {
190 RtcTimeProvider
191 }
192
158 /// Set the datetime to a new value. 193 /// Set the datetime to a new value.
159 /// 194 ///
160 /// # Errors 195 /// # Errors
@@ -187,21 +222,7 @@ impl Rtc {
187 /// 222 ///
188 /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. 223 /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`].
189 pub fn now(&self) -> Result<DateTime, RtcError> { 224 pub fn now(&self) -> Result<DateTime, RtcError> {
190 let r = RTC::regs(); 225 RtcTimeProvider.now()
191 let tr = r.tr().read();
192 let second = bcd2_to_byte((tr.st(), tr.su()));
193 let minute = bcd2_to_byte((tr.mnt(), tr.mnu()));
194 let hour = bcd2_to_byte((tr.ht(), tr.hu()));
195 // Reading either RTC_SSR or RTC_TR locks the values in the higher-order
196 // calendar shadow registers until RTC_DR is read.
197 let dr = r.dr().read();
198
199 let weekday = dr.wdu();
200 let day = bcd2_to_byte((dr.dt(), dr.du()));
201 let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
202 let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
203
204 self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
205 } 226 }
206 227
207 /// Check if daylight savings time is active. 228 /// Check if daylight savings time is active.