diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-05-01 19:32:06 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-01 19:32:06 +0000 |
| commit | 855c0d1423cb1aacd4f4f45e255b02b442afde34 (patch) | |
| tree | 727d6409543c308d2e8cb48fc722c61ed753be9c | |
| parent | 05c36e05f9f6b1a0a36982239b2e7c697f0d3734 (diff) | |
| parent | 0d82ebea29d5bad6d1b40258419a215c44786e1d (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]>
| -rw-r--r-- | embassy-stm32/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/datetime.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/datetime_chrono.rs | 85 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 44 | ||||
| -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.rs | 41 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2f2.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2f3.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2f4.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2f7.rs | 41 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2h7.rs | 33 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2l0.rs | 26 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2l1.rs | 24 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2l4.rs | 41 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2/v2wb.rs | 39 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v3.rs | 81 | ||||
| -rw-r--r-- | examples/stm32f4/Cargo.toml | 1 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/rtc.rs | 30 | ||||
| -rw-r--r-- | tests/stm32/Cargo.toml | 10 | ||||
| -rw-r--r-- | tests/stm32/src/bin/rtc.rs | 52 |
20 files changed, 251 insertions, 534 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; | |||
| 51 | pub mod qspi; | 51 | pub mod qspi; |
| 52 | #[cfg(rng)] | 52 | #[cfg(rng)] |
| 53 | pub mod rng; | 53 | pub 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)))] |
| 55 | pub mod rtc; | 55 | pub mod rtc; |
| 56 | #[cfg(sdmmc)] | 56 | #[cfg(sdmmc)] |
| 57 | pub mod sdmmc; | 57 | pub 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 { | |||
| 51 | impl From<chrono::NaiveDateTime> for DateTime { | 51 | impl 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")] |
| 66 | impl From<DateTime> for chrono::NaiveDateTime { | 66 | impl 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 @@ | |||
| 1 | use chrono::{Datelike, Timelike}; | ||
| 2 | |||
| 3 | use super::byte_to_bcd2; | ||
| 4 | use crate::pac::rtc::Rtc; | ||
| 5 | |||
| 6 | /// Alias for [`chrono::NaiveDateTime`] | ||
| 7 | pub type DateTime = chrono::NaiveDateTime; | ||
| 8 | /// Alias for [`chrono::Weekday`] | ||
| 9 | pub 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)] | ||
| 15 | pub 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 | |||
| 24 | pub(super) fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 { | ||
| 25 | dotw.num_days_from_monday() as u8 | ||
| 26 | } | ||
| 27 | |||
| 28 | pub(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 | |||
| 38 | pub(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 | |||
| 72 | pub(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")] |
| 16 | mod versions; | 16 | mod _version; |
| 17 | pub use _version::*; | ||
| 17 | use embassy_hal_common::Peripheral; | 18 | use embassy_hal_common::Peripheral; |
| 18 | pub 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 | ||
| 114 | impl<'d, T: Instance> Rtc<'d, T> { | 114 | impl<'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 | ||
| 221 | pub(crate) mod sealed { | 221 | pub(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 | ||
| 227 | pub trait Instance: sealed::Instance + 'static {} | 227 | fn regs() -> Rtc { |
| 228 | crate::pac::RTC | ||
| 229 | } | ||
| 228 | 230 | ||
| 229 | impl 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 | ||
| 235 | impl Instance for crate::peripherals::RTC {} | 249 | pub 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 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; |
| 2 | 2 | ||
| 3 | use super::{Instance, RtcConfig}; | 3 | use super::{sealed, Instance, RtcConfig}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use 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")] | ||
| 16 | mod family; | ||
| 17 | |||
| 18 | pub use family::*; | ||
| 19 | |||
| 20 | impl<'d, T: Instance> super::Rtc<'d, T> { | 6 | impl<'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. | 200 | impl 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() { |
| 155 | pub 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 { |
| 167 | pub 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 | |||
| 229 | impl 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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 35 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 29 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 29 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 29 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 35 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 31 | pub(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 @@ | |||
| 1 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 2 | |||
| 3 | /// Unlock the backup domain | ||
| 4 | pub(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 | |||
| 24 | pub(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 @@ | |||
| 1 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 2 | |||
| 3 | /// Unlock the backup domain | ||
| 4 | pub(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 | |||
| 22 | pub(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 @@ | |||
| 1 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 2 | |||
| 3 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 4 | |||
| 5 | /// Unlock the backup domain | ||
| 6 | pub(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 | |||
| 35 | pub(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 @@ | |||
| 1 | pub const BACKUP_REGISTER_COUNT: usize = 20; | ||
| 2 | |||
| 3 | /// Unlock the backup domain | ||
| 4 | pub(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 | |||
| 33 | pub(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 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; | 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; |
| 2 | 2 | ||
| 3 | use super::{Instance, RtcCalibrationCyclePeriod, RtcConfig}; | 3 | use super::{sealed, Instance, RtcCalibrationCyclePeriod, RtcConfig}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | 5 | ||
| 6 | impl<'d, T: Instance> super::Rtc<'d, T> { | 6 | impl<'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 | ||
| 198 | pub(super) unsafe fn enable_peripheral_clk() { | 185 | impl sealed::Instance for crate::peripherals::RTC { |
| 199 | // Nothing to do | 186 | const BACKUP_REGISTER_COUNT: usize = 32; |
| 200 | } | ||
| 201 | 187 | ||
| 202 | pub 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 |
| 208 | pub 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)) } |
| 221 | pub 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 | |||
| 205 | impl Instance for crate::peripherals::RTC {} | ||
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 511a1fa8c..f5f8b632d 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -26,6 +26,7 @@ nb = "1.0.0" | |||
| 26 | embedded-storage = "0.3.0" | 26 | embedded-storage = "0.3.0" |
| 27 | micromath = "2.0.0" | 27 | micromath = "2.0.0" |
| 28 | static_cell = "1.0" | 28 | static_cell = "1.0" |
| 29 | chrono = { version = "^0.4", default-features = false} | ||
| 29 | 30 | ||
| 30 | [profile.release] | 31 | [profile.release] |
| 31 | debug = 2 | 32 | debug = 2 |
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs new file mode 100644 index 000000000..0eca58203 --- /dev/null +++ b/examples/stm32f4/src/bin/rtc.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use chrono::{NaiveDate, NaiveDateTime}; | ||
| 6 | use defmt::*; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 9 | use embassy_time::{Duration, Timer}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let p = embassy_stm32::init(Default::default()); | ||
| 15 | info!("Hello World!"); | ||
| 16 | |||
| 17 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | ||
| 18 | .unwrap() | ||
| 19 | .and_hms_opt(10, 30, 15) | ||
| 20 | .unwrap(); | ||
| 21 | |||
| 22 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 23 | |||
| 24 | rtc.set_datetime(now.into()).expect("datetime not set"); | ||
| 25 | |||
| 26 | // In reality the delay would be much longer | ||
| 27 | Timer::after(Duration::from_millis(20000)).await; | ||
| 28 | |||
| 29 | let _then: NaiveDateTime = rtc.now().unwrap().into(); | ||
| 30 | } | ||
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 84261f8ea..d10d01e29 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [features] | 7 | [features] |
| 8 | stm32f103c8 = ["embassy-stm32/stm32f103c8"] # Blue Pill | 8 | stm32f103c8 = ["embassy-stm32/stm32f103c8"] # Blue Pill |
| 9 | stm32f429zi = ["embassy-stm32/stm32f429zi", "sdmmc"] # Nucleo | 9 | stm32f429zi = ["embassy-stm32/stm32f429zi", "sdmmc", "chrono"] # Nucleo |
| 10 | stm32g071rb = ["embassy-stm32/stm32g071rb"] # Nucleo | 10 | stm32g071rb = ["embassy-stm32/stm32g071rb"] # Nucleo |
| 11 | stm32c031c6 = ["embassy-stm32/stm32c031c6"] # Nucleo | 11 | stm32c031c6 = ["embassy-stm32/stm32c031c6"] # Nucleo |
| 12 | stm32g491re = ["embassy-stm32/stm32g491re"] # Nucleo | 12 | stm32g491re = ["embassy-stm32/stm32g491re"] # Nucleo |
| @@ -16,6 +16,7 @@ stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo | |||
| 16 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board | 16 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board |
| 17 | 17 | ||
| 18 | sdmmc = [] | 18 | sdmmc = [] |
| 19 | chrono = ["embassy-stm32/chrono", "dep:chrono"] | ||
| 19 | 20 | ||
| 20 | [dependencies] | 21 | [dependencies] |
| 21 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 22 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| @@ -33,6 +34,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10" } | |||
| 33 | embedded-hal-async = { version = "=0.2.0-alpha.1" } | 34 | embedded-hal-async = { version = "=0.2.0-alpha.1" } |
| 34 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 35 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 35 | 36 | ||
| 37 | chrono = { version = "^0.4", default-features = false, optional = true} | ||
| 38 | |||
| 36 | # BEGIN TESTS | 39 | # BEGIN TESTS |
| 37 | # Generated by gen_test.py. DO NOT EDIT. | 40 | # Generated by gen_test.py. DO NOT EDIT. |
| 38 | [[bin]] | 41 | [[bin]] |
| @@ -41,6 +44,11 @@ path = "src/bin/gpio.rs" | |||
| 41 | required-features = [] | 44 | required-features = [] |
| 42 | 45 | ||
| 43 | [[bin]] | 46 | [[bin]] |
| 47 | name = "rtc" | ||
| 48 | path = "src/bin/rtc.rs" | ||
| 49 | required-features = [ "chrono",] | ||
| 50 | |||
| 51 | [[bin]] | ||
| 44 | name = "sdmmc" | 52 | name = "sdmmc" |
| 45 | path = "src/bin/sdmmc.rs" | 53 | path = "src/bin/sdmmc.rs" |
| 46 | required-features = [ "sdmmc",] | 54 | required-features = [ "sdmmc",] |
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs new file mode 100644 index 000000000..ccf2ca609 --- /dev/null +++ b/tests/stm32/src/bin/rtc.rs | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | // required-features: chrono | ||
| 6 | |||
| 7 | #[path = "../example_common.rs"] | ||
| 8 | mod example_common; | ||
| 9 | use chrono::{NaiveDate, NaiveDateTime}; | ||
| 10 | use defmt::assert; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::pac; | ||
| 13 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 14 | use embassy_time::{Duration, Timer}; | ||
| 15 | use example_common::*; | ||
| 16 | |||
| 17 | #[embassy_executor::main] | ||
| 18 | async fn main(_spawner: Spawner) { | ||
| 19 | let p = embassy_stm32::init(config()); | ||
| 20 | info!("Hello World!"); | ||
| 21 | |||
| 22 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | ||
| 23 | .unwrap() | ||
| 24 | .and_hms_opt(10, 30, 15) | ||
| 25 | .unwrap(); | ||
| 26 | |||
| 27 | info!("Starting LSI"); | ||
| 28 | |||
| 29 | unsafe { | ||
| 30 | pac::RCC.csr().modify(|w| w.set_lsion(true)); | ||
| 31 | while !pac::RCC.csr().read().lsirdy() {} | ||
| 32 | } | ||
| 33 | |||
| 34 | info!("Started LSI"); | ||
| 35 | |||
| 36 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 37 | |||
| 38 | rtc.set_datetime(now.into()).expect("datetime not set"); | ||
| 39 | |||
| 40 | info!("Waiting 5 seconds"); | ||
| 41 | Timer::after(Duration::from_millis(5000)).await; | ||
| 42 | |||
| 43 | let then: NaiveDateTime = rtc.now().unwrap().into(); | ||
| 44 | let seconds = (then - now).num_seconds(); | ||
| 45 | |||
| 46 | defmt::info!("measured = {}", seconds); | ||
| 47 | |||
| 48 | assert!(seconds > 3 && seconds < 7); | ||
| 49 | |||
| 50 | info!("Test OK"); | ||
| 51 | cortex_m::asm::bkpt(); | ||
| 52 | } | ||
