diff options
| -rw-r--r-- | embassy-stm32/src/rcc/wb.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 52 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 57 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v3.rs | 56 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/rtc.rs | 5 |
5 files changed, 90 insertions, 84 deletions
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index e9b7296d5..ae708b37f 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::rcc::Clocks; | 2 | use crate::rcc::Clocks; |
| 3 | use crate::rtc::{enable as enable_rtc, RtcClockSource}; | 3 | use crate::rtc::{Rtc, RtcClockSource}; |
| 4 | use crate::time::{khz, mhz, Hertz}; | 4 | use crate::time::{khz, mhz, Hertz}; |
| 5 | 5 | ||
| 6 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 6 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, |
| @@ -375,5 +375,5 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 375 | w.set_shdhpre(config.ahb3_pre.into()); | 375 | w.set_shdhpre(config.ahb3_pre.into()); |
| 376 | }); | 376 | }); |
| 377 | 377 | ||
| 378 | config.rtc.map(|clock_source| enable_rtc(clock_source)); | 378 | config.rtc.map(|clock_source| Rtc::set_clock_source(clock_source)); |
| 379 | } | 379 | } |
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 2d54c926d..945bfafd6 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | //! RTC peripheral abstraction | 1 | //! RTC peripheral abstraction |
| 2 | use core::marker::PhantomData; | ||
| 3 | mod datetime; | 2 | mod datetime; |
| 4 | 3 | ||
| 5 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | 4 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; |
| @@ -17,6 +16,9 @@ mod _version; | |||
| 17 | pub use _version::*; | 16 | pub use _version::*; |
| 18 | use embassy_hal_internal::Peripheral; | 17 | use embassy_hal_internal::Peripheral; |
| 19 | 18 | ||
| 19 | use crate::peripherals::RTC; | ||
| 20 | use crate::rtc::sealed::Instance; | ||
| 21 | |||
| 20 | /// Errors that can occur on methods on [RtcClock] | 22 | /// Errors that can occur on methods on [RtcClock] |
| 21 | #[derive(Clone, Debug, PartialEq, Eq)] | 23 | #[derive(Clone, Debug, PartialEq, Eq)] |
| 22 | pub enum RtcError { | 24 | pub enum RtcError { |
| @@ -28,22 +30,10 @@ pub enum RtcError { | |||
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | /// RTC Abstraction | 32 | /// RTC Abstraction |
| 31 | pub struct Rtc<'d, T: Instance> { | 33 | pub struct Rtc { |
| 32 | phantom: PhantomData<&'d mut T>, | ||
| 33 | rtc_config: RtcConfig, | 34 | rtc_config: RtcConfig, |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | #[allow(dead_code)] | ||
| 37 | pub(crate) fn enable(clock_source: RtcClockSource) { | ||
| 38 | Rtc::<crate::peripherals::RTC>::enable(clock_source); | ||
| 39 | } | ||
| 40 | |||
| 41 | #[cfg(feature = "time")] | ||
| 42 | #[allow(dead_code)] | ||
| 43 | pub(crate) fn set_wakeup_timer(_duration: embassy_time::Duration) { | ||
| 44 | todo!() | ||
| 45 | } | ||
| 46 | |||
| 47 | #[derive(Copy, Clone, Debug, PartialEq)] | 37 | #[derive(Copy, Clone, Debug, PartialEq)] |
| 48 | #[repr(u8)] | 38 | #[repr(u8)] |
| 49 | pub enum RtcClockSource { | 39 | pub enum RtcClockSource { |
| @@ -59,8 +49,6 @@ pub enum RtcClockSource { | |||
| 59 | 49 | ||
| 60 | #[derive(Copy, Clone, PartialEq)] | 50 | #[derive(Copy, Clone, PartialEq)] |
| 61 | pub struct RtcConfig { | 51 | pub struct RtcConfig { |
| 62 | /// RTC clock source | ||
| 63 | clock_source: RtcClockSource, | ||
| 64 | /// Asynchronous prescaler factor | 52 | /// Asynchronous prescaler factor |
| 65 | /// This is the asynchronous division factor: | 53 | /// This is the asynchronous division factor: |
| 66 | /// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1) | 54 | /// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1) |
| @@ -78,7 +66,6 @@ impl Default for RtcConfig { | |||
| 78 | /// Raw sub-seconds in 1/256. | 66 | /// Raw sub-seconds in 1/256. |
| 79 | fn default() -> Self { | 67 | fn default() -> Self { |
| 80 | RtcConfig { | 68 | RtcConfig { |
| 81 | clock_source: RtcClockSource::LSI, | ||
| 82 | async_prescaler: 127, | 69 | async_prescaler: 127, |
| 83 | sync_prescaler: 255, | 70 | sync_prescaler: 255, |
| 84 | } | 71 | } |
| @@ -86,12 +73,6 @@ impl Default for RtcConfig { | |||
| 86 | } | 73 | } |
| 87 | 74 | ||
| 88 | impl RtcConfig { | 75 | impl RtcConfig { |
| 89 | /// Sets the clock source of RTC config | ||
| 90 | pub fn clock_source(mut self, clock_source: RtcClockSource) -> Self { | ||
| 91 | self.clock_source = clock_source; | ||
| 92 | self | ||
| 93 | } | ||
| 94 | |||
| 95 | /// Set the asynchronous prescaler of RTC config | 76 | /// Set the asynchronous prescaler of RTC config |
| 96 | pub fn async_prescaler(mut self, prescaler: u8) -> Self { | 77 | pub fn async_prescaler(mut self, prescaler: u8) -> Self { |
| 97 | self.async_prescaler = prescaler; | 78 | self.async_prescaler = prescaler; |
| @@ -122,16 +103,13 @@ impl Default for RtcCalibrationCyclePeriod { | |||
| 122 | } | 103 | } |
| 123 | } | 104 | } |
| 124 | 105 | ||
| 125 | impl<'d, T: Instance> Rtc<'d, T> { | 106 | impl Rtc { |
| 126 | pub fn new(_rtc: impl Peripheral<P = T> + 'd, rtc_config: RtcConfig) -> Self { | 107 | pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { |
| 127 | T::enable_peripheral_clk(); | 108 | RTC::enable_peripheral_clk(); |
| 128 | 109 | ||
| 129 | let mut rtc_struct = Self { | 110 | let mut rtc_struct = Self { rtc_config }; |
| 130 | phantom: PhantomData, | ||
| 131 | rtc_config, | ||
| 132 | }; | ||
| 133 | 111 | ||
| 134 | Self::enable(rtc_config.clock_source); | 112 | Self::enable(); |
| 135 | 113 | ||
| 136 | rtc_struct.configure(rtc_config); | 114 | rtc_struct.configure(rtc_config); |
| 137 | rtc_struct.rtc_config = rtc_config; | 115 | rtc_struct.rtc_config = rtc_config; |
| @@ -157,7 +135,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 157 | /// | 135 | /// |
| 158 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. | 136 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. |
| 159 | pub fn now(&self) -> Result<DateTime, RtcError> { | 137 | pub fn now(&self) -> Result<DateTime, RtcError> { |
| 160 | let r = T::regs(); | 138 | let r = RTC::regs(); |
| 161 | let tr = r.tr().read(); | 139 | let tr = r.tr().read(); |
| 162 | let second = bcd2_to_byte((tr.st(), tr.su())); | 140 | let second = bcd2_to_byte((tr.st(), tr.su())); |
| 163 | let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); | 141 | let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); |
| @@ -176,7 +154,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 176 | 154 | ||
| 177 | /// Check if daylight savings time is active. | 155 | /// Check if daylight savings time is active. |
| 178 | pub fn get_daylight_savings(&self) -> bool { | 156 | pub fn get_daylight_savings(&self) -> bool { |
| 179 | let cr = T::regs().cr().read(); | 157 | let cr = RTC::regs().cr().read(); |
| 180 | cr.bkp() | 158 | cr.bkp() |
| 181 | } | 159 | } |
| 182 | 160 | ||
| @@ -191,14 +169,14 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 191 | self.rtc_config | 169 | self.rtc_config |
| 192 | } | 170 | } |
| 193 | 171 | ||
| 194 | pub const BACKUP_REGISTER_COUNT: usize = T::BACKUP_REGISTER_COUNT; | 172 | pub const BACKUP_REGISTER_COUNT: usize = RTC::BACKUP_REGISTER_COUNT; |
| 195 | 173 | ||
| 196 | /// Read content of the backup register. | 174 | /// Read content of the backup register. |
| 197 | /// | 175 | /// |
| 198 | /// The registers retain their values during wakes from standby mode or system resets. They also | 176 | /// The registers retain their values during wakes from standby mode or system resets. They also |
| 199 | /// retain their value when Vdd is switched off as long as V_BAT is powered. | 177 | /// retain their value when Vdd is switched off as long as V_BAT is powered. |
| 200 | pub fn read_backup_register(&self, register: usize) -> Option<u32> { | 178 | pub fn read_backup_register(&self, register: usize) -> Option<u32> { |
| 201 | T::read_backup_register(&T::regs(), register) | 179 | RTC::read_backup_register(&RTC::regs(), register) |
| 202 | } | 180 | } |
| 203 | 181 | ||
| 204 | /// Set content of the backup register. | 182 | /// Set content of the backup register. |
| @@ -206,7 +184,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 206 | /// The registers retain their values during wakes from standby mode or system resets. They also | 184 | /// The registers retain their values during wakes from standby mode or system resets. They also |
| 207 | /// retain their value when Vdd is switched off as long as V_BAT is powered. | 185 | /// retain their value when Vdd is switched off as long as V_BAT is powered. |
| 208 | pub fn write_backup_register(&self, register: usize, value: u32) { | 186 | pub fn write_backup_register(&self, register: usize, value: u32) { |
| 209 | T::write_backup_register(&T::regs(), register, value) | 187 | RTC::write_backup_register(&RTC::regs(), register, value) |
| 210 | } | 188 | } |
| 211 | } | 189 | } |
| 212 | 190 | ||
| @@ -257,5 +235,3 @@ pub(crate) mod sealed { | |||
| 257 | // fn apply_config(&mut self, rtc_config: RtcConfig); | 235 | // fn apply_config(&mut self, rtc_config: RtcConfig); |
| 258 | } | 236 | } |
| 259 | } | 237 | } |
| 260 | |||
| 261 | pub trait Instance: sealed::Instance + 'static {} | ||
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 743a04d62..5b8960696 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -1,13 +1,12 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; |
| 2 | 2 | ||
| 3 | use super::{sealed, Instance, RtcClockSource, RtcConfig}; | 3 | use super::{sealed, RtcClockSource, RtcConfig}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | ||
| 6 | use crate::rtc::sealed::Instance; | ||
| 5 | 7 | ||
| 6 | impl<'d, T: Instance> super::Rtc<'d, T> { | 8 | impl super::Rtc { |
| 7 | pub(super) fn enable(clock_source: RtcClockSource) { | 9 | fn unlock_registers() { |
| 8 | #[cfg(not(rtc_v2wb))] | ||
| 9 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 10 | |||
| 11 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] | 10 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] |
| 12 | let cr = crate::pac::PWR.cr(); | 11 | let cr = crate::pac::PWR.cr(); |
| 13 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] | 12 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] |
| @@ -16,10 +15,35 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 16 | // TODO: Missing from PAC for l0 and f0? | 15 | // TODO: Missing from PAC for l0 and f0? |
| 17 | #[cfg(not(any(rtc_v2f0, rtc_v2l0)))] | 16 | #[cfg(not(any(rtc_v2f0, rtc_v2l0)))] |
| 18 | { | 17 | { |
| 19 | cr.modify(|w| w.set_dbp(true)); | 18 | if !cr.read().dbp() { |
| 20 | while !cr.read().dbp() {} | 19 | cr.modify(|w| w.set_dbp(true)); |
| 20 | while !cr.read().dbp() {} | ||
| 21 | } | ||
| 21 | } | 22 | } |
| 23 | } | ||
| 24 | |||
| 25 | #[allow(dead_code)] | ||
| 26 | pub(crate) fn set_clock_source(clock_source: RtcClockSource) { | ||
| 27 | #[cfg(not(rtc_v2wb))] | ||
| 28 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 29 | |||
| 30 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 31 | let cr = crate::pac::RCC.bdcr(); | ||
| 32 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 33 | let cr = crate::pac::RCC.csr(); | ||
| 34 | |||
| 35 | Self::unlock_registers(); | ||
| 36 | |||
| 37 | cr.modify(|w| { | ||
| 38 | // Select RTC source | ||
| 39 | #[cfg(not(rtc_v2wb))] | ||
| 40 | w.set_rtcsel(Rtcsel::from_bits(clock_source as u8)); | ||
| 41 | #[cfg(rtc_v2wb)] | ||
| 42 | w.set_rtcsel(clock_source as u8); | ||
| 43 | }); | ||
| 44 | } | ||
| 22 | 45 | ||
| 46 | pub(super) fn enable() { | ||
| 23 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | 47 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |
| 24 | let reg = crate::pac::RCC.bdcr().read(); | 48 | let reg = crate::pac::RCC.bdcr().read(); |
| 25 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | 49 | #[cfg(any(rtc_v2l0, rtc_v2l1))] |
| @@ -28,12 +52,9 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 28 | #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] | 52 | #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] |
| 29 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | 53 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); |
| 30 | 54 | ||
| 31 | #[cfg(rtc_v2wb)] | 55 | if !reg.rtcen() { |
| 32 | let rtcsel = reg.rtcsel(); | 56 | Self::unlock_registers(); |
| 33 | #[cfg(not(rtc_v2wb))] | ||
| 34 | let rtcsel = reg.rtcsel().to_bits(); | ||
| 35 | 57 | ||
| 36 | if !reg.rtcen() || rtcsel != clock_source as u8 { | ||
| 37 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] | 58 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] |
| 38 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); | 59 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); |
| 39 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | 60 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |
| @@ -46,12 +67,8 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 46 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | 67 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |
| 47 | w.set_bdrst(false); | 68 | w.set_bdrst(false); |
| 48 | 69 | ||
| 49 | // Select RTC source | ||
| 50 | #[cfg(not(rtc_v2wb))] | ||
| 51 | w.set_rtcsel(Rtcsel::from_bits(clock_source as u8)); | ||
| 52 | #[cfg(rtc_v2wb)] | ||
| 53 | w.set_rtcsel(clock_source as u8); | ||
| 54 | w.set_rtcen(true); | 70 | w.set_rtcen(true); |
| 71 | w.set_rtcsel(reg.rtcsel()); | ||
| 55 | 72 | ||
| 56 | // Restore bcdr | 73 | // Restore bcdr |
| 57 | #[cfg(any(rtc_v2l4, rtc_v2wb))] | 74 | #[cfg(any(rtc_v2l4, rtc_v2wb))] |
| @@ -157,7 +174,7 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 157 | where | 174 | where |
| 158 | F: FnOnce(&crate::pac::rtc::Rtc) -> R, | 175 | F: FnOnce(&crate::pac::rtc::Rtc) -> R, |
| 159 | { | 176 | { |
| 160 | let r = T::regs(); | 177 | let r = RTC::regs(); |
| 161 | // Disable write protection. | 178 | // Disable write protection. |
| 162 | // This is safe, as we're only writin the correct and expected values. | 179 | // This is safe, as we're only writin the correct and expected values. |
| 163 | r.wpr().write(|w| w.set_key(0xca)); | 180 | r.wpr().write(|w| w.set_key(0xca)); |
| @@ -218,5 +235,3 @@ impl sealed::Instance for crate::peripherals::RTC { | |||
| 218 | } | 235 | } |
| 219 | } | 236 | } |
| 220 | } | 237 | } |
| 221 | |||
| 222 | impl Instance for crate::peripherals::RTC {} | ||
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 9f04c9b69..3297303ee 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs | |||
| @@ -1,42 +1,62 @@ | |||
| 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::{sealed, Instance, RtcCalibrationCyclePeriod, RtcClockSource, RtcConfig}; | 3 | use super::{sealed, RtcCalibrationCyclePeriod, RtcClockSource, RtcConfig}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | ||
| 6 | use crate::rtc::sealed::Instance; | ||
| 5 | 7 | ||
| 6 | impl<'d, T: Instance> super::Rtc<'d, T> { | 8 | impl super::Rtc { |
| 7 | pub(super) fn enable(clock_source: RtcClockSource) { | 9 | fn unlock_registers() { |
| 8 | // Unlock the backup domain | 10 | // Unlock the backup domain |
| 9 | #[cfg(not(any(rtc_v3u5, rcc_wl5, rcc_wle)))] | 11 | #[cfg(not(any(rtc_v3u5, rcc_wl5, rcc_wle)))] |
| 10 | { | 12 | { |
| 11 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(true)); | 13 | if !crate::pac::PWR.cr1().read().dbp() { |
| 12 | while !crate::pac::PWR.cr1().read().dbp() {} | 14 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(true)); |
| 15 | while !crate::pac::PWR.cr1().read().dbp() {} | ||
| 16 | } | ||
| 13 | } | 17 | } |
| 14 | #[cfg(any(rcc_wl5, rcc_wle))] | 18 | #[cfg(any(rcc_wl5, rcc_wle))] |
| 15 | { | 19 | { |
| 16 | use crate::pac::pwr::vals::Dbp; | 20 | use crate::pac::pwr::vals::Dbp; |
| 17 | 21 | ||
| 18 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); | 22 | if crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED { |
| 19 | while crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED {} | 23 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); |
| 24 | while crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED {} | ||
| 25 | } | ||
| 20 | } | 26 | } |
| 27 | } | ||
| 21 | 28 | ||
| 22 | let reg = crate::pac::RCC.bdcr().read(); | 29 | #[allow(dead_code)] |
| 23 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | 30 | pub(crate) fn set_clock_source(clock_source: RtcClockSource) { |
| 24 | |||
| 25 | let clock_source = clock_source as u8; | 31 | let clock_source = clock_source as u8; |
| 26 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | 32 | #[cfg(not(any(rcc_wl5, rcc_wle)))] |
| 27 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); | 33 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); |
| 28 | 34 | ||
| 29 | if !reg.rtcen() || reg.rtcsel() != clock_source { | 35 | Self::unlock_registers(); |
| 30 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); | 36 | |
| 37 | crate::pac::RCC.bdcr().modify(|w| { | ||
| 38 | // Select RTC source | ||
| 39 | w.set_rtcsel(clock_source); | ||
| 40 | }); | ||
| 41 | } | ||
| 42 | |||
| 43 | pub(super) fn enable() { | ||
| 44 | let bdcr = crate::pac::RCC.bdcr(); | ||
| 31 | 45 | ||
| 32 | crate::pac::RCC.bdcr().modify(|w| { | 46 | let reg = bdcr.read(); |
| 47 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||
| 48 | |||
| 49 | if !reg.rtcen() { | ||
| 50 | Self::unlock_registers(); | ||
| 51 | |||
| 52 | bdcr.modify(|w| w.set_bdrst(true)); | ||
| 53 | |||
| 54 | bdcr.modify(|w| { | ||
| 33 | // Reset | 55 | // Reset |
| 34 | w.set_bdrst(false); | 56 | w.set_bdrst(false); |
| 35 | 57 | ||
| 36 | // Select RTC source | ||
| 37 | w.set_rtcsel(clock_source); | ||
| 38 | |||
| 39 | w.set_rtcen(true); | 58 | w.set_rtcen(true); |
| 59 | w.set_rtcsel(reg.rtcsel()); | ||
| 40 | 60 | ||
| 41 | // Restore bcdr | 61 | // Restore bcdr |
| 42 | w.set_lscosel(reg.lscosel()); | 62 | w.set_lscosel(reg.lscosel()); |
| @@ -141,7 +161,7 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 141 | where | 161 | where |
| 142 | F: FnOnce(&crate::pac::rtc::Rtc) -> R, | 162 | F: FnOnce(&crate::pac::rtc::Rtc) -> R, |
| 143 | { | 163 | { |
| 144 | let r = T::regs(); | 164 | let r = RTC::regs(); |
| 145 | // Disable write protection. | 165 | // Disable write protection. |
| 146 | // This is safe, as we're only writin the correct and expected values. | 166 | // This is safe, as we're only writin the correct and expected values. |
| 147 | r.wpr().write(|w| w.set_key(Key::DEACTIVATE1)); | 167 | r.wpr().write(|w| w.set_key(Key::DEACTIVATE1)); |
| @@ -188,5 +208,3 @@ impl sealed::Instance for crate::peripherals::RTC { | |||
| 188 | } | 208 | } |
| 189 | } | 209 | } |
| 190 | } | 210 | } |
| 191 | |||
| 192 | impl Instance for crate::peripherals::RTC {} | ||
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index 0d7906bde..fb1bc6e3d 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs | |||
| @@ -27,10 +27,7 @@ async fn main(_spawner: Spawner) { | |||
| 27 | .and_hms_opt(10, 30, 15) | 27 | .and_hms_opt(10, 30, 15) |
| 28 | .unwrap(); | 28 | .unwrap(); |
| 29 | 29 | ||
| 30 | let mut rtc = Rtc::new( | 30 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); |
| 31 | p.RTC, | ||
| 32 | RtcConfig::default().clock_source(embassy_stm32::rtc::RtcClockSource::LSE), | ||
| 33 | ); | ||
| 34 | info!("Got RTC! {:?}", now.timestamp()); | 31 | info!("Got RTC! {:?}", now.timestamp()); |
| 35 | 32 | ||
| 36 | rtc.set_datetime(now.into()).expect("datetime not set"); | 33 | rtc.set_datetime(now.into()).expect("datetime not set"); |
