aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/rtc
diff options
context:
space:
mode:
authorMatt Ickstadt <[email protected]>2023-10-03 16:45:05 -0500
committerMatt Ickstadt <[email protected]>2023-10-06 13:28:30 -0500
commitf01609036ff757ef3f04e568c646a467289d5440 (patch)
tree1a1f974ba94cb5f9fe59de9c89b6f3682ed4766a /embassy-stm32/src/rtc
parent65ed19aae272d6d6320554446f9187ec2ef8bf39 (diff)
h7: implement RTC and LSE clock configuration
Diffstat (limited to 'embassy-stm32/src/rtc')
-rw-r--r--embassy-stm32/src/rtc/mod.rs65
-rw-r--r--embassy-stm32/src/rtc/v2.rs2
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| {