diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index d774b993b..762e84355 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -1,5 +1,5 @@ #[allow(dead_code)] -#[derive(Default)] +#[derive(Default, Clone, Copy)] pub enum LseDrive { #[cfg(any(rtc_v2f7, rtc_v2l4))] Low = 0, @@ -87,40 +87,42 @@ impl BackupDomain { rtc_v3u5 ))] #[allow(dead_code, unused_variables)] - pub fn configure_ls(clock_source: RtcClockSource, lse_drive: Option) { - match clock_source { - RtcClockSource::LSI => { - #[cfg(rtc_v3u5)] - let csr = crate::pac::RCC.bdcr(); + pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { + if lsi { + #[cfg(rtc_v3u5)] + let csr = crate::pac::RCC.bdcr(); - #[cfg(not(rtc_v3u5))] - let csr = crate::pac::RCC.csr(); - - Self::modify(|_| { - #[cfg(not(any(rcc_wb, rcc_wba)))] - csr.modify(|w| w.set_lsion(true)); - - #[cfg(any(rcc_wb, rcc_wba))] - csr.modify(|w| w.set_lsi1on(true)); - }); + #[cfg(not(rtc_v3u5))] + let csr = crate::pac::RCC.csr(); + Self::modify(|_| { #[cfg(not(any(rcc_wb, rcc_wba)))] - while !csr.read().lsirdy() {} + csr.modify(|w| w.set_lsion(true)); #[cfg(any(rcc_wb, rcc_wba))] - while !csr.read().lsi1rdy() {} - } - RtcClockSource::LSE => { - let lse_drive = lse_drive.unwrap_or_default(); + csr.modify(|w| w.set_lsi1on(true)); + }); - Self::modify(|w| { - #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] - w.set_lsedrv(lse_drive.into()); - w.set_lseon(true); - }); + #[cfg(not(any(rcc_wb, rcc_wba)))] + while !csr.read().lsirdy() {} - while !Self::read().lserdy() {} - } + #[cfg(any(rcc_wb, rcc_wba))] + while !csr.read().lsi1rdy() {} + } + + if let Some(lse_drive) = lse { + Self::modify(|w| { + #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] + w.set_lsedrv(lse_drive.into()); + w.set_lseon(true); + }); + + while !Self::read().lserdy() {} + } + + match clock_source { + RtcClockSource::LSI => assert!(lsi), + RtcClockSource::LSE => assert!(&lse.is_some()), _ => {} }; diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index da88e44dc..56ccdcbd8 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -291,6 +291,8 @@ pub struct Config { pub pll: PLLConfig, pub mux: ClockSrc, pub rtc: Option, + pub lsi: bool, + pub lse: Option, pub voltage: VoltageScale, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, @@ -308,6 +310,8 @@ impl Default for Config { voltage: VoltageScale::Scale3, mux: ClockSrc::HSI, rtc: None, + lsi: false, + lse: None, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -421,9 +425,11 @@ pub(crate) unsafe fn init(config: Config) { RCC.apb1enr().modify(|w| w.set_pwren(true)); PWR.cr().read(); - config - .rtc - .map(|clock_source| BackupDomain::configure_ls(clock_source, None)); + BackupDomain::configure_ls( + config.rtc.unwrap_or(RtcClockSource::NOCLOCK), + config.lsi, + config.lse.map(|_| Default::default()), + ); set_freqs(Clocks { sys: sys_clk, diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index f7bc0d99a..d8d0312bc 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -35,6 +35,8 @@ pub struct Config { pub pll48: bool, pub rtc: Option, + pub lsi: bool, + pub lse: Option, } #[cfg(stm32f410)] @@ -461,12 +463,15 @@ pub(crate) unsafe fn init(config: Config) { }) }); - config - .rtc - .map(|clock_source| BackupDomain::configure_ls(clock_source, None)); + BackupDomain::configure_ls( + config.rtc.unwrap_or(RtcClockSource::NOCLOCK), + config.lsi, + config.lse.map(|_| Default::default()), + ); let rtc = match config.rtc { Some(RtcClockSource::LSI) => Some(LSI_FREQ), + Some(RtcClockSource::LSE) => Some(config.lse.unwrap()), _ => None, }; diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 2dfd0232c..1c655592e 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -138,6 +138,8 @@ pub struct Config { #[cfg(crs)] pub enable_hsi48: bool, pub rtc: Option, + pub lse: Option, + pub lsi: bool, } impl Default for Config { @@ -151,6 +153,8 @@ impl Default for Config { #[cfg(crs)] enable_hsi48: false, rtc: None, + lse: None, + lsi: false, } } } @@ -235,9 +239,11 @@ pub(crate) unsafe fn init(config: Config) { } }; - config.rtc.map(|rtc| { - BackupDomain::configure_ls(rtc, None); - }); + BackupDomain::configure_ls( + config.rtc.unwrap_or(RtcClockSource::NOCLOCK), + config.lsi, + config.lse.map(|_| Default::default()), + ); RCC.cfgr().modify(|w| { w.set_sw(sw); diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 447a57b2c..f7b9354a6 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -241,6 +241,8 @@ pub struct Config { #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] pub hsi48: bool, pub rtc_mux: RtcClockSource, + pub lse: Option, + pub lsi: bool, } impl Default for Config { @@ -255,6 +257,8 @@ impl Default for Config { #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] hsi48: false, rtc_mux: RtcClockSource::LSI, + lsi: true, + lse: None, } } } @@ -407,7 +411,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.apb1enr1().modify(|w| w.set_pwren(true)); - BackupDomain::configure_ls(config.rtc_mux, None); + BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); let (sys_clk, sw) = match config.mux { ClockSrc::MSI(range) => { diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 892dcf937..ff9b9bac8 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -31,6 +31,16 @@ pub use _version::*; #[cfg(feature = "low-power")] use atomic_polyfill::{AtomicU32, Ordering}; +// Model Clock Configuration +// +// pub struct Clocks { +// hse: Option, +// hsi: bool, +// lse: Option, +// lsi: bool, +// rtc: RtcSource, +// } + #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Clocks { diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 3f4c37429..ee45a342b 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -108,6 +108,7 @@ pub struct Pll { pub struct Config { pub hse: Option, pub lse: Option, + pub lsi: bool, pub sys: Sysclk, pub mux: Option, pub pll48: Option, @@ -136,6 +137,7 @@ pub const WPAN_DEFAULT: Config = Config { }), pll48: None, rtc: Some(RtcClockSource::LSE), + lsi: false, pll: Some(Pll { mul: 12, @@ -164,6 +166,7 @@ impl Default for Config { pll: None, pllsai: None, rtc: None, + lsi: false, ahb1_pre: AHBPrescaler::DIV1, ahb2_pre: AHBPrescaler::DIV1, @@ -294,9 +297,11 @@ pub(crate) fn configure_clocks(config: &Config) { rcc.cfgr().modify(|w| w.set_stopwuck(true)); - config - .rtc - .map(|clock_source| BackupDomain::configure_ls(clock_source, None)); + BackupDomain::configure_ls( + config.rtc.unwrap_or(RtcClockSource::NOCLOCK), + config.lsi, + config.lse.map(|_| Default::default()), + ); match &config.hse { Some(hse) => { diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 07856a28c..5db942fca 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -138,6 +138,8 @@ pub struct Config { pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, pub rtc_mux: RtcClockSource, + pub lse: Option, + pub lsi: bool, pub adc_clock_source: AdcClockSource, } @@ -151,6 +153,8 @@ impl Default for Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, rtc_mux: RtcClockSource::LSI, + lsi: true, + lse: None, adc_clock_source: AdcClockSource::default(), } } @@ -231,7 +235,7 @@ pub(crate) unsafe fn init(config: Config) { while FLASH.acr().read().latency() != ws {} // Enables the LSI if configured - BackupDomain::configure_ls(config.rtc_mux, None); + BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); match config.mux { ClockSrc::HSI16 => {