aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-05-01 19:32:06 +0000
committerGitHub <[email protected]>2023-05-01 19:32:06 +0000
commit855c0d1423cb1aacd4f4f45e255b02b442afde34 (patch)
tree727d6409543c308d2e8cb48fc722c61ed753be9c /embassy-stm32
parent05c36e05f9f6b1a0a36982239b2e7c697f0d3734 (diff)
parent0d82ebea29d5bad6d1b40258419a215c44786e1d (diff)
Merge #1376
1376: rtc: cleanup and consolidate r=Dirbaio a=xoviat This removes an extra file that I left in, adds an example, and consolidates the files into one 'v2' file. Co-authored-by: xoviat <[email protected]>
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/rtc/datetime.rs18
-rw-r--r--embassy-stm32/src/rtc/datetime_chrono.rs85
-rw-r--r--embassy-stm32/src/rtc/mod.rs44
-rw-r--r--embassy-stm32/src/rtc/v2.rs (renamed from embassy-stm32/src/rtc/v2/mod.rs)124
-rw-r--r--embassy-stm32/src/rtc/v2/v2f0.rs41
-rw-r--r--embassy-stm32/src/rtc/v2/v2f2.rs31
-rw-r--r--embassy-stm32/src/rtc/v2/v2f3.rs31
-rw-r--r--embassy-stm32/src/rtc/v2/v2f4.rs31
-rw-r--r--embassy-stm32/src/rtc/v2/v2f7.rs41
-rw-r--r--embassy-stm32/src/rtc/v2/v2h7.rs33
-rw-r--r--embassy-stm32/src/rtc/v2/v2l0.rs26
-rw-r--r--embassy-stm32/src/rtc/v2/v2l1.rs24
-rw-r--r--embassy-stm32/src/rtc/v2/v2l4.rs41
-rw-r--r--embassy-stm32/src/rtc/v2/v2wb.rs39
-rw-r--r--embassy-stm32/src/rtc/v3.rs81
16 files changed, 159 insertions, 533 deletions
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 599041302..11820b7a0 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -51,7 +51,7 @@ pub mod pwm;
51pub mod qspi; 51pub mod qspi;
52#[cfg(rng)] 52#[cfg(rng)]
53pub mod rng; 53pub mod rng;
54#[cfg(all(rtc, not(any(rtc_v1, rtc_v2f0, rtc_v2f7, rtc_v3, rtc_v3u5))))] 54#[cfg(all(rtc, not(rtc_v1)))]
55pub mod rtc; 55pub mod rtc;
56#[cfg(sdmmc)] 56#[cfg(sdmmc)]
57pub mod sdmmc; 57pub mod sdmmc;
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs
index 6274c1e05..0a590c1bb 100644
--- a/embassy-stm32/src/rtc/datetime.rs
+++ b/embassy-stm32/src/rtc/datetime.rs
@@ -51,7 +51,7 @@ pub struct DateTime {
51impl From<chrono::NaiveDateTime> for DateTime { 51impl From<chrono::NaiveDateTime> for DateTime {
52 fn from(date_time: chrono::NaiveDateTime) -> Self { 52 fn from(date_time: chrono::NaiveDateTime) -> Self {
53 Self { 53 Self {
54 year: (date_time.year() - 1970) as u16, 54 year: date_time.year() as u16,
55 month: date_time.month() as u8, 55 month: date_time.month() as u8,
56 day: date_time.day() as u8, 56 day: date_time.day() as u8,
57 day_of_week: date_time.weekday().into(), 57 day_of_week: date_time.weekday().into(),
@@ -65,14 +65,10 @@ impl From<chrono::NaiveDateTime> for DateTime {
65#[cfg(feature = "chrono")] 65#[cfg(feature = "chrono")]
66impl From<DateTime> for chrono::NaiveDateTime { 66impl From<DateTime> for chrono::NaiveDateTime {
67 fn from(date_time: DateTime) -> Self { 67 fn from(date_time: DateTime) -> Self {
68 NaiveDate::from_ymd_opt( 68 NaiveDate::from_ymd_opt(date_time.year as i32, date_time.month as u32, date_time.day as u32)
69 (date_time.year + 1970) as i32, 69 .unwrap()
70 date_time.month as u32, 70 .and_hms_opt(date_time.hour as u32, date_time.minute as u32, date_time.second as u32)
71 date_time.day as u32, 71 .unwrap()
72 )
73 .unwrap()
74 .and_hms_opt(date_time.hour as u32, date_time.minute as u32, date_time.second as u32)
75 .unwrap()
76 } 72 }
77} 73}
78 74
@@ -159,6 +155,8 @@ pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) {
159 let (yt, yu) = byte_to_bcd2(yr_offset); 155 let (yt, yu) = byte_to_bcd2(yr_offset);
160 156
161 unsafe { 157 unsafe {
158 use crate::pac::rtc::vals::Ampm;
159
162 rtc.tr().write(|w| { 160 rtc.tr().write(|w| {
163 w.set_ht(ht); 161 w.set_ht(ht);
164 w.set_hu(hu); 162 w.set_hu(hu);
@@ -166,7 +164,7 @@ pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) {
166 w.set_mnu(mnu); 164 w.set_mnu(mnu);
167 w.set_st(st); 165 w.set_st(st);
168 w.set_su(su); 166 w.set_su(su);
169 w.set_pm(stm32_metapac::rtc::vals::Ampm::AM); 167 w.set_pm(Ampm::AM);
170 }); 168 });
171 169
172 rtc.dr().write(|w| { 170 rtc.dr().write(|w| {
diff --git a/embassy-stm32/src/rtc/datetime_chrono.rs b/embassy-stm32/src/rtc/datetime_chrono.rs
deleted file mode 100644
index b46316cc9..000000000
--- a/embassy-stm32/src/rtc/datetime_chrono.rs
+++ /dev/null
@@ -1,85 +0,0 @@
1use chrono::{Datelike, Timelike};
2
3use super::byte_to_bcd2;
4use crate::pac::rtc::Rtc;
5
6/// Alias for [`chrono::NaiveDateTime`]
7pub type DateTime = chrono::NaiveDateTime;
8/// Alias for [`chrono::Weekday`]
9pub type DayOfWeek = chrono::Weekday;
10
11/// Errors regarding the [`DateTime`] and [`DateTimeFilter`] structs.
12///
13/// [`DateTimeFilter`]: struct.DateTimeFilter.html
14#[derive(Clone, Debug, PartialEq, Eq)]
15pub enum Error {
16 /// The [DateTime] has an invalid year. The year must be between 0 and 4095.
17 InvalidYear,
18 /// The [DateTime] contains an invalid date.
19 InvalidDate,
20 /// The [DateTime] contains an invalid time.
21 InvalidTime,
22}
23
24pub(super) fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 {
25 dotw.num_days_from_monday() as u8
26}
27
28pub(crate) fn validate_datetime(dt: &DateTime) -> Result<(), Error> {
29 if dt.year() < 0 || dt.year() > 4095 {
30 // rp2040 can't hold these years
31 Err(Error::InvalidYear)
32 } else {
33 // The rest of the chrono date is assumed to be valid
34 Ok(())
35 }
36}
37
38pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) {
39 let (ht, hu) = byte_to_bcd2(t.hour() as u8);
40 let (mnt, mnu) = byte_to_bcd2(t.minute() as u8);
41 let (st, su) = byte_to_bcd2(t.second() as u8);
42
43 let (dt, du) = byte_to_bcd2(t.day() as u8);
44 let (mt, mu) = byte_to_bcd2(t.month() as u8);
45 let yr = t.year() as u16;
46 let yr_offset = (yr - 1970_u16) as u8;
47 let (yt, yu) = byte_to_bcd2(yr_offset);
48
49 unsafe {
50 rtc.tr().write(|w| {
51 w.set_ht(ht);
52 w.set_hu(hu);
53 w.set_mnt(mnt);
54 w.set_mnu(mnu);
55 w.set_st(st);
56 w.set_su(su);
57 w.set_pm(stm32_metapac::rtc::vals::Ampm::AM);
58 });
59
60 rtc.dr().write(|w| {
61 w.set_dt(dt);
62 w.set_du(du);
63 w.set_mt(mt > 0);
64 w.set_mu(mu);
65 w.set_yt(yt);
66 w.set_yu(yu);
67 w.set_wdu(day_of_week_to_u8(t.weekday()));
68 });
69 }
70}
71
72pub(super) fn datetime(
73 year: u16,
74 month: u8,
75 day: u8,
76 _day_of_week: u8,
77 hour: u8,
78 minute: u8,
79 second: u8,
80) -> Result<DateTime, Error> {
81 let date = chrono::NaiveDate::from_ymd_opt(year.into(), month.try_into().unwrap(), day.into())
82 .ok_or(Error::InvalidDate)?;
83 let time = chrono::NaiveTime::from_hms_opt(hour.into(), minute.into(), second.into()).ok_or(Error::InvalidTime)?;
84 Ok(DateTime::new(date, time))
85}
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 170783b2d..962927fb1 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -10,12 +10,12 @@ pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
10 any( 10 any(
11 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb 11 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb
12 ), 12 ),
13 path = "v2/mod.rs" 13 path = "v2.rs"
14)] 14)]
15#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")] 15#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")]
16mod versions; 16mod _version;
17pub use _version::*;
17use embassy_hal_common::Peripheral; 18use embassy_hal_common::Peripheral;
18pub use versions::*;
19 19
20/// Errors that can occur on methods on [RtcClock] 20/// Errors that can occur on methods on [RtcClock]
21#[derive(Clone, Debug, PartialEq, Eq)] 21#[derive(Clone, Debug, PartialEq, Eq)]
@@ -113,7 +113,7 @@ impl Default for RtcCalibrationCyclePeriod {
113 113
114impl<'d, T: Instance> Rtc<'d, T> { 114impl<'d, T: Instance> Rtc<'d, T> {
115 pub fn new(_rtc: impl Peripheral<P = T> + 'd, rtc_config: RtcConfig) -> Self { 115 pub fn new(_rtc: impl Peripheral<P = T> + 'd, rtc_config: RtcConfig) -> Self {
116 unsafe { enable_peripheral_clk() }; 116 unsafe { T::enable_peripheral_clk() };
117 117
118 let mut rtc_struct = Self { 118 let mut rtc_struct = Self {
119 phantom: PhantomData, 119 phantom: PhantomData,
@@ -179,14 +179,14 @@ impl<'d, T: Instance> Rtc<'d, T> {
179 self.rtc_config 179 self.rtc_config
180 } 180 }
181 181
182 pub const BACKUP_REGISTER_COUNT: usize = BACKUP_REGISTER_COUNT; 182 pub const BACKUP_REGISTER_COUNT: usize = T::BACKUP_REGISTER_COUNT;
183 183
184 /// Read content of the backup register. 184 /// Read content of the backup register.
185 /// 185 ///
186 /// The registers retain their values during wakes from standby mode or system resets. They also 186 /// The registers retain their values during wakes from standby mode or system resets. They also
187 /// retain their value when Vdd is switched off as long as V_BAT is powered. 187 /// retain their value when Vdd is switched off as long as V_BAT is powered.
188 pub fn read_backup_register(&self, register: usize) -> Option<u32> { 188 pub fn read_backup_register(&self, register: usize) -> Option<u32> {
189 read_backup_register(&T::regs(), register) 189 T::read_backup_register(&T::regs(), register)
190 } 190 }
191 191
192 /// Set content of the backup register. 192 /// Set content of the backup register.
@@ -194,7 +194,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
194 /// The registers retain their values during wakes from standby mode or system resets. They also 194 /// The registers retain their values during wakes from standby mode or system resets. They also
195 /// retain their value when Vdd is switched off as long as V_BAT is powered. 195 /// retain their value when Vdd is switched off as long as V_BAT is powered.
196 pub fn write_backup_register(&self, register: usize, value: u32) { 196 pub fn write_backup_register(&self, register: usize, value: u32) {
197 write_backup_register(&T::regs(), register, value) 197 T::write_backup_register(&T::regs(), register, value)
198 } 198 }
199} 199}
200 200
@@ -219,17 +219,31 @@ pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
219} 219}
220 220
221pub(crate) mod sealed { 221pub(crate) mod sealed {
222 use crate::pac::rtc::Rtc;
223
222 pub trait Instance { 224 pub trait Instance {
223 fn regs() -> crate::pac::rtc::Rtc; 225 const BACKUP_REGISTER_COUNT: usize;
224 }
225}
226 226
227pub trait Instance: sealed::Instance + 'static {} 227 fn regs() -> Rtc {
228 crate::pac::RTC
229 }
228 230
229impl sealed::Instance for crate::peripherals::RTC { 231 unsafe fn enable_peripheral_clk() {}
230 fn regs() -> crate::pac::rtc::Rtc { 232
231 crate::pac::RTC 233 /// Read content of the backup register.
234 ///
235 /// The registers retain their values during wakes from standby mode or system resets. They also
236 /// retain their value when Vdd is switched off as long as V_BAT is powered.
237 fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32>;
238
239 /// Set content of the backup register.
240 ///
241 /// The registers retain their values during wakes from standby mode or system resets. They also
242 /// retain their value when Vdd is switched off as long as V_BAT is powered.
243 fn write_backup_register(rtc: &Rtc, register: usize, value: u32);
244
245 // fn apply_config(&mut self, rtc_config: RtcConfig);
232 } 246 }
233} 247}
234 248
235impl Instance for crate::peripherals::RTC {} 249pub trait Instance: sealed::Instance + 'static {}
diff --git a/embassy-stm32/src/rtc/v2/mod.rs b/embassy-stm32/src/rtc/v2.rs
index 296adae89..adaafe67a 100644
--- a/embassy-stm32/src/rtc/v2/mod.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -1,29 +1,78 @@
1use stm32_metapac::rtc::vals::{Init, Osel, Pol}; 1use stm32_metapac::rtc::vals::{Init, Osel, Pol};
2 2
3use super::{Instance, RtcConfig}; 3use super::{sealed, Instance, RtcConfig};
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5 5
6#[cfg_attr(rtc_v2f0, path = "v2f0.rs")]
7#[cfg_attr(rtc_v2f2, path = "v2f2.rs")]
8#[cfg_attr(rtc_v2f3, path = "v2f3.rs")]
9#[cfg_attr(rtc_v2f4, path = "v2f4.rs")]
10#[cfg_attr(rtc_v2f7, path = "v2f7.rs")]
11#[cfg_attr(rtc_v2h7, path = "v2h7.rs")]
12#[cfg_attr(rtc_v2l0, path = "v2l0.rs")]
13#[cfg_attr(rtc_v2l1, path = "v2l1.rs")]
14#[cfg_attr(rtc_v2l4, path = "v2l4.rs")]
15#[cfg_attr(rtc_v2wb, path = "v2wb.rs")]
16mod family;
17
18pub use family::*;
19
20impl<'d, T: Instance> super::Rtc<'d, T> { 6impl<'d, T: Instance> super::Rtc<'d, T> {
21 /// Applies the RTC config 7 /// Applies the RTC config
22 /// It this changes the RTC clock source the time will be reset 8 /// It this changes the RTC clock source the time will be reset
23 pub(super) fn apply_config(&mut self, rtc_config: RtcConfig) { 9 pub(super) fn apply_config(&mut self, rtc_config: RtcConfig) {
24 // Unlock the backup domain 10 // Unlock the backup domain
25 unsafe { 11 unsafe {
26 unlock_backup_domain(rtc_config.clock_config as u8); 12 let clock_config = rtc_config.clock_config as u8;
13
14 #[cfg(not(rtc_v2wb))]
15 use stm32_metapac::rcc::vals::Rtcsel;
16
17 #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))]
18 let cr = crate::pac::PWR.cr();
19 #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))]
20 let cr = crate::pac::PWR.cr1();
21
22 // TODO: Missing from PAC for l0 and f0?
23 #[cfg(not(any(rtc_v2f0, rtc_v2l0)))]
24 {
25 cr.modify(|w| w.set_dbp(true));
26 while !cr.read().dbp() {}
27 }
28
29 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
30 let reg = crate::pac::RCC.bdcr().read();
31 #[cfg(any(rtc_v2l0, rtc_v2l1))]
32 let reg = crate::pac::RCC.csr().read();
33
34 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))]
35 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
36
37 #[cfg(rtc_v2wb)]
38 let rtcsel = reg.rtcsel();
39 #[cfg(not(rtc_v2wb))]
40 let rtcsel = reg.rtcsel().0;
41
42 if !reg.rtcen() || rtcsel != clock_config {
43 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
44 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
45
46 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
47 let cr = crate::pac::RCC.bdcr();
48 #[cfg(any(rtc_v2l0, rtc_v2l1))]
49 let cr = crate::pac::RCC.csr();
50
51 cr.modify(|w| {
52 // Reset
53 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
54 w.set_bdrst(false);
55
56 // Select RTC source
57 #[cfg(not(rtc_v2wb))]
58 w.set_rtcsel(Rtcsel(clock_config));
59 #[cfg(rtc_v2wb)]
60 w.set_rtcsel(clock_config);
61 w.set_rtcen(true);
62
63 // Restore bcdr
64 #[cfg(any(rtc_v2l4, rtc_v2wb))]
65 w.set_lscosel(reg.lscosel());
66 #[cfg(any(rtc_v2l4, rtc_v2wb))]
67 w.set_lscoen(reg.lscoen());
68
69 w.set_lseon(reg.lseon());
70
71 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))]
72 w.set_lsedrv(reg.lsedrv());
73 w.set_lsebyp(reg.lsebyp());
74 });
75 }
27 } 76 }
28 77
29 self.write(true, |rtc| unsafe { 78 self.write(true, |rtc| unsafe {
@@ -148,24 +197,33 @@ impl<'d, T: Instance> super::Rtc<'d, T> {
148 } 197 }
149} 198}
150 199
151/// Read content of the backup register. 200impl sealed::Instance for crate::peripherals::RTC {
152/// 201 const BACKUP_REGISTER_COUNT: usize = 20;
153/// The registers retain their values during wakes from standby mode or system resets. They also 202
154/// retain their value when Vdd is switched off as long as V_BAT is powered. 203 unsafe fn enable_peripheral_clk() {
155pub fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> { 204 #[cfg(any(rtc_v2l4, rtc_v2wb))]
156 if register < BACKUP_REGISTER_COUNT { 205 {
157 Some(unsafe { rtc.bkpr(register).read().bkp() }) 206 // enable peripheral clock for communication
158 } else { 207 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
159 None 208
209 // read to allow the pwr clock to enable
210 crate::pac::PWR.cr1().read();
211 }
160 } 212 }
161}
162 213
163/// Set content of the backup register. 214 fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> {
164/// 215 if register < Self::BACKUP_REGISTER_COUNT {
165/// The registers retain their values during wakes from standby mode or system resets. They also 216 Some(unsafe { rtc.bkpr(register).read().bkp() })
166/// retain their value when Vdd is switched off as long as V_BAT is powered. 217 } else {
167pub fn write_backup_register(rtc: &Rtc, register: usize, value: u32) { 218 None
168 if register < BACKUP_REGISTER_COUNT { 219 }
169 unsafe { rtc.bkpr(register).write(|w| w.set_bkp(value)) } 220 }
221
222 fn write_backup_register(rtc: &Rtc, register: usize, value: u32) {
223 if register < Self::BACKUP_REGISTER_COUNT {
224 unsafe { rtc.bkpr(register).write(|w| w.set_bkp(value)) }
225 }
170 } 226 }
171} 227}
228
229impl Instance for crate::peripherals::RTC {}
diff --git a/embassy-stm32/src/rtc/v2/v2f0.rs b/embassy-stm32/src/rtc/v2/v2f0.rs
deleted file mode 100644
index d6871d91e..000000000
--- a/embassy-stm32/src/rtc/v2/v2f0.rs
+++ /dev/null
@@ -1,41 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr1().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
12
13 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
14 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
15
16 crate::pac::RCC.bdcr().modify(|w| {
17 // Reset
18 w.set_bdrst(false);
19
20 // Select RTC source
21 w.set_rtcsel(Rtcsel(clock_config));
22 w.set_rtcen(true);
23
24 // Restore bcdr
25 w.set_lscosel(reg.lscosel());
26 w.set_lscoen(reg.lscoen());
27
28 w.set_lseon(reg.lseon());
29 w.set_lsedrv(reg.lsedrv());
30 w.set_lsebyp(reg.lsebyp());
31 });
32 }
33}
34
35pub(crate) unsafe fn enable_peripheral_clk() {
36 // enable peripheral clock for communication
37 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
38
39 // read to allow the pwr clock to enable
40 crate::pac::PWR.cr1().read();
41}
diff --git a/embassy-stm32/src/rtc/v2/v2f2.rs b/embassy-stm32/src/rtc/v2/v2f2.rs
deleted file mode 100644
index e041f3f4e..000000000
--- a/embassy-stm32/src/rtc/v2/v2f2.rs
+++ /dev/null
@@ -1,31 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11
12 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
13 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
14
15 crate::pac::RCC.bdcr().modify(|w| {
16 // Reset
17 w.set_bdrst(false);
18
19 // Select RTC source
20 w.set_rtcsel(Rtcsel(clock_config));
21 w.set_rtcen(true);
22
23 w.set_lseon(reg.lseon());
24 w.set_lsebyp(reg.lsebyp());
25 });
26 }
27}
28
29pub(crate) unsafe fn enable_peripheral_clk() {
30 // Nothing to do
31}
diff --git a/embassy-stm32/src/rtc/v2/v2f3.rs b/embassy-stm32/src/rtc/v2/v2f3.rs
deleted file mode 100644
index e041f3f4e..000000000
--- a/embassy-stm32/src/rtc/v2/v2f3.rs
+++ /dev/null
@@ -1,31 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11
12 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
13 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
14
15 crate::pac::RCC.bdcr().modify(|w| {
16 // Reset
17 w.set_bdrst(false);
18
19 // Select RTC source
20 w.set_rtcsel(Rtcsel(clock_config));
21 w.set_rtcen(true);
22
23 w.set_lseon(reg.lseon());
24 w.set_lsebyp(reg.lsebyp());
25 });
26 }
27}
28
29pub(crate) unsafe fn enable_peripheral_clk() {
30 // Nothing to do
31}
diff --git a/embassy-stm32/src/rtc/v2/v2f4.rs b/embassy-stm32/src/rtc/v2/v2f4.rs
deleted file mode 100644
index 4dd21cae4..000000000
--- a/embassy-stm32/src/rtc/v2/v2f4.rs
+++ /dev/null
@@ -1,31 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr1().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11
12 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
13 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
14
15 crate::pac::RCC.bdcr().modify(|w| {
16 // Reset
17 w.set_bdrst(false);
18
19 // Select RTC source
20 w.set_rtcsel(Rtcsel(clock_config));
21 w.set_rtcen(true);
22
23 w.set_lseon(reg.lseon());
24 w.set_lsebyp(reg.lsebyp());
25 });
26 }
27}
28
29pub(crate) unsafe fn enable_peripheral_clk() {
30 // Nothing to do
31}
diff --git a/embassy-stm32/src/rtc/v2/v2f7.rs b/embassy-stm32/src/rtc/v2/v2f7.rs
deleted file mode 100644
index d6871d91e..000000000
--- a/embassy-stm32/src/rtc/v2/v2f7.rs
+++ /dev/null
@@ -1,41 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr1().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
12
13 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
14 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
15
16 crate::pac::RCC.bdcr().modify(|w| {
17 // Reset
18 w.set_bdrst(false);
19
20 // Select RTC source
21 w.set_rtcsel(Rtcsel(clock_config));
22 w.set_rtcen(true);
23
24 // Restore bcdr
25 w.set_lscosel(reg.lscosel());
26 w.set_lscoen(reg.lscoen());
27
28 w.set_lseon(reg.lseon());
29 w.set_lsedrv(reg.lsedrv());
30 w.set_lsebyp(reg.lsebyp());
31 });
32 }
33}
34
35pub(crate) unsafe fn enable_peripheral_clk() {
36 // enable peripheral clock for communication
37 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
38
39 // read to allow the pwr clock to enable
40 crate::pac::PWR.cr1().read();
41}
diff --git a/embassy-stm32/src/rtc/v2/v2h7.rs b/embassy-stm32/src/rtc/v2/v2h7.rs
deleted file mode 100644
index f3b180683..000000000
--- a/embassy-stm32/src/rtc/v2/v2h7.rs
+++ /dev/null
@@ -1,33 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr1().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
12
13 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
14 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
15
16 crate::pac::RCC.bdcr().modify(|w| {
17 // Reset
18 w.set_bdrst(false);
19
20 // Select RTC source
21 w.set_rtcsel(Rtcsel(clock_config));
22 w.set_rtcen(true);
23
24 w.set_lseon(reg.lseon());
25 w.set_lsedrv(reg.lsedrv());
26 w.set_lsebyp(reg.lsebyp());
27 });
28 }
29}
30
31pub(crate) unsafe fn enable_peripheral_clk() {
32 // Nothing to do
33}
diff --git a/embassy-stm32/src/rtc/v2/v2l0.rs b/embassy-stm32/src/rtc/v2/v2l0.rs
deleted file mode 100644
index dbd3b0882..000000000
--- a/embassy-stm32/src/rtc/v2/v2l0.rs
+++ /dev/null
@@ -1,26 +0,0 @@
1pub const BACKUP_REGISTER_COUNT: usize = 20;
2
3/// Unlock the backup domain
4pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
5 // TODO: Missing from PAC?
6 // crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
7 // while !crate::pac::PWR.cr().read().dbp() {}
8
9 let reg = crate::pac::RCC.csr().read();
10
11 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
12 crate::pac::RCC.csr().modify(|w| {
13 // Select RTC source
14 w.set_rtcsel(crate::pac::rcc::vals::Rtcsel(clock_config));
15 w.set_rtcen(true);
16
17 w.set_lseon(reg.lseon());
18 w.set_lsedrv(reg.lsedrv());
19 w.set_lsebyp(reg.lsebyp());
20 });
21 }
22}
23
24pub(crate) unsafe fn enable_peripheral_clk() {
25 // Nothing to do
26}
diff --git a/embassy-stm32/src/rtc/v2/v2l1.rs b/embassy-stm32/src/rtc/v2/v2l1.rs
deleted file mode 100644
index 1ac78b31a..000000000
--- a/embassy-stm32/src/rtc/v2/v2l1.rs
+++ /dev/null
@@ -1,24 +0,0 @@
1pub const BACKUP_REGISTER_COUNT: usize = 20;
2
3/// Unlock the backup domain
4pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
5 crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
6 while !crate::pac::PWR.cr().read().dbp() {}
7
8 let reg = crate::pac::RCC.csr().read();
9
10 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
11 crate::pac::RCC.csr().modify(|w| {
12 // Select RTC source
13 w.set_rtcsel(crate::pac::rcc::vals::Rtcsel(clock_config));
14 w.set_rtcen(true);
15
16 w.set_lseon(reg.lseon());
17 w.set_lsebyp(reg.lsebyp());
18 });
19 }
20}
21
22pub(crate) unsafe fn enable_peripheral_clk() {
23 // Nothing to do
24}
diff --git a/embassy-stm32/src/rtc/v2/v2l4.rs b/embassy-stm32/src/rtc/v2/v2l4.rs
deleted file mode 100644
index d6871d91e..000000000
--- a/embassy-stm32/src/rtc/v2/v2l4.rs
+++ /dev/null
@@ -1,41 +0,0 @@
1use stm32_metapac::rcc::vals::Rtcsel;
2
3pub const BACKUP_REGISTER_COUNT: usize = 20;
4
5/// Unlock the backup domain
6pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
7 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
8 while !crate::pac::PWR.cr1().read().dbp() {}
9
10 let reg = crate::pac::RCC.bdcr().read();
11 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
12
13 if !reg.rtcen() || reg.rtcsel().0 != clock_config {
14 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
15
16 crate::pac::RCC.bdcr().modify(|w| {
17 // Reset
18 w.set_bdrst(false);
19
20 // Select RTC source
21 w.set_rtcsel(Rtcsel(clock_config));
22 w.set_rtcen(true);
23
24 // Restore bcdr
25 w.set_lscosel(reg.lscosel());
26 w.set_lscoen(reg.lscoen());
27
28 w.set_lseon(reg.lseon());
29 w.set_lsedrv(reg.lsedrv());
30 w.set_lsebyp(reg.lsebyp());
31 });
32 }
33}
34
35pub(crate) unsafe fn enable_peripheral_clk() {
36 // enable peripheral clock for communication
37 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
38
39 // read to allow the pwr clock to enable
40 crate::pac::PWR.cr1().read();
41}
diff --git a/embassy-stm32/src/rtc/v2/v2wb.rs b/embassy-stm32/src/rtc/v2/v2wb.rs
deleted file mode 100644
index 98761fa60..000000000
--- a/embassy-stm32/src/rtc/v2/v2wb.rs
+++ /dev/null
@@ -1,39 +0,0 @@
1pub const BACKUP_REGISTER_COUNT: usize = 20;
2
3/// Unlock the backup domain
4pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
5 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
6 while !crate::pac::PWR.cr1().read().dbp() {}
7
8 let reg = crate::pac::RCC.bdcr().read();
9 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
10
11 if !reg.rtcen() || reg.rtcsel() != clock_config {
12 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
13
14 crate::pac::RCC.bdcr().modify(|w| {
15 // Reset
16 w.set_bdrst(false);
17
18 // Select RTC source
19 w.set_rtcsel(clock_config);
20 w.set_rtcen(true);
21
22 // Restore bcdr
23 w.set_lscosel(reg.lscosel());
24 w.set_lscoen(reg.lscoen());
25
26 w.set_lseon(reg.lseon());
27 w.set_lsedrv(reg.lsedrv());
28 w.set_lsebyp(reg.lsebyp());
29 });
30 }
31}
32
33pub(crate) unsafe fn enable_peripheral_clk() {
34 // enable peripheral clock for communication
35 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
36
37 // read to allow the pwr clock to enable
38 crate::pac::PWR.cr1().read();
39}
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 6998c48c2..19c52ee02 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -1,6 +1,6 @@
1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; 1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType};
2 2
3use super::{Instance, RtcCalibrationCyclePeriod, RtcConfig}; 3use super::{sealed, Instance, RtcCalibrationCyclePeriod, RtcConfig};
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5 5
6impl<'d, T: Instance> super::Rtc<'d, T> { 6impl<'d, T: Instance> super::Rtc<'d, T> {
@@ -9,43 +9,30 @@ impl<'d, T: Instance> super::Rtc<'d, T> {
9 pub(super) fn apply_config(&mut self, rtc_config: RtcConfig) { 9 pub(super) fn apply_config(&mut self, rtc_config: RtcConfig) {
10 // Unlock the backup domain 10 // Unlock the backup domain
11 unsafe { 11 unsafe {
12 #[cfg(feature = "stm32g0c1ve")] 12 #[cfg(any(rtc_v3u5, rcc_g0))]
13 use crate::pac::rcc::vals::Rtcsel;
14 #[cfg(not(any(rtc_v3u5, rcc_g0, rcc_g4, rcc_wl5, rcc_wle)))]
15 use crate::pac::rtc::vals::Rtcsel;
16
17 #[cfg(not(any(rtc_v3u5, rcc_wl5, rcc_wle)))]
13 { 18 {
14 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true)); 19 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
15 while !crate::pac::PWR.cr1().read().dbp() {} 20 while !crate::pac::PWR.cr1().read().dbp() {}
16 } 21 }
17 22 #[cfg(any(rcc_wl5, rcc_wle))]
18 #[cfg(not(any(
19 feature = "stm32g0c1ve",
20 feature = "stm32g491re",
21 feature = "stm32u585zi",
22 feature = "stm32g473cc"
23 )))]
24 { 23 {
25 crate::pac::PWR 24 use crate::pac::pwr::vals::Dbp;
26 .cr1() 25
27 .modify(|w| w.set_dbp(stm32_metapac::pwr::vals::Dbp::ENABLED)); 26 crate::pac::PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED));
28 while crate::pac::PWR.cr1().read().dbp() != stm32_metapac::pwr::vals::Dbp::DISABLED {} 27 while crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED {}
29 } 28 }
30 29
31 let reg = crate::pac::RCC.bdcr().read(); 30 let reg = crate::pac::RCC.bdcr().read();
32 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); 31 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
33 32
34 let config_rtcsel = rtc_config.clock_config as u8; 33 let config_rtcsel = rtc_config.clock_config as u8;
35 #[cfg(not(any( 34 #[cfg(not(any(rcc_wl5, rcc_wle, rcc_g4)))]
36 feature = "stm32wl54jc-cm0p", 35 let config_rtcsel = Rtcsel(config_rtcsel);
37 feature = "stm32wle5ub",
38 feature = "stm32g0c1ve",
39 feature = "stm32wl55jc-cm4",
40 feature = "stm32wl55uc-cm4",
41 feature = "stm32g491re",
42 feature = "stm32g473cc",
43 feature = "stm32u585zi",
44 feature = "stm32wle5jb"
45 )))]
46 let config_rtcsel = stm32_metapac::rtc::vals::Rtcsel(config_rtcsel);
47 #[cfg(feature = "stm32g0c1ve")]
48 let config_rtcsel = stm32_metapac::rcc::vals::Rtcsel(config_rtcsel);
49 36
50 if !reg.rtcen() || reg.rtcsel() != config_rtcsel { 37 if !reg.rtcen() || reg.rtcsel() != config_rtcsel {
51 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); 38 crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
@@ -195,32 +182,24 @@ impl<'d, T: Instance> super::Rtc<'d, T> {
195 } 182 }
196} 183}
197 184
198pub(super) unsafe fn enable_peripheral_clk() { 185impl sealed::Instance for crate::peripherals::RTC {
199 // Nothing to do 186 const BACKUP_REGISTER_COUNT: usize = 32;
200}
201 187
202pub const BACKUP_REGISTER_COUNT: usize = 32; 188 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
203 189 if register < Self::BACKUP_REGISTER_COUNT {
204/// Read content of the backup register. 190 //Some(rtc.bkpr()[register].read().bits())
205/// 191 None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
206/// The registers retain their values during wakes from standby mode or system resets. They also 192 } else {
207/// retain their value when Vdd is switched off as long as V_BAT is powered. 193 None
208pub fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> { 194 }
209 if register < BACKUP_REGISTER_COUNT {
210 //Some(rtc.bkpr()[register].read().bits())
211 None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
212 } else {
213 None
214 } 195 }
215}
216 196
217/// Set content of the backup register. 197 fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) {
218/// 198 if register < Self::BACKUP_REGISTER_COUNT {
219/// The registers retain their values during wakes from standby mode or system resets. They also 199 // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
220/// retain their value when Vdd is switched off as long as V_BAT is powered. 200 //unsafe { self.rtc.bkpr()[register].write(|w| w.bits(value)) }
221pub fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) { 201 }
222 if register < BACKUP_REGISTER_COUNT {
223 // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
224 //unsafe { self.rtc.bkpr()[register].write(|w| w.bits(value)) }
225 } 202 }
226} 203}
204
205impl Instance for crate::peripherals::RTC {}