diff options
| author | Matt Ickstadt <[email protected]> | 2023-10-03 16:45:05 -0500 |
|---|---|---|
| committer | Matt Ickstadt <[email protected]> | 2023-10-06 13:28:30 -0500 |
| commit | f01609036ff757ef3f04e568c646a467289d5440 (patch) | |
| tree | 1a1f974ba94cb5f9fe59de9c89b6f3682ed4766a /embassy-stm32/src/rtc | |
| parent | 65ed19aae272d6d6320554446f9187ec2ef8bf39 (diff) | |
h7: implement RTC and LSE clock configuration
Diffstat (limited to 'embassy-stm32/src/rtc')
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 65 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 2 |
2 files changed, 49 insertions, 18 deletions
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 73b78f253..28dde2eb1 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -93,21 +93,50 @@ impl RtcTimeProvider { | |||
| 93 | /// | 93 | /// |
| 94 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. | 94 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. |
| 95 | pub fn now(&self) -> Result<DateTime, RtcError> { | 95 | pub fn now(&self) -> Result<DateTime, RtcError> { |
| 96 | let r = RTC::regs(); | 96 | // For RM0433 we use BYPSHAD=1 to work around errata ES0392 2.19.1 |
| 97 | let tr = r.tr().read(); | 97 | #[cfg(rcc_h7rm0433)] |
| 98 | let second = bcd2_to_byte((tr.st(), tr.su())); | 98 | loop { |
| 99 | let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); | 99 | let r = RTC::regs(); |
| 100 | let hour = bcd2_to_byte((tr.ht(), tr.hu())); | 100 | let ss = r.ssr().read().ss(); |
| 101 | // Reading either RTC_SSR or RTC_TR locks the values in the higher-order | 101 | let dr = r.dr().read(); |
| 102 | // calendar shadow registers until RTC_DR is read. | 102 | let tr = r.tr().read(); |
| 103 | let dr = r.dr().read(); | 103 | |
| 104 | 104 | // If an RTCCLK edge occurs during read we may see inconsistent values | |
| 105 | let weekday = dr.wdu(); | 105 | // so read ssr again and see if it has changed. (see RM0433 Rev 7 46.3.9) |
| 106 | let day = bcd2_to_byte((dr.dt(), dr.du())); | 106 | let ss_after = r.ssr().read().ss(); |
| 107 | let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); | 107 | if ss == ss_after { |
| 108 | let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; | 108 | let second = bcd2_to_byte((tr.st(), tr.su())); |
| 109 | 109 | let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); | |
| 110 | self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) | 110 | let hour = bcd2_to_byte((tr.ht(), tr.hu())); |
| 111 | |||
| 112 | let weekday = dr.wdu(); | ||
| 113 | let day = bcd2_to_byte((dr.dt(), dr.du())); | ||
| 114 | let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); | ||
| 115 | let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; | ||
| 116 | |||
| 117 | return self::datetime::datetime(year, month, day, weekday, hour, minute, second) | ||
| 118 | .map_err(RtcError::InvalidDateTime); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | #[cfg(not(rcc_h7rm0433))] | ||
| 123 | { | ||
| 124 | let r = RTC::regs(); | ||
| 125 | let tr = r.tr().read(); | ||
| 126 | let second = bcd2_to_byte((tr.st(), tr.su())); | ||
| 127 | let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); | ||
| 128 | let hour = bcd2_to_byte((tr.ht(), tr.hu())); | ||
| 129 | // Reading either RTC_SSR or RTC_TR locks the values in the higher-order | ||
| 130 | // calendar shadow registers until RTC_DR is read. | ||
| 131 | let dr = r.dr().read(); | ||
| 132 | |||
| 133 | let weekday = dr.wdu(); | ||
| 134 | let day = bcd2_to_byte((dr.dt(), dr.du())); | ||
| 135 | let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); | ||
| 136 | let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; | ||
| 137 | |||
| 138 | self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) | ||
| 139 | } | ||
| 111 | } | 140 | } |
| 112 | } | 141 | } |
| 113 | 142 | ||
| @@ -175,18 +204,18 @@ impl Rtc { | |||
| 175 | } | 204 | } |
| 176 | 205 | ||
| 177 | fn frequency() -> Hertz { | 206 | fn frequency() -> Hertz { |
| 178 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | 207 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] |
| 179 | let freqs = unsafe { crate::rcc::get_freqs() }; | 208 | let freqs = unsafe { crate::rcc::get_freqs() }; |
| 180 | 209 | ||
| 181 | // Load the clock frequency from the rcc mod, if supported | 210 | // Load the clock frequency from the rcc mod, if supported |
| 182 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | 211 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] |
| 183 | match freqs.rtc { | 212 | match freqs.rtc { |
| 184 | Some(hertz) => hertz, | 213 | Some(hertz) => hertz, |
| 185 | None => freqs.rtc_hse.unwrap(), | 214 | None => freqs.rtc_hse.unwrap(), |
| 186 | } | 215 | } |
| 187 | 216 | ||
| 188 | // Assume the default value, if not supported | 217 | // Assume the default value, if not supported |
| 189 | #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))] | 218 | #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab)))] |
| 190 | Hertz(32_768) | 219 | Hertz(32_768) |
| 191 | } | 220 | } |
| 192 | 221 | ||
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 4974f6ee6..eeb23e1f1 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -157,6 +157,8 @@ impl super::Rtc { | |||
| 157 | w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR); | 157 | w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR); |
| 158 | w.set_osel(Osel::DISABLED); | 158 | w.set_osel(Osel::DISABLED); |
| 159 | w.set_pol(Pol::HIGH); | 159 | w.set_pol(Pol::HIGH); |
| 160 | #[cfg(rcc_h7rm0433)] | ||
| 161 | w.set_bypshad(true); | ||
| 160 | }); | 162 | }); |
| 161 | 163 | ||
| 162 | rtc.prer().modify(|w| { | 164 | rtc.prer().modify(|w| { |
