diff options
| -rw-r--r-- | embassy-stm32/src/rcc/f4.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wb.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 73 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v3.rs | 8 |
6 files changed, 45 insertions, 52 deletions
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 10d3322aa..c2c78a45e 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs | |||
| @@ -499,6 +499,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 499 | pllsai: None, | 499 | pllsai: None, |
| 500 | 500 | ||
| 501 | rtc: rtc, | 501 | rtc: rtc, |
| 502 | rtc_hse: None, | ||
| 502 | }); | 503 | }); |
| 503 | } | 504 | } |
| 504 | 505 | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9f1b3b663..0430e4a74 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -78,8 +78,12 @@ pub struct Clocks { | |||
| 78 | pub adc: Option<Hertz>, | 78 | pub adc: Option<Hertz>, |
| 79 | 79 | ||
| 80 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | 80 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] |
| 81 | /// Set only if the lsi or lse is configured | 81 | /// Set only if the lsi or lse is configured, indicates stop is supported |
| 82 | pub rtc: Option<Hertz>, | 82 | pub rtc: Option<Hertz>, |
| 83 | |||
| 84 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | ||
| 85 | /// Set if the hse is configured, indicates stop is not supported | ||
| 86 | pub rtc_hse: Option<Hertz>, | ||
| 83 | } | 87 | } |
| 84 | 88 | ||
| 85 | #[cfg(feature = "low-power")] | 89 | #[cfg(feature = "low-power")] |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 6a3eab707..6496b41e1 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -271,6 +271,7 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { | |||
| 271 | apb1_tim: apb1_tim_clk, | 271 | apb1_tim: apb1_tim_clk, |
| 272 | apb2_tim: apb2_tim_clk, | 272 | apb2_tim: apb2_tim_clk, |
| 273 | rtc: rtc_clk, | 273 | rtc: rtc_clk, |
| 274 | rtc_hse: None, | ||
| 274 | } | 275 | } |
| 275 | } | 276 | } |
| 276 | 277 | ||
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 796fd7d96..9db4f69c5 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -12,6 +12,7 @@ use embassy_sync::blocking_mutex::Mutex; | |||
| 12 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | 12 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; |
| 13 | use crate::rcc::bd::BackupDomain; | 13 | use crate::rcc::bd::BackupDomain; |
| 14 | pub use crate::rcc::RtcClockSource; | 14 | pub use crate::rcc::RtcClockSource; |
| 15 | use crate::time::Hertz; | ||
| 15 | 16 | ||
| 16 | /// refer to AN4759 to compare features of RTC2 and RTC3 | 17 | /// refer to AN4759 to compare features of RTC2 and RTC3 |
| 17 | #[cfg_attr(any(rtc_v1), path = "v1.rs")] | 18 | #[cfg_attr(any(rtc_v1), path = "v1.rs")] |
| @@ -84,47 +85,23 @@ impl core::ops::Sub for RtcInstant { | |||
| 84 | 85 | ||
| 85 | /// RTC Abstraction | 86 | /// RTC Abstraction |
| 86 | pub struct Rtc { | 87 | pub struct Rtc { |
| 87 | rtc_config: RtcConfig, | ||
| 88 | #[cfg(feature = "low-power")] | 88 | #[cfg(feature = "low-power")] |
| 89 | stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, | 89 | stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | #[derive(Copy, Clone, PartialEq)] | 92 | #[derive(Copy, Clone, PartialEq)] |
| 93 | pub struct RtcConfig { | 93 | pub struct RtcConfig { |
| 94 | /// Asynchronous prescaler factor | 94 | /// The subsecond counter frequency; default is 256 |
| 95 | /// This is the asynchronous division factor: | 95 | /// |
| 96 | /// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1) | 96 | /// A high counter frequency may impact stop power consumption |
| 97 | /// ck_apre drives the subsecond register | 97 | pub frequency: Hertz, |
| 98 | async_prescaler: u8, | ||
| 99 | /// Synchronous prescaler factor | ||
| 100 | /// This is the synchronous division factor: | ||
| 101 | /// ck_spre frequency = ck_apre frequency/(PREDIV_S+1) | ||
| 102 | /// ck_spre must be 1Hz | ||
| 103 | sync_prescaler: u16, | ||
| 104 | } | 98 | } |
| 105 | 99 | ||
| 106 | impl Default for RtcConfig { | 100 | impl Default for RtcConfig { |
| 107 | /// LSI with prescalers assuming 32.768 kHz. | 101 | /// LSI with prescalers assuming 32.768 kHz. |
| 108 | /// Raw sub-seconds in 1/256. | 102 | /// Raw sub-seconds in 1/256. |
| 109 | fn default() -> Self { | 103 | fn default() -> Self { |
| 110 | RtcConfig { | 104 | RtcConfig { frequency: Hertz(256) } |
| 111 | async_prescaler: 127, | ||
| 112 | sync_prescaler: 255, | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | impl RtcConfig { | ||
| 118 | /// Set the asynchronous prescaler of RTC config | ||
| 119 | pub fn async_prescaler(mut self, prescaler: u8) -> Self { | ||
| 120 | self.async_prescaler = prescaler; | ||
| 121 | self | ||
| 122 | } | ||
| 123 | |||
| 124 | /// Set the synchronous prescaler of RTC config | ||
| 125 | pub fn sync_prescaler(mut self, prescaler: u16) -> Self { | ||
| 126 | self.sync_prescaler = prescaler; | ||
| 127 | self | ||
| 128 | } | 105 | } |
| 129 | } | 106 | } |
| 130 | 107 | ||
| @@ -147,23 +124,37 @@ impl Default for RtcCalibrationCyclePeriod { | |||
| 147 | 124 | ||
| 148 | impl Rtc { | 125 | impl Rtc { |
| 149 | pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { | 126 | pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { |
| 150 | RTC::enable_peripheral_clk(); | 127 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] |
| 128 | use crate::rcc::get_freqs; | ||
| 151 | 129 | ||
| 152 | #[cfg(not(feature = "low-power"))] | 130 | RTC::enable_peripheral_clk(); |
| 153 | let mut rtc_struct = Self { rtc_config }; | 131 | BackupDomain::enable_rtc(); |
| 154 | 132 | ||
| 155 | #[cfg(feature = "low-power")] | 133 | let mut this = Self { |
| 156 | let mut rtc_struct = Self { | 134 | #[cfg(feature = "low-power")] |
| 157 | rtc_config, | ||
| 158 | stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), | 135 | stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), |
| 159 | }; | 136 | }; |
| 160 | 137 | ||
| 161 | BackupDomain::enable_rtc(); | 138 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] |
| 139 | let freqs = unsafe { get_freqs() }; | ||
| 140 | |||
| 141 | // Load the clock frequency from the rcc mod, if supported | ||
| 142 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | ||
| 143 | let frequency = match freqs.rtc { | ||
| 144 | Some(hertz) => hertz, | ||
| 145 | None => freqs.rtc_hse.unwrap(), | ||
| 146 | }; | ||
| 162 | 147 | ||
| 163 | rtc_struct.configure(rtc_config); | 148 | // Assume the default value, if not supported |
| 164 | rtc_struct.rtc_config = rtc_config; | 149 | #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))] |
| 150 | let frequency = Hertz(32_768); | ||
| 165 | 151 | ||
| 166 | rtc_struct | 152 | let async_psc = ((frequency.0 / rtc_config.frequency.0) - 1) as u8; |
| 153 | let sync_psc = (rtc_config.frequency.0 - 1) as u16; | ||
| 154 | |||
| 155 | this.configure(async_psc, sync_psc); | ||
| 156 | |||
| 157 | this | ||
| 167 | } | 158 | } |
| 168 | 159 | ||
| 169 | /// Set the datetime to a new value. | 160 | /// Set the datetime to a new value. |
| @@ -228,10 +219,6 @@ impl Rtc { | |||
| 228 | }) | 219 | }) |
| 229 | } | 220 | } |
| 230 | 221 | ||
| 231 | pub fn get_config(&self) -> RtcConfig { | ||
| 232 | self.rtc_config | ||
| 233 | } | ||
| 234 | |||
| 235 | pub const BACKUP_REGISTER_COUNT: usize = RTC::BACKUP_REGISTER_COUNT; | 222 | pub const BACKUP_REGISTER_COUNT: usize = RTC::BACKUP_REGISTER_COUNT; |
| 236 | 223 | ||
| 237 | /// Read content of the backup register. | 224 | /// Read content of the backup register. |
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 49f66e957..482b6e75d 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | 1 | use stm32_metapac::rtc::vals::{Init, Osel, Pol}; |
| 2 | 2 | ||
| 3 | use super::{sealed, RtcConfig}; | 3 | use super::sealed; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 6 | use crate::rtc::sealed::Instance; | 6 | use crate::rtc::sealed::Instance; |
| @@ -154,7 +154,7 @@ impl super::Rtc { | |||
| 154 | 154 | ||
| 155 | /// Applies the RTC config | 155 | /// Applies the RTC config |
| 156 | /// It this changes the RTC clock source the time will be reset | 156 | /// It this changes the RTC clock source the time will be reset |
| 157 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | 157 | pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { |
| 158 | self.write(true, |rtc| { | 158 | self.write(true, |rtc| { |
| 159 | rtc.cr().modify(|w| { | 159 | rtc.cr().modify(|w| { |
| 160 | #[cfg(rtc_v2f2)] | 160 | #[cfg(rtc_v2f2)] |
| @@ -166,8 +166,8 @@ impl super::Rtc { | |||
| 166 | }); | 166 | }); |
| 167 | 167 | ||
| 168 | rtc.prer().modify(|w| { | 168 | rtc.prer().modify(|w| { |
| 169 | w.set_prediv_s(rtc_config.sync_prescaler); | 169 | w.set_prediv_s(sync_psc); |
| 170 | w.set_prediv_a(rtc_config.async_prescaler); | 170 | w.set_prediv_a(async_psc); |
| 171 | }); | 171 | }); |
| 172 | }); | 172 | }); |
| 173 | } | 173 | } |
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 12952b15a..a6b2655d8 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::{sealed, RtcCalibrationCyclePeriod, RtcConfig}; | 3 | use super::{sealed, RtcCalibrationCyclePeriod}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 6 | use crate::rtc::sealed::Instance; | 6 | use crate::rtc::sealed::Instance; |
| @@ -8,7 +8,7 @@ use crate::rtc::sealed::Instance; | |||
| 8 | impl super::Rtc { | 8 | impl super::Rtc { |
| 9 | /// Applies the RTC config | 9 | /// Applies the RTC config |
| 10 | /// It this changes the RTC clock source the time will be reset | 10 | /// It this changes the RTC clock source the time will be reset |
| 11 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | 11 | pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { |
| 12 | self.write(true, |rtc| { | 12 | self.write(true, |rtc| { |
| 13 | rtc.cr().modify(|w| { | 13 | rtc.cr().modify(|w| { |
| 14 | w.set_fmt(Fmt::TWENTYFOURHOUR); | 14 | w.set_fmt(Fmt::TWENTYFOURHOUR); |
| @@ -17,8 +17,8 @@ impl super::Rtc { | |||
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | rtc.prer().modify(|w| { | 19 | rtc.prer().modify(|w| { |
| 20 | w.set_prediv_s(rtc_config.sync_prescaler); | 20 | w.set_prediv_s(sync_psc); |
| 21 | w.set_prediv_a(rtc_config.async_prescaler); | 21 | w.set_prediv_a(async_psc); |
| 22 | }); | 22 | }); |
| 23 | 23 | ||
| 24 | // TODO: configuration for output pins | 24 | // TODO: configuration for output pins |
