diff options
| author | xoviat <[email protected]> | 2023-09-17 17:32:56 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-17 17:32:56 +0000 |
| commit | cd128c20faaecc685771997cb4a31f2da4722b17 (patch) | |
| tree | 72c4fa0fad638fb0b9cd01a374a58fdebabf6bc1 | |
| parent | 75cae09e79cbc0d494240235edda13f81e098e18 (diff) | |
| parent | 087ef918bf9444b41d1260be5f2b475d3499f640 (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.rs | 51 |
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] | ||
| 86 | pub struct RtcTimeProvider; | ||
| 87 | |||
| 88 | impl 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 |
| 86 | pub struct Rtc { | 115 | pub 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)] |
| 92 | pub struct RtcConfig { | 122 | pub 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. |
