diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-25 22:45:48 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-25 22:45:48 +0000 |
| commit | 497515ed57b768332295ef58630231609fb959fc (patch) | |
| tree | a3bee07eda154faa8f3f32493e91905b927d5740 | |
| parent | 326e32adc4f5035a122fa12d3111026d27d48e63 (diff) | |
| parent | 394abda092cac80c875998c429f629caa289f9d1 (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.rs | 68 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f013.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 2 | ||||
| -rw-r--r-- | examples/stm32f334/src/bin/pwm.rs | 3 |
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 | ||
| 32 | pub use _version::*; | 32 | pub use _version::*; |
| 33 | 33 | ||
| 34 | #[cfg(clock_mux)] | ||
| 35 | pub use crate::_generated::mux; | ||
| 34 | pub use crate::_generated::Clocks; | 36 | pub 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 | ||
