aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-25 22:45:48 +0000
committerGitHub <[email protected]>2024-02-25 22:45:48 +0000
commit497515ed57b768332295ef58630231609fb959fc (patch)
treea3bee07eda154faa8f3f32493e91905b927d5740
parent326e32adc4f5035a122fa12d3111026d27d48e63 (diff)
parent394abda092cac80c875998c429f629caa289f9d1 (diff)
Merge pull request #2583 from OroArmor/tim_pll_clk
Enable PLL Clocks for TIMx peripherals on STM32F3xx Chips
-rw-r--r--embassy-stm32/build.rs68
-rw-r--r--embassy-stm32/src/rcc/f013.rs20
-rw-r--r--embassy-stm32/src/rcc/mod.rs2
-rw-r--r--examples/stm32f334/src/bin/pwm.rs3
4 files changed, 84 insertions, 9 deletions
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() {
379 379
380 let mut clock_names = BTreeSet::new(); 380 let mut clock_names = BTreeSet::new();
381 381
382 let mut rcc_cfgr_regs = BTreeSet::new();
383
382 for p in METADATA.peripherals { 384 for p in METADATA.peripherals {
383 if !singletons.contains(&p.name.to_string()) { 385 if !singletons.contains(&p.name.to_string()) {
384 continue; 386 continue;
@@ -457,6 +459,8 @@ fn main() {
457 let field_name = format_ident!("{}", field_name); 459 let field_name = format_ident!("{}", field_name);
458 let enum_name = format_ident!("{}", enum_name); 460 let enum_name = format_ident!("{}", enum_name);
459 461
462 rcc_cfgr_regs.insert((fieldset_name.clone(), field_name.clone(), enum_name.clone()));
463
460 let match_arms: TokenStream = enumm 464 let match_arms: TokenStream = enumm
461 .variants 465 .variants
462 .iter() 466 .iter()
@@ -539,6 +543,70 @@ fn main() {
539 } 543 }
540 } 544 }
541 545
546 if !rcc_cfgr_regs.is_empty() {
547 println!("cargo:rustc-cfg=clock_mux");
548
549 let struct_fields: Vec<_> = rcc_cfgr_regs
550 .iter()
551 .map(|(_fieldset, fieldname, enum_name)| {
552 quote! {
553 pub #fieldname: Option<#enum_name>
554 }
555 })
556 .collect();
557
558 let field_names: Vec<_> = rcc_cfgr_regs
559 .iter()
560 .map(|(_fieldset, fieldname, _enum_name)| fieldname)
561 .collect();
562
563 let inits: Vec<_> = rcc_cfgr_regs
564 .iter()
565 .map(|(fieldset, fieldname, _enum_name)| {
566 let setter = format_ident!("set_{}", fieldname);
567 quote! {
568 match self.#fieldname {
569 None => {}
570 Some(val) => {
571 crate::pac::RCC.#fieldset()
572 .modify(|w| w.#setter(val));
573 }
574 };
575 }
576 })
577 .collect();
578
579 let enum_names: BTreeSet<_> = rcc_cfgr_regs
580 .iter()
581 .map(|(_fieldset, _fieldname, enum_name)| enum_name)
582 .collect();
583
584 g.extend(quote! {
585 pub mod mux {
586 #(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )*
587
588 #[derive(Clone, Copy)]
589 pub struct ClockMux {
590 #( #struct_fields, )*
591 }
592
593 impl Default for ClockMux {
594 fn default() -> Self {
595 Self {
596 #( #field_names: None, )*
597 }
598 }
599 }
600
601 impl ClockMux {
602 pub fn init(self) {
603 #( #inits )*
604 }
605 }
606 }
607 });
608 }
609
542 // Generate RCC 610 // Generate RCC
543 clock_names.insert("sys".to_string()); 611 clock_names.insert("sys".to_string());
544 clock_names.insert("rtc".to_string()); 612 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 {
97 pub adc: AdcClockSource, 97 pub adc: AdcClockSource,
98 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 98 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
99 pub adc34: AdcClockSource, 99 pub adc34: AdcClockSource,
100 #[cfg(stm32f334)] 100
101 pub hrtim: HrtimClockSource, 101 #[cfg(clock_mux)]
102 pub mux: crate::rcc::mux::ClockMux,
102 103
103 pub ls: super::LsConfig, 104 pub ls: super::LsConfig,
104} 105}
@@ -122,13 +123,13 @@ impl Default for Config {
122 // ensure ADC is not out of range by default even if APB2 is maxxed out (36mhz) 123 // ensure ADC is not out of range by default even if APB2 is maxxed out (36mhz)
123 adc_pre: ADCPrescaler::DIV6, 124 adc_pre: ADCPrescaler::DIV6,
124 125
125
126 #[cfg(all(stm32f3, not(rcc_f37)))] 126 #[cfg(all(stm32f3, not(rcc_f37)))]
127 adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), 127 adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
128 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 128 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
129 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), 129 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
130 #[cfg(stm32f334)] 130
131 hrtim: HrtimClockSource::BusClk, 131 #[cfg(clock_mux)]
132 mux: Default::default(),
132 } 133 }
133 } 134 }
134} 135}
@@ -347,7 +348,8 @@ pub(crate) unsafe fn init(config: Config) {
347 } 348 }
348 }; 349 };
349 350
350 #[cfg(stm32f334)] 351 /*
352 TODO: Maybe add something like this to clock_mux? How can we autogenerate the data for this?
351 let hrtim = match config.hrtim { 353 let hrtim = match config.hrtim {
352 // Must be configured after the bus is ready, otherwise it won't work 354 // Must be configured after the bus is ready, otherwise it won't work
353 HrtimClockSource::BusClk => None, 355 HrtimClockSource::BusClk => None,
@@ -363,6 +365,10 @@ pub(crate) unsafe fn init(config: Config) {
363 Some(pll * 2u32) 365 Some(pll * 2u32)
364 } 366 }
365 }; 367 };
368 */
369
370 #[cfg(clock_mux)]
371 config.mux.init();
366 372
367 set_clocks!( 373 set_clocks!(
368 hsi: hsi, 374 hsi: hsi,
@@ -378,8 +384,6 @@ pub(crate) unsafe fn init(config: Config) {
378 adc: Some(adc), 384 adc: Some(adc),
379 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 385 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
380 adc34: Some(adc34), 386 adc34: Some(adc34),
381 #[cfg(stm32f334)]
382 hrtim: hrtim,
383 rtc: rtc, 387 rtc: rtc,
384 hsi48: hsi48, 388 hsi48: hsi48,
385 #[cfg(any(rcc_f1, rcc_f1cl, stm32f3))] 389 #[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;
31 31
32pub use _version::*; 32pub use _version::*;
33 33
34#[cfg(clock_mux)]
35pub use crate::_generated::mux;
34pub use crate::_generated::Clocks; 36pub use crate::_generated::Clocks;
35 37
36#[cfg(feature = "low-power")] 38#[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) {
27 config.rcc.ahb_pre = AHBPrescaler::DIV1; 27 config.rcc.ahb_pre = AHBPrescaler::DIV1;
28 config.rcc.apb1_pre = APBPrescaler::DIV2; 28 config.rcc.apb1_pre = APBPrescaler::DIV2;
29 config.rcc.apb2_pre = APBPrescaler::DIV1; 29 config.rcc.apb2_pre = APBPrescaler::DIV1;
30 config.rcc.hrtim = HrtimClockSource::PllClk; 30
31 config.rcc.mux.hrtim1sw = Some(embassy_stm32::rcc::mux::Timsw::PLL1_P);
31 } 32 }
32 let p = embassy_stm32::init(config); 33 let p = embassy_stm32::init(config);
33 34