1use stm32_metapac::rtc::vals::{Osel, Pol};
2
3use super::SealedInstance;
4use crate::pac::rtc::Rtc;
5use crate::peripherals::RTC;
6
7#[allow(dead_code)]
8impl super::Rtc {
9 pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
12 self.write(true, |rtc| {
13 rtc.cr().modify(|w| {
14 #[cfg(not(rtc_v2f2))]
15 w.set_bypshad(true);
16 #[cfg(rtc_v2f2)]
17 w.set_fmt(false);
18 #[cfg(not(rtc_v2f2))]
19 w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR);
20 w.set_osel(Osel::DISABLED);
21 w.set_pol(Pol::HIGH);
22 });
23
24 rtc.prer().modify(|w| {
25 w.set_prediv_s(sync_psc);
26 w.set_prediv_a(async_psc);
27 });
28 });
29 }
30
31 #[cfg(not(rtc_v2f2))]
40 pub fn calibrate(&mut self, mut clock_drift: f32, period: super::RtcCalibrationCyclePeriod) {
41 const RTC_CALR_MIN_PPM: f32 = -487.1;
42 const RTC_CALR_MAX_PPM: f32 = 488.5;
43 const RTC_CALR_RESOLUTION_PPM: f32 = 0.9537;
44
45 if clock_drift < RTC_CALR_MIN_PPM {
46 clock_drift = RTC_CALR_MIN_PPM;
47 } else if clock_drift > RTC_CALR_MAX_PPM {
48 clock_drift = RTC_CALR_MAX_PPM;
49 }
50
51 clock_drift /= RTC_CALR_RESOLUTION_PPM;
52
53 self.write(false, |rtc| {
54 rtc.calr().write(|w| {
55 match period {
56 super::RtcCalibrationCyclePeriod::Seconds8 => {
57 w.set_calw8(stm32_metapac::rtc::vals::Calw8::EIGHT_SECOND);
58 }
59 super::RtcCalibrationCyclePeriod::Seconds16 => {
60 w.set_calw16(stm32_metapac::rtc::vals::Calw16::SIXTEEN_SECOND);
61 }
62 super::RtcCalibrationCyclePeriod::Seconds32 => {
63 }
65 }
66
67 if clock_drift > 0.0 {
74 clock_drift += 0.5;
76
77 w.set_calp(stm32_metapac::rtc::vals::Calp::INCREASE_FREQ);
81 w.set_calm(512 - clock_drift as u16);
82 } else {
83 clock_drift -= 0.5;
85
86 w.set_calp(stm32_metapac::rtc::vals::Calp::NO_CHANGE);
90 w.set_calm((clock_drift * -1.0) as u16);
91 }
92 });
93 })
94 }
95
96 pub(super) fn write<F, R>(&self, init_mode: bool, f: F) -> R
97 where
98 F: FnOnce(crate::pac::rtc::Rtc) -> R,
99 {
100 let r = RTC::regs();
101 r.wpr().write(|w| w.set_key(0xca));
104 r.wpr().write(|w| w.set_key(0x53));
105
106 if init_mode && !r.isr().read().initf() {
108 r.isr().modify(|w| w.set_init(true));
110 while !r.isr().read().initf() {}
113 }
114
115 let result = f(r);
116
117 if init_mode {
118 r.isr().modify(|w| w.set_init(false)); }
120
121 r.wpr().write(|w| w.set_key(0xff));
124 result
125 }
126}
127
128impl SealedInstance for crate::peripherals::RTC {
129 const BACKUP_REGISTER_COUNT: usize = 20;
130
131 #[cfg(all(feature = "low-power", stm32f4))]
132 const EXTI_WAKEUP_LINE: usize = 22;
133
134 #[cfg(all(feature = "low-power", stm32l4))]
135 const EXTI_WAKEUP_LINE: usize = 20;
136
137 #[cfg(all(feature = "low-power", stm32l0))]
138 const EXTI_WAKEUP_LINE: usize = 20;
139
140 #[cfg(all(feature = "low-power", any(stm32f4, stm32l4)))]
141 type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
142
143 #[cfg(all(feature = "low-power", stm32l0))]
144 type WakeupInterrupt = crate::interrupt::typelevel::RTC;
145
146 fn read_backup_register(rtc: Rtc, register: usize) -> Option<u32> {
147 if register < Self::BACKUP_REGISTER_COUNT {
148 Some(rtc.bkpr(register).read().bkp())
149 } else {
150 None
151 }
152 }
153
154 fn write_backup_register(rtc: Rtc, register: usize, value: u32) {
155 if register < Self::BACKUP_REGISTER_COUNT {
156 rtc.bkpr(register).write(|w| w.set_bkp(value));
157 }
158 }
159}