diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 4ecc97536..08c051956 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -379,6 +379,8 @@ fn main() { let mut clock_names = BTreeSet::new(); + let mut rcc_cfgr_regs = BTreeSet::new(); + for p in METADATA.peripherals { if !singletons.contains(&p.name.to_string()) { continue; @@ -457,6 +459,8 @@ fn main() { let field_name = format_ident!("{}", field_name); let enum_name = format_ident!("{}", enum_name); + rcc_cfgr_regs.insert((fieldset_name.clone(), field_name.clone(), enum_name.clone())); + let match_arms: TokenStream = enumm .variants .iter() @@ -539,6 +543,70 @@ fn main() { } } + if !rcc_cfgr_regs.is_empty() { + println!("cargo:rustc-cfg=clock_mux"); + + let struct_fields: Vec<_> = rcc_cfgr_regs + .iter() + .map(|(_fieldset, fieldname, enum_name)| { + quote! { + pub #fieldname: Option<#enum_name> + } + }) + .collect(); + + let field_names: Vec<_> = rcc_cfgr_regs + .iter() + .map(|(_fieldset, fieldname, _enum_name)| fieldname) + .collect(); + + let inits: Vec<_> = rcc_cfgr_regs + .iter() + .map(|(fieldset, fieldname, _enum_name)| { + let setter = format_ident!("set_{}", fieldname); + quote! { + match self.#fieldname { + None => {} + Some(val) => { + crate::pac::RCC.#fieldset() + .modify(|w| w.#setter(val)); + } + }; + } + }) + .collect(); + + let enum_names: BTreeSet<_> = rcc_cfgr_regs + .iter() + .map(|(_fieldset, _fieldname, enum_name)| enum_name) + .collect(); + + g.extend(quote! { + pub mod mux { + #(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )* + + #[derive(Clone, Copy)] + pub struct ClockMux { + #( #struct_fields, )* + } + + impl Default for ClockMux { + fn default() -> Self { + Self { + #( #field_names: None, )* + } + } + } + + impl ClockMux { + pub fn init(self) { + #( #inits )* + } + } + } + }); + } + // Generate RCC clock_names.insert("sys".to_string()); clock_names.insert("rtc".to_string()); diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs index c2933186c..de209272d 100644 --- a/embassy-stm32/src/rcc/f013.rs +++ b/embassy-stm32/src/rcc/f013.rs @@ -97,8 +97,9 @@ pub struct Config { pub adc: AdcClockSource, #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] pub adc34: AdcClockSource, - #[cfg(stm32f334)] - pub hrtim: HrtimClockSource, + + #[cfg(clock_mux)] + pub mux: crate::rcc::mux::ClockMux, pub ls: super::LsConfig, } @@ -122,13 +123,13 @@ impl Default for Config { // ensure ADC is not out of range by default even if APB2 is maxxed out (36mhz) adc_pre: ADCPrescaler::DIV6, - #[cfg(all(stm32f3, not(rcc_f37)))] adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), - #[cfg(stm32f334)] - hrtim: HrtimClockSource::BusClk, + + #[cfg(clock_mux)] + mux: Default::default(), } } } @@ -347,7 +348,8 @@ pub(crate) unsafe fn init(config: Config) { } }; - #[cfg(stm32f334)] + /* + TODO: Maybe add something like this to clock_mux? How can we autogenerate the data for this? let hrtim = match config.hrtim { // Must be configured after the bus is ready, otherwise it won't work HrtimClockSource::BusClk => None, @@ -363,6 +365,10 @@ pub(crate) unsafe fn init(config: Config) { Some(pll * 2u32) } }; + */ + + #[cfg(clock_mux)] + config.mux.init(); set_clocks!( hsi: hsi, @@ -378,8 +384,6 @@ pub(crate) unsafe fn init(config: Config) { adc: Some(adc), #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] adc34: Some(adc34), - #[cfg(stm32f334)] - hrtim: hrtim, rtc: rtc, hsi48: hsi48, #[cfg(any(rcc_f1, rcc_f1cl, stm32f3))] diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0f3467151..c8ca713de 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -31,6 +31,8 @@ mod _version; pub use _version::*; +#[cfg(clock_mux)] +pub use crate::_generated::mux; pub use crate::_generated::Clocks; #[cfg(feature = "low-power")] diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs index 7fc1ea926..7c6d6cd71 100644 --- a/examples/stm32f334/src/bin/pwm.rs +++ b/examples/stm32f334/src/bin/pwm.rs @@ -27,7 +27,8 @@ async fn main(_spawner: Spawner) { config.rcc.ahb_pre = AHBPrescaler::DIV1; config.rcc.apb1_pre = APBPrescaler::DIV2; config.rcc.apb2_pre = APBPrescaler::DIV1; - config.rcc.hrtim = HrtimClockSource::PllClk; + + config.rcc.mux.hrtim1sw = Some(embassy_stm32::rcc::mux::Timsw::PLL1_P); } let p = embassy_stm32::init(config);