aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-26 03:28:27 +0100
committerDario Nieuwenhuis <[email protected]>2024-03-01 23:54:37 +0100
commit95234cddbac6f21fce0f5df510d49816f343b87d (patch)
treea9daf8a1bb9449191a7174269bc348f3ce61bfef
parentd5c9c611fa317e066d6cf7c5af0513b40bd69d8c (diff)
stm32: autogenerate mux config for all chips.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs299
-rw-r--r--embassy-stm32/src/ipcc.rs19
-rw-r--r--embassy-stm32/src/rcc/c0.rs34
-rw-r--r--embassy-stm32/src/rcc/f013.rs6
-rw-r--r--embassy-stm32/src/rcc/f247.rs10
-rw-r--r--embassy-stm32/src/rcc/g0.rs63
-rw-r--r--embassy-stm32/src/rcc/g4.rs78
-rw-r--r--embassy-stm32/src/rcc/h.rs72
-rw-r--r--embassy-stm32/src/rcc/l.rs56
-rw-r--r--embassy-stm32/src/rcc/mod.rs4
-rw-r--r--embassy-stm32/src/rcc/u5.rs7
-rw-r--r--embassy-stm32/src/rcc/wba.rs13
-rw-r--r--embassy-stm32/src/usb_otg/usb.rs14
-rw-r--r--examples/stm32f334/src/bin/pwm.rs2
-rw-r--r--examples/stm32g0/src/bin/hf_timer.rs44
-rw-r--r--examples/stm32g0/src/bin/usb_serial.rs10
-rw-r--r--examples/stm32g4/src/bin/adc.rs29
-rw-r--r--examples/stm32g4/src/bin/can.rs21
-rw-r--r--examples/stm32g4/src/bin/pll.rs1
-rw-r--r--examples/stm32g4/src/bin/usb_serial.rs50
-rw-r--r--examples/stm32h5/src/bin/can.rs2
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs7
-rw-r--r--examples/stm32h7/src/bin/adc.rs2
-rw-r--r--examples/stm32h7/src/bin/can.rs2
-rw-r--r--examples/stm32h7/src/bin/dac.rs2
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs2
-rw-r--r--examples/stm32l4/src/bin/adc.rs14
-rw-r--r--tests/stm32/src/bin/fdcan.rs4
-rw-r--r--tests/stm32/src/common.rs47
30 files changed, 406 insertions, 512 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 460184920..4bbd43c47 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -70,7 +70,7 @@ rand_core = "0.6.3"
70sdio-host = "0.5.0" 70sdio-host = "0.5.0"
71critical-section = "1.1" 71critical-section = "1.1"
72#stm32-metapac = { version = "15" } 72#stm32-metapac = { version = "15" }
73stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7462d805ef05892531a83cd9ad60c9cba568d54" } 73stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e853cf944b150898312984d092d63926970c340d" }
74vcell = "0.1.3" 74vcell = "0.1.3"
75bxcan = "0.7.0" 75bxcan = "0.7.0"
76nb = "1.0.0" 76nb = "1.0.0"
@@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] }
94proc-macro2 = "1.0.36" 94proc-macro2 = "1.0.36"
95quote = "1.0.15" 95quote = "1.0.15"
96#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 96#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
97stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7462d805ef05892531a83cd9ad60c9cba568d54", default-features = false, features = ["metadata"]} 97stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e853cf944b150898312984d092d63926970c340d", default-features = false, features = ["metadata"]}
98 98
99 99
100[features] 100[features]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 08c051956..84e8be25d 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -5,7 +5,9 @@ use std::{env, fs};
5 5
6use proc_macro2::{Ident, TokenStream}; 6use proc_macro2::{Ident, TokenStream};
7use quote::{format_ident, quote}; 7use quote::{format_ident, quote};
8use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccKernelClock, StopMode, METADATA}; 8use stm32_metapac::metadata::{
9 MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA,
10};
9 11
10fn main() { 12fn main() {
11 let target = env::var("TARGET").unwrap(); 13 let target = env::var("TARGET").unwrap();
@@ -374,12 +376,130 @@ fn main() {
374 } 376 }
375 } 377 }
376 378
377 let force_refcount = HashSet::from(["usart"]); 379 struct ClockGen<'a> {
378 let mut refcount_statics = BTreeSet::new(); 380 rcc_registers: &'a PeripheralRegisters,
381 chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>,
382 force_refcount: HashSet<&'a str>,
379 383
380 let mut clock_names = BTreeSet::new(); 384 refcount_statics: BTreeSet<Ident>,
385 clock_names: BTreeSet<String>,
386 muxes: BTreeSet<(Ident, Ident, Ident)>,
387 }
388
389 let mut clock_gen = ClockGen {
390 rcc_registers,
391 chained_muxes: HashMap::new(),
392 force_refcount: HashSet::from(["usart"]),
381 393
382 let mut rcc_cfgr_regs = BTreeSet::new(); 394 refcount_statics: BTreeSet::new(),
395 clock_names: BTreeSet::new(),
396 muxes: BTreeSet::new(),
397 };
398 if chip_name.starts_with("stm32h5") {
399 clock_gen.chained_muxes.insert(
400 "PER",
401 &PeripheralRccRegister {
402 register: "CCIPR5",
403 field: "PERSEL",
404 },
405 );
406 }
407 if chip_name.starts_with("stm32h7") {
408 clock_gen.chained_muxes.insert(
409 "PER",
410 &PeripheralRccRegister {
411 register: "D1CCIPR",
412 field: "PERSEL",
413 },
414 );
415 }
416 if chip_name.starts_with("stm32u5") {
417 clock_gen.chained_muxes.insert(
418 "ICLK",
419 &PeripheralRccRegister {
420 register: "CCIPR1",
421 field: "ICLKSEL",
422 },
423 );
424 }
425 if chip_name.starts_with("stm32wb") && !chip_name.starts_with("stm32wba") {
426 clock_gen.chained_muxes.insert(
427 "CLK48",
428 &PeripheralRccRegister {
429 register: "CCIPR",
430 field: "CLK48SEL",
431 },
432 );
433 }
434 if chip_name.starts_with("stm32f7") {
435 clock_gen.chained_muxes.insert(
436 "CLK48",
437 &PeripheralRccRegister {
438 register: "DCKCFGR2",
439 field: "CLK48SEL",
440 },
441 );
442 }
443 if chip_name.starts_with("stm32f4") && !chip_name.starts_with("stm32f410") {
444 clock_gen.chained_muxes.insert(
445 "CLK48",
446 &PeripheralRccRegister {
447 register: "DCKCFGR",
448 field: "CLK48SEL",
449 },
450 );
451 }
452
453 impl<'a> ClockGen<'a> {
454 fn gen_clock(&mut self, name: &str) -> TokenStream {
455 let clock_name = format_ident!("{}", name.to_ascii_lowercase());
456 self.clock_names.insert(name.to_ascii_lowercase());
457 quote!( unsafe { crate::rcc::get_freqs().#clock_name.unwrap() } )
458 }
459
460 fn gen_mux(&mut self, mux: &PeripheralRccRegister) -> TokenStream {
461 let ir = &self.rcc_registers.ir;
462 let fieldset_name = mux.register.to_ascii_lowercase();
463 let fieldset = ir
464 .fieldsets
465 .iter()
466 .find(|i| i.name.eq_ignore_ascii_case(&fieldset_name))
467 .unwrap();
468 let field_name = mux.field.to_ascii_lowercase();
469 let field = fieldset.fields.iter().find(|i| i.name == field_name).unwrap();
470 let enum_name = field.enumm.unwrap();
471 let enumm = ir.enums.iter().find(|i| i.name == enum_name).unwrap();
472
473 let fieldset_name = format_ident!("{}", fieldset_name);
474 let field_name = format_ident!("{}", field_name);
475 let enum_name = format_ident!("{}", enum_name);
476
477 self.muxes
478 .insert((fieldset_name.clone(), field_name.clone(), enum_name.clone()));
479
480 let mut match_arms = TokenStream::new();
481
482 for v in enumm.variants.iter().filter(|v| v.name != "DISABLE") {
483 let variant_name = format_ident!("{}", v.name);
484 let expr = if let Some(mux) = self.chained_muxes.get(&v.name) {
485 self.gen_mux(mux)
486 } else {
487 self.gen_clock(&v.name)
488 };
489 match_arms.extend(quote! {
490 crate::pac::rcc::vals::#enum_name::#variant_name => #expr,
491 });
492 }
493
494 quote! {
495 match crate::pac::RCC.#fieldset_name().read().#field_name() {
496 #match_arms
497 #[allow(unreachable_patterns)]
498 _ => unreachable!(),
499 }
500 }
501 }
502 }
383 503
384 for p in METADATA.peripherals { 504 for p in METADATA.peripherals {
385 if !singletons.contains(&p.name.to_string()) { 505 if !singletons.contains(&p.name.to_string()) {
@@ -416,12 +536,12 @@ fn main() {
416 let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); 536 let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
417 537
418 let refcount = 538 let refcount =
419 force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1; 539 clock_gen.force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1;
420 let (before_enable, before_disable) = if refcount { 540 let (before_enable, before_disable) = if refcount {
421 let refcount_static = 541 let refcount_static =
422 format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); 542 format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase());
423 543
424 refcount_statics.insert(refcount_static.clone()); 544 clock_gen.refcount_statics.insert(refcount_static.clone());
425 545
426 ( 546 (
427 quote! { 547 quote! {
@@ -442,63 +562,12 @@ fn main() {
442 }; 562 };
443 563
444 let clock_frequency = match &rcc.kernel_clock { 564 let clock_frequency = match &rcc.kernel_clock {
445 PeripheralRccKernelClock::Mux(mux) => { 565 PeripheralRccKernelClock::Mux(mux) => clock_gen.gen_mux(mux),
446 let ir = &rcc_registers.ir; 566 PeripheralRccKernelClock::Clock(clock) => clock_gen.gen_clock(clock),
447 let fieldset_name = mux.register.to_ascii_lowercase();
448 let fieldset = ir
449 .fieldsets
450 .iter()
451 .find(|i| i.name.eq_ignore_ascii_case(&fieldset_name))
452 .unwrap();
453 let field_name = mux.field.to_ascii_lowercase();
454 let field = fieldset.fields.iter().find(|i| i.name == field_name).unwrap();
455 let enum_name = field.enumm.unwrap();
456 let enumm = ir.enums.iter().find(|i| i.name == enum_name).unwrap();
457
458 let fieldset_name = format_ident!("{}", fieldset_name);
459 let field_name = format_ident!("{}", field_name);
460 let enum_name = format_ident!("{}", enum_name);
461
462 rcc_cfgr_regs.insert((fieldset_name.clone(), field_name.clone(), enum_name.clone()));
463
464 let match_arms: TokenStream = enumm
465 .variants
466 .iter()
467 .filter(|v| v.name != "DISABLE")
468 .map(|v| {
469 let variant_name = format_ident!("{}", v.name);
470 let clock_name = format_ident!("{}", v.name.to_ascii_lowercase());
471 clock_names.insert(v.name.to_ascii_lowercase());
472 quote! {
473 #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
474 }
475 })
476 .collect();
477
478 quote! {
479 use crate::pac::rcc::vals::#enum_name;
480
481 #[allow(unreachable_patterns)]
482 match crate::pac::RCC.#fieldset_name().read().#field_name() {
483 #match_arms
484 _ => unreachable!(),
485 }
486 }
487 }
488 PeripheralRccKernelClock::Clock(clock) => {
489 let clock = clock.to_ascii_lowercase();
490 let clock_name = format_ident!("{}", clock);
491 clock_names.insert(clock.to_string());
492 quote! {
493 unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }
494 }
495 }
496 }; 567 };
497 568
498 /* 569 // A refcount leak can result if the same field is shared by peripherals with different stop modes
499 A refcount leak can result if the same field is shared by peripherals with different stop modes 570 // This condition should be checked in stm32-data
500 This condition should be checked in stm32-data
501 */
502 let stop_refcount = match rcc.stop_mode { 571 let stop_refcount = match rcc.stop_mode {
503 StopMode::Standby => None, 572 StopMode::Standby => None,
504 StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }), 573 StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }),
@@ -543,74 +612,79 @@ fn main() {
543 } 612 }
544 } 613 }
545 614
546 if !rcc_cfgr_regs.is_empty() { 615 let struct_fields: Vec<_> = clock_gen
547 println!("cargo:rustc-cfg=clock_mux"); 616 .muxes
617 .iter()
618 .map(|(_fieldset, fieldname, enum_name)| {
619 quote! {
620 pub #fieldname: #enum_name
621 }
622 })
623 .collect();
548 624
549 let struct_fields: Vec<_> = rcc_cfgr_regs 625 let mut inits = TokenStream::new();
626 for fieldset in clock_gen
627 .muxes
628 .iter()
629 .map(|(f, _, _)| f)
630 .collect::<BTreeSet<_>>()
631 .into_iter()
632 {
633 let setters: Vec<_> = clock_gen
634 .muxes
550 .iter() 635 .iter()
551 .map(|(_fieldset, fieldname, enum_name)| { 636 .filter(|(f, _, _)| f == fieldset)
637 .map(|(_, fieldname, _)| {
638 let setter = format_ident!("set_{}", fieldname);
552 quote! { 639 quote! {
553 pub #fieldname: Option<#enum_name> 640 w.#setter(self.#fieldname);
554 } 641 }
555 }) 642 })
556 .collect(); 643 .collect();
557 644
558 let field_names: Vec<_> = rcc_cfgr_regs 645 inits.extend(quote! {
559 .iter() 646 crate::pac::RCC.#fieldset().modify(|w| {
560 .map(|(_fieldset, fieldname, _enum_name)| fieldname) 647 #(#setters)*
561 .collect(); 648 });
649 })
650 }
562 651
563 let inits: Vec<_> = rcc_cfgr_regs 652 let enum_names: BTreeSet<_> = clock_gen.muxes.iter().map(|(_, _, enum_name)| enum_name).collect();
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 653
579 let enum_names: BTreeSet<_> = rcc_cfgr_regs 654 g.extend(quote! {
580 .iter() 655 pub mod mux {
581 .map(|(_fieldset, _fieldname, enum_name)| enum_name) 656 #(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )*
582 .collect();
583 657
584 g.extend(quote! { 658 #[derive(Clone, Copy)]
585 pub mod mux { 659 pub struct ClockMux {
586 #(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )* 660 #( #struct_fields, )*
661 }
587 662
588 #[derive(Clone, Copy)] 663 impl ClockMux {
589 pub struct ClockMux { 664 pub(crate) const fn default() -> Self {
590 #( #struct_fields, )* 665 // safety: zero value is valid for all PAC enums.
666 unsafe { ::core::mem::zeroed() }
591 } 667 }
668 }
592 669
593 impl Default for ClockMux { 670 impl Default for ClockMux {
594 fn default() -> Self { 671 fn default() -> Self {
595 Self { 672 Self::default()
596 #( #field_names: None, )*
597 }
598 }
599 } 673 }
674 }
600 675
601 impl ClockMux { 676 impl ClockMux {
602 pub fn init(self) { 677 pub(crate) fn init(&self) {
603 #( #inits )* 678 #inits
604 }
605 } 679 }
606 } 680 }
607 }); 681 }
608 } 682 });
609 683
610 // Generate RCC 684 // Generate RCC
611 clock_names.insert("sys".to_string()); 685 clock_gen.clock_names.insert("sys".to_string());
612 clock_names.insert("rtc".to_string()); 686 clock_gen.clock_names.insert("rtc".to_string());
613 let clock_idents: Vec<_> = clock_names.iter().map(|n| format_ident!("{}", n)).collect(); 687 let clock_idents: Vec<_> = clock_gen.clock_names.iter().map(|n| format_ident!("{}", n)).collect();
614 g.extend(quote! { 688 g.extend(quote! {
615 #[derive(Clone, Copy, Debug)] 689 #[derive(Clone, Copy, Debug)]
616 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 690 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -640,7 +714,8 @@ fn main() {
640 } 714 }
641 ); 715 );
642 716
643 let refcount_mod: TokenStream = refcount_statics 717 let refcount_mod: TokenStream = clock_gen
718 .refcount_statics
644 .iter() 719 .iter()
645 .map(|refcount_static| { 720 .map(|refcount_static| {
646 quote! { 721 quote! {
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index 663a7f59d..523719bb9 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -7,7 +7,6 @@ use core::task::Poll;
7use self::sealed::Instance; 7use self::sealed::Instance;
8use crate::interrupt; 8use crate::interrupt;
9use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
10use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel};
11use crate::peripherals::IPCC; 10use crate::peripherals::IPCC;
12use crate::rcc::sealed::RccPeripheral; 11use crate::rcc::sealed::RccPeripheral;
13 12
@@ -105,7 +104,8 @@ impl Ipcc {
105 IPCC::enable_and_reset(); 104 IPCC::enable_and_reset();
106 IPCC::set_cpu2(true); 105 IPCC::set_cpu2(true);
107 106
108 _configure_pwr(); 107 // set RF wake-up clock = LSE
108 crate::pac::RCC.csr().modify(|w| w.set_rfwkpsel(0b01));
109 109
110 let regs = IPCC::regs(); 110 let regs = IPCC::regs();
111 111
@@ -271,18 +271,3 @@ pub(crate) mod sealed {
271 fn state() -> &'static State; 271 fn state() -> &'static State;
272 } 272 }
273} 273}
274
275fn _configure_pwr() {
276 // TODO: move the rest of this to rcc
277 let rcc = crate::pac::RCC;
278
279 // TODO: required
280 // set RF wake-up clock = LSE
281 rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
282
283 // set LPTIM1 & LPTIM2 clock source
284 rcc.ccipr().modify(|w| {
285 w.set_lptim1sel(Lptim1sel::PCLK1);
286 w.set_lptim2sel(Lptim2sel::PCLK1);
287 });
288}
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index ec6ec34e8..1946c5a15 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -21,6 +21,9 @@ pub struct Config {
21 pub ahb_pre: AHBPrescaler, 21 pub ahb_pre: AHBPrescaler,
22 pub apb_pre: APBPrescaler, 22 pub apb_pre: APBPrescaler,
23 pub ls: super::LsConfig, 23 pub ls: super::LsConfig,
24
25 /// Per-peripheral kernel clock selection muxes
26 pub mux: super::mux::ClockMux,
24} 27}
25 28
26impl Default for Config { 29impl Default for Config {
@@ -31,6 +34,7 @@ impl Default for Config {
31 ahb_pre: AHBPrescaler::DIV1, 34 ahb_pre: AHBPrescaler::DIV1,
32 apb_pre: APBPrescaler::DIV1, 35 apb_pre: APBPrescaler::DIV1,
33 ls: Default::default(), 36 ls: Default::default(),
37 mux: Default::default(),
34 } 38 }
35 } 39 }
36} 40}
@@ -97,28 +101,25 @@ pub(crate) unsafe fn init(config: Config) {
97 101
98 if !set_flash_latency_after { 102 if !set_flash_latency_after {
99 // Spin until the effective flash latency is compatible with the clock change 103 // Spin until the effective flash latency is compatible with the clock change
100 while FLASH.acr().read().latency().to_bits() < target_flash_latency.to_bits() {} 104 while FLASH.acr().read().latency() < target_flash_latency {}
101 } 105 }
102 106
103 // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once 107 // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
104 let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre);
105 RCC.cfgr().modify(|w| { 108 RCC.cfgr().modify(|w| {
106 w.set_sw(sw); 109 w.set_sw(sw);
107 w.set_hpre(hpre); 110 w.set_hpre(config.ahb_pre);
108 w.set_ppre(ppre); 111 w.set_ppre(config.apb_pre);
109 }); 112 });
110 113 // Spin until the SYSCLK changes have taken effect
111 if set_flash_latency_after { 114 loop {
112 // We can make the flash require fewer wait states 115 let cfgr = RCC.cfgr().read();
113 // Spin until the SYSCLK changes have taken effect 116 if cfgr.sw() == sw && cfgr.hpre() == config.ahb_pre && cfgr.ppre() == config.apb_pre {
114 loop { 117 break;
115 let cfgr = RCC.cfgr().read();
116 if cfgr.sw() == sw && cfgr.hpre() == hpre && cfgr.ppre() == ppre {
117 break;
118 }
119 } 118 }
119 }
120 120
121 // Set the flash latency to require fewer wait states 121 // Set the flash latency to require fewer wait states
122 if set_flash_latency_after {
122 FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); 123 FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
123 } 124 }
124 125
@@ -132,6 +133,11 @@ pub(crate) unsafe fn init(config: Config) {
132 } 133 }
133 }; 134 };
134 135
136 config.mux.init();
137
138 // without this, the ringbuffered uart test fails.
139 cortex_m::asm::dsb();
140
135 set_clocks!( 141 set_clocks!(
136 hsi: None, 142 hsi: None,
137 lse: None, 143 lse: None,
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 5046f0a3a..215f8a3d2 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -98,8 +98,8 @@ pub struct Config {
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 100
101 #[cfg(clock_mux)] 101 /// Per-peripheral kernel clock selection muxes
102 pub mux: crate::rcc::mux::ClockMux, 102 pub mux: super::mux::ClockMux,
103 103
104 pub ls: super::LsConfig, 104 pub ls: super::LsConfig,
105} 105}
@@ -128,7 +128,6 @@ impl Default for Config {
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 130
131 #[cfg(clock_mux)]
132 mux: Default::default(), 131 mux: Default::default(),
133 } 132 }
134 } 133 }
@@ -370,7 +369,6 @@ pub(crate) unsafe fn init(config: Config) {
370 }; 369 };
371 */ 370 */
372 371
373 #[cfg(clock_mux)]
374 config.mux.init(); 372 config.mux.init();
375 373
376 set_clocks!( 374 set_clocks!(
diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs
index 343d075cd..7b252870c 100644
--- a/embassy-stm32/src/rcc/f247.rs
+++ b/embassy-stm32/src/rcc/f247.rs
@@ -95,6 +95,9 @@ pub struct Config {
95 95
96 pub ls: super::LsConfig, 96 pub ls: super::LsConfig,
97 97
98 /// Per-peripheral kernel clock selection muxes
99 pub mux: super::mux::ClockMux,
100
98 #[cfg(stm32f2)] 101 #[cfg(stm32f2)]
99 pub voltage: VoltageScale, 102 pub voltage: VoltageScale,
100} 103}
@@ -120,6 +123,7 @@ impl Default for Config {
120 123
121 #[cfg(stm32f2)] 124 #[cfg(stm32f2)]
122 voltage: VoltageScale::Range3, 125 voltage: VoltageScale::Range3,
126 mux: Default::default(),
123 } 127 }
124 } 128 }
125} 129}
@@ -256,6 +260,8 @@ pub(crate) unsafe fn init(config: Config) {
256 }); 260 });
257 while RCC.cfgr().read().sws() != config.sys {} 261 while RCC.cfgr().read().sws() != config.sys {}
258 262
263 config.mux.init();
264
259 set_clocks!( 265 set_clocks!(
260 hsi: hsi, 266 hsi: hsi,
261 hse: hse, 267 hse: hse,
@@ -286,7 +292,9 @@ pub(crate) unsafe fn init(config: Config) {
286 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 292 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
287 pllsai1_r: pllsai.r, 293 pllsai1_r: pllsai.r,
288 294
289 clk48: pll.q, 295 // TODO workaround until f4 rcc is fixed in stm32-data
296 #[cfg(not(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7)))]
297 pllsai1_q: None,
290 298
291 hsi_div488: hsi.map(|hsi| hsi/488u32), 299 hsi_div488: hsi.map(|hsi| hsi/488u32),
292 hsi_hse: None, 300 hsi_hse: None,
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index ae502dd9c..5cfe9953b 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -71,22 +71,6 @@ pub enum PllSource {
71 HSE(Hertz, HseMode), 71 HSE(Hertz, HseMode),
72} 72}
73 73
74/// Sets the source for the 48MHz clock to the USB peripheral.
75#[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))]
76pub enum UsbSrc {
77 /// Use the High Speed Internal Oscillator. The CRS must be used to calibrate the
78 /// oscillator to comply with the USB specification for oscillator tolerance.
79 #[cfg(any(stm32g0b1, stm32g0c1))]
80 Hsi48(super::Hsi48Config),
81 /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. The
82 /// PLL needs to be using the HSE source to comply with the USB specification for oscillator
83 /// tolerance.
84 PllQ,
85 /// Use the HSE source directly. The HSE must be a 48MHz source. The HSE source must comply
86 /// with the USB specification for oscillator tolerance.
87 HSE,
88}
89
90/// Clocks configutation 74/// Clocks configutation
91pub struct Config { 75pub struct Config {
92 pub sys: Sysclk, 76 pub sys: Sysclk,
@@ -94,8 +78,10 @@ pub struct Config {
94 pub apb_pre: APBPrescaler, 78 pub apb_pre: APBPrescaler,
95 pub low_power_run: bool, 79 pub low_power_run: bool,
96 pub ls: super::LsConfig, 80 pub ls: super::LsConfig,
97 #[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))] 81 #[cfg(crs)]
98 pub usb_src: Option<UsbSrc>, 82 pub hsi48: Option<super::Hsi48Config>,
83 /// Per-peripheral kernel clock selection muxes
84 pub mux: super::mux::ClockMux,
99} 85}
100 86
101impl Default for Config { 87impl Default for Config {
@@ -107,8 +93,9 @@ impl Default for Config {
107 apb_pre: APBPrescaler::DIV1, 93 apb_pre: APBPrescaler::DIV1,
108 low_power_run: false, 94 low_power_run: false,
109 ls: Default::default(), 95 ls: Default::default(),
110 #[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))] 96 #[cfg(crs)]
111 usb_src: None, 97 hsi48: Some(Default::default()),
98 mux: Default::default(),
112 } 99 }
113 } 100 }
114} 101}
@@ -322,34 +309,12 @@ pub(crate) unsafe fn init(config: Config) {
322 let lsi_freq = (sw == Sw::LSI).then_some(super::LSI_FREQ); 309 let lsi_freq = (sw == Sw::LSI).then_some(super::LSI_FREQ);
323 let hse_freq = (sw == Sw::HSE).then_some(sys_clk); 310 let hse_freq = (sw == Sw::HSE).then_some(sys_clk);
324 311
325 #[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))] 312 #[cfg(crs)]
326 let hsi48_freq = config.usb_src.and_then(|config| { 313 let hsi48 = config.hsi48.map(super::init_hsi48);
327 match config { 314 #[cfg(not(crs))]
328 UsbSrc::PllQ => { 315 let hsi48: Option<Hertz> = None;
329 // Make sure the PLLQ is enabled and running at 48Mhz 316
330 assert!(pll1_q_freq.is_some() && pll1_q_freq.unwrap().0 == 48_000_000); 317 config.mux.init();
331 RCC.ccipr2()
332 .modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::PLL1_Q));
333 None
334 }
335 UsbSrc::HSE => {
336 // Make sure the HSE is enabled and running at 48Mhz
337 assert!(hse_freq.is_some() && hse_freq.unwrap().0 == 48_000_000);
338 RCC.ccipr2()
339 .modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSE));
340 None
341 }
342 #[cfg(any(stm32g0b1, stm32g0c1))]
343 UsbSrc::Hsi48(config) => {
344 let freq = super::init_hsi48(config);
345 RCC.ccipr2()
346 .modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSI48));
347 Some(freq)
348 }
349 }
350 });
351 #[cfg(not(any(stm32g0b1, stm32g0c1, stm32g0b0)))]
352 let hsi48_freq: Option<Hertz> = None;
353 318
354 set_clocks!( 319 set_clocks!(
355 sys: Some(sys_clk), 320 sys: Some(sys_clk),
@@ -357,7 +322,7 @@ pub(crate) unsafe fn init(config: Config) {
357 pclk1: Some(apb_freq), 322 pclk1: Some(apb_freq),
358 pclk1_tim: Some(apb_tim_freq), 323 pclk1_tim: Some(apb_tim_freq),
359 hsi: hsi_freq, 324 hsi: hsi_freq,
360 hsi48: hsi48_freq, 325 hsi48: hsi48,
361 hsi_div_8: hsi_div_8_freq, 326 hsi_div_8: hsi_div_8_freq,
362 hse: hse_freq, 327 hse: hse_freq,
363 lse: lse_freq, 328 lse: lse_freq,
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 6ed266284..79bdbeb77 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -1,11 +1,10 @@
1use stm32_metapac::flash::vals::Latency; 1use stm32_metapac::flash::vals::Latency;
2use stm32_metapac::rcc::vals::{Adcsel, Sw}; 2use stm32_metapac::rcc::vals::Sw;
3use stm32_metapac::FLASH; 3use stm32_metapac::FLASH;
4 4
5pub use crate::pac::rcc::vals::{ 5pub use crate::pac::rcc::vals::{
6 Adcsel as AdcClockSource, Clk48sel as Clk48Src, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler, 6 Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc,
7 Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc, Ppre as APBPrescaler, 7 Ppre as APBPrescaler, Sw as Sysclk,
8 Sw as Sysclk,
9}; 8};
10use crate::pac::{PWR, RCC}; 9use crate::pac::{PWR, RCC};
11use crate::time::Hertz; 10use crate::time::Hertz;
@@ -82,24 +81,15 @@ pub struct Config {
82 81
83 pub low_power_run: bool, 82 pub low_power_run: bool,
84 83
85 /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
86 pub clk48_src: Clk48Src,
87
88 /// Low-Speed Clock Configuration 84 /// Low-Speed Clock Configuration
89 pub ls: super::LsConfig, 85 pub ls: super::LsConfig,
90 86
91 /// Clock Source for ADCs 1 and 2
92 pub adc12_clock_source: AdcClockSource,
93
94 /// Clock Source for ADCs 3, 4 and 5
95 pub adc345_clock_source: AdcClockSource,
96
97 /// Clock Source for FDCAN
98 pub fdcan_clock_source: FdCanClockSource,
99
100 /// Enable range1 boost mode 87 /// Enable range1 boost mode
101 /// Recommended when the SYSCLK frequency is greater than 150MHz. 88 /// Recommended when the SYSCLK frequency is greater than 150MHz.
102 pub boost: bool, 89 pub boost: bool,
90
91 /// Per-peripheral kernel clock selection muxes
92 pub mux: super::mux::ClockMux,
103} 93}
104 94
105impl Default for Config { 95impl Default for Config {
@@ -115,12 +105,9 @@ impl Default for Config {
115 apb1_pre: APBPrescaler::DIV1, 105 apb1_pre: APBPrescaler::DIV1,
116 apb2_pre: APBPrescaler::DIV1, 106 apb2_pre: APBPrescaler::DIV1,
117 low_power_run: false, 107 low_power_run: false,
118 clk48_src: Clk48Src::HSI48,
119 ls: Default::default(), 108 ls: Default::default(),
120 adc12_clock_source: Adcsel::DISABLE,
121 adc345_clock_source: Adcsel::DISABLE,
122 fdcan_clock_source: FdCanClockSource::PCLK1,
123 boost: false, 109 boost: false,
110 mux: Default::default(),
124 } 111 }
125 } 112 }
126} 113}
@@ -165,9 +152,7 @@ pub(crate) unsafe fn init(config: Config) {
165 }; 152 };
166 153
167 // Configure HSI48 if required 154 // Configure HSI48 if required
168 if let Some(hsi48_config) = config.hsi48 { 155 let hsi48 = config.hsi48.map(super::init_hsi48);
169 super::init_hsi48(hsi48_config);
170 }
171 156
172 let pll_freq = config.pll.map(|pll_config| { 157 let pll_freq = config.pll.map(|pll_config| {
173 let src_freq = match pll_config.source { 158 let src_freq = match pll_config.source {
@@ -176,13 +161,13 @@ pub(crate) unsafe fn init(config: Config) {
176 _ => unreachable!(), 161 _ => unreachable!(),
177 }; 162 };
178 163
179 assert!(max::PLL_IN.contains(&src_freq));
180
181 // Disable PLL before configuration 164 // Disable PLL before configuration
182 RCC.cr().modify(|w| w.set_pllon(false)); 165 RCC.cr().modify(|w| w.set_pllon(false));
183 while RCC.cr().read().pllrdy() {} 166 while RCC.cr().read().pllrdy() {}
184 167
185 let internal_freq = src_freq / pll_config.prediv * pll_config.mul; 168 let in_freq = src_freq / pll_config.prediv;
169 assert!(max::PLL_IN.contains(&in_freq));
170 let internal_freq = in_freq * pll_config.mul;
186 171
187 assert!(max::PLL_VCO.contains(&internal_freq)); 172 assert!(max::PLL_VCO.contains(&internal_freq));
188 173
@@ -301,42 +286,6 @@ pub(crate) unsafe fn init(config: Config) {
301 let (apb1_freq, apb1_tim_freq) = super::util::calc_pclk(hclk, config.apb1_pre); 286 let (apb1_freq, apb1_tim_freq) = super::util::calc_pclk(hclk, config.apb1_pre);
302 let (apb2_freq, apb2_tim_freq) = super::util::calc_pclk(hclk, config.apb2_pre); 287 let (apb2_freq, apb2_tim_freq) = super::util::calc_pclk(hclk, config.apb2_pre);
303 288
304 // Configure the 48MHz clock source for USB and RNG peripherals.
305 RCC.ccipr().modify(|w| {
306 w.set_clk48sel(match config.clk48_src {
307 Clk48Src::PLL1_Q => {
308 // Not checking that PLL1_Q is 48MHz here so as not to require the user to have a 48MHz clock.
309 // Peripherals which require one (USB, RNG) should check that they‘re driven by a valid 48MHz
310 // clock at init.
311 crate::pac::rcc::vals::Clk48sel::PLL1_Q
312 }
313 Clk48Src::HSI48 => {
314 // Make sure HSI48 is enabled
315 assert!(config.hsi48.is_some());
316 crate::pac::rcc::vals::Clk48sel::HSI48
317 }
318 _ => unreachable!(),
319 })
320 });
321
322 RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source));
323 RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source));
324 RCC.ccipr().modify(|w| w.set_fdcansel(config.fdcan_clock_source));
325
326 let adc12_ck = match config.adc12_clock_source {
327 AdcClockSource::DISABLE => None,
328 AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p,
329 AdcClockSource::SYS => Some(sys_clk),
330 _ => unreachable!(),
331 };
332
333 let adc345_ck = match config.adc345_clock_source {
334 AdcClockSource::DISABLE => None,
335 AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p,
336 AdcClockSource::SYS => Some(sys_clk),
337 _ => unreachable!(),
338 };
339
340 if config.low_power_run { 289 if config.low_power_run {
341 assert!(sys_clk <= Hertz(2_000_000)); 290 assert!(sys_clk <= Hertz(2_000_000));
342 PWR.cr1().modify(|w| w.set_lpr(true)); 291 PWR.cr1().modify(|w| w.set_lpr(true));
@@ -344,6 +293,8 @@ pub(crate) unsafe fn init(config: Config) {
344 293
345 let rtc = config.ls.init(); 294 let rtc = config.ls.init();
346 295
296 config.mux.init();
297
347 set_clocks!( 298 set_clocks!(
348 sys: Some(sys_clk), 299 sys: Some(sys_clk),
349 hclk1: Some(hclk), 300 hclk1: Some(hclk),
@@ -353,12 +304,11 @@ pub(crate) unsafe fn init(config: Config) {
353 pclk1_tim: Some(apb1_tim_freq), 304 pclk1_tim: Some(apb1_tim_freq),
354 pclk2: Some(apb2_freq), 305 pclk2: Some(apb2_freq),
355 pclk2_tim: Some(apb2_tim_freq), 306 pclk2_tim: Some(apb2_tim_freq),
356 adc: adc12_ck,
357 adc34: adc345_ck,
358 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p), 307 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
359 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_q), 308 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_q),
360 pll1_r: pll_freq.as_ref().and_then(|pll| pll.pll_r), 309 pll1_r: pll_freq.as_ref().and_then(|pll| pll.pll_r),
361 hse: hse, 310 hse: hse,
311 hsi48: hsi48,
362 rtc: rtc, 312 rtc: rtc,
363 ); 313 );
364} 314}
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 7b2255cc6..bab8bb19e 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -2,15 +2,10 @@ use core::ops::RangeInclusive;
2 2
3use crate::pac; 3use crate::pac;
4use crate::pac::pwr::vals::Vos; 4use crate::pac::pwr::vals::Vos;
5#[cfg(stm32h5)]
6pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource;
7#[cfg(stm32h7)]
8pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
9pub use crate::pac::rcc::vals::{ 5pub use crate::pac::rcc::vals::{
10 Ckpersel as PerClockSource, Fdcansel as FdCanClockSource, Hsidiv as HSIPrescaler, Plldiv as PllDiv, 6 Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
11 Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
12}; 7};
13use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre}; 8use crate::pac::rcc::vals::{Pllrge, Pllvcosel, Timpre};
14use crate::pac::{FLASH, PWR, RCC}; 9use crate::pac::{FLASH, PWR, RCC};
15use crate::time::Hertz; 10use crate::time::Hertz;
16 11
@@ -194,16 +189,15 @@ pub struct Config {
194 #[cfg(stm32h7)] 189 #[cfg(stm32h7)]
195 pub apb4_pre: APBPrescaler, 190 pub apb4_pre: APBPrescaler,
196 191
197 pub per_clock_source: PerClockSource,
198 pub adc_clock_source: AdcClockSource,
199 pub fdcan_clock_source: FdCanClockSource,
200
201 pub timer_prescaler: TimerPrescaler, 192 pub timer_prescaler: TimerPrescaler,
202 pub voltage_scale: VoltageScale, 193 pub voltage_scale: VoltageScale,
203 pub ls: super::LsConfig, 194 pub ls: super::LsConfig,
204 195
205 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 196 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))]
206 pub supply_config: SupplyConfig, 197 pub supply_config: SupplyConfig,
198
199 /// Per-peripheral kernel clock selection muxes
200 pub mux: super::mux::ClockMux,
207} 201}
208 202
209impl Default for Config { 203impl Default for Config {
@@ -227,21 +221,14 @@ impl Default for Config {
227 #[cfg(stm32h7)] 221 #[cfg(stm32h7)]
228 apb4_pre: APBPrescaler::DIV1, 222 apb4_pre: APBPrescaler::DIV1,
229 223
230 per_clock_source: PerClockSource::HSI,
231
232 #[cfg(stm32h5)]
233 adc_clock_source: AdcClockSource::HCLK1,
234 #[cfg(stm32h7)]
235 adc_clock_source: AdcClockSource::PER,
236
237 fdcan_clock_source: FdCanClockSource::from_bits(0), // HSE
238
239 timer_prescaler: TimerPrescaler::DefaultX2, 224 timer_prescaler: TimerPrescaler::DefaultX2,
240 voltage_scale: VoltageScale::Scale0, 225 voltage_scale: VoltageScale::Scale0,
241 ls: Default::default(), 226 ls: Default::default(),
242 227
243 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 228 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))]
244 supply_config: SupplyConfig::Default, 229 supply_config: SupplyConfig::Default,
230
231 mux: Default::default(),
245 } 232 }
246 } 233 }
247} 234}
@@ -504,31 +491,6 @@ pub(crate) unsafe fn init(config: Config) {
504 #[cfg(stm32h7)] 491 #[cfg(stm32h7)]
505 assert!(apb4 <= pclk_max); 492 assert!(apb4 <= pclk_max);
506 493
507 let _per_ck = match config.per_clock_source {
508 Ckpersel::HSI => hsi,
509 Ckpersel::CSI => csi,
510 Ckpersel::HSE => hse,
511 _ => unreachable!(),
512 };
513
514 #[cfg(stm32h7)]
515 let adc = match config.adc_clock_source {
516 AdcClockSource::PLL2_P => pll2.p,
517 AdcClockSource::PLL3_R => pll3.r,
518 AdcClockSource::PER => _per_ck,
519 _ => unreachable!(),
520 };
521 #[cfg(stm32h5)]
522 let adc = match config.adc_clock_source {
523 AdcClockSource::HCLK1 => Some(hclk),
524 AdcClockSource::SYS => Some(sys),
525 AdcClockSource::PLL2_R => pll2.r,
526 AdcClockSource::HSE => hse,
527 AdcClockSource::HSI => hsi,
528 AdcClockSource::CSI => csi,
529 _ => unreachable!(),
530 };
531
532 flash_setup(hclk, config.voltage_scale); 494 flash_setup(hclk, config.voltage_scale);
533 495
534 let rtc = config.ls.init(); 496 let rtc = config.ls.init();
@@ -550,16 +512,6 @@ pub(crate) unsafe fn init(config: Config) {
550 RCC.d3cfgr().modify(|w| { 512 RCC.d3cfgr().modify(|w| {
551 w.set_d3ppre(config.apb4_pre); 513 w.set_d3ppre(config.apb4_pre);
552 }); 514 });
553
554 RCC.d1ccipr().modify(|w| {
555 w.set_ckpersel(config.per_clock_source);
556 });
557 RCC.d3ccipr().modify(|w| {
558 w.set_adcsel(config.adc_clock_source);
559 });
560 RCC.d2ccip1r().modify(|w| {
561 w.set_fdcansel(config.fdcan_clock_source);
562 });
563 } 515 }
564 #[cfg(stm32h5)] 516 #[cfg(stm32h5)]
565 { 517 {
@@ -573,12 +525,6 @@ pub(crate) unsafe fn init(config: Config) {
573 w.set_ppre2(config.apb2_pre); 525 w.set_ppre2(config.apb2_pre);
574 w.set_ppre3(config.apb3_pre); 526 w.set_ppre3(config.apb3_pre);
575 }); 527 });
576
577 RCC.ccipr5().modify(|w| {
578 w.set_ckpersel(config.per_clock_source);
579 w.set_adcdacsel(config.adc_clock_source);
580 w.set_fdcan12sel(config.fdcan_clock_source)
581 });
582 } 528 }
583 529
584 RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into())); 530 RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into()));
@@ -601,6 +547,8 @@ pub(crate) unsafe fn init(config: Config) {
601 while !pac::SYSCFG.cccsr().read().ready() {} 547 while !pac::SYSCFG.cccsr().read().ready() {}
602 } 548 }
603 549
550 config.mux.init();
551
604 set_clocks!( 552 set_clocks!(
605 sys: Some(sys), 553 sys: Some(sys),
606 hclk1: Some(hclk), 554 hclk1: Some(hclk),
@@ -614,7 +562,6 @@ pub(crate) unsafe fn init(config: Config) {
614 pclk4: Some(apb4), 562 pclk4: Some(apb4),
615 pclk1_tim: Some(apb1_tim), 563 pclk1_tim: Some(apb1_tim),
616 pclk2_tim: Some(apb2_tim), 564 pclk2_tim: Some(apb2_tim),
617 adc: adc,
618 rtc: rtc, 565 rtc: rtc,
619 566
620 hsi: hsi, 567 hsi: hsi,
@@ -646,7 +593,6 @@ pub(crate) unsafe fn init(config: Config) {
646 593
647 #[cfg(stm32h5)] 594 #[cfg(stm32h5)]
648 audioclk: None, 595 audioclk: None,
649 per: None,
650 i2s_ckin: None, 596 i2s_ckin: None,
651 ); 597 );
652} 598}
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs
index aa4245d4e..9079ddd41 100644
--- a/embassy-stm32/src/rcc/l.rs
+++ b/embassy-stm32/src/rcc/l.rs
@@ -1,10 +1,6 @@
1#[cfg(any(stm32l0, stm32l1))] 1#[cfg(any(stm32l0, stm32l1))]
2pub use crate::pac::pwr::vals::Vos as VoltageScale; 2pub use crate::pac::pwr::vals::Vos as VoltageScale;
3use crate::pac::rcc::regs::Cfgr; 3use crate::pac::rcc::regs::Cfgr;
4#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
5pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
6#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
7pub use crate::pac::rcc::vals::Clk48sel as Clk48Src;
8#[cfg(any(stm32wb, stm32wl))] 4#[cfg(any(stm32wb, stm32wl))]
9pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; 5pub use crate::pac::rcc::vals::Hsepre as HsePrescaler;
10pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as Sysclk}; 6pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as Sysclk};
@@ -59,18 +55,14 @@ pub struct Config {
59 #[cfg(any(stm32wl, stm32wb))] 55 #[cfg(any(stm32wl, stm32wb))]
60 pub shared_ahb_pre: AHBPrescaler, 56 pub shared_ahb_pre: AHBPrescaler,
61 57
62 // muxes
63 #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
64 pub clk48_src: Clk48Src,
65
66 // low speed LSI/LSE/RTC 58 // low speed LSI/LSE/RTC
67 pub ls: super::LsConfig, 59 pub ls: super::LsConfig,
68 60
69 #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
70 pub adc_clock_source: AdcClockSource,
71
72 #[cfg(any(stm32l0, stm32l1))] 61 #[cfg(any(stm32l0, stm32l1))]
73 pub voltage_scale: VoltageScale, 62 pub voltage_scale: VoltageScale,
63
64 /// Per-peripheral kernel clock selection muxes
65 pub mux: super::mux::ClockMux,
74} 66}
75 67
76impl Default for Config { 68impl Default for Config {
@@ -95,13 +87,10 @@ impl Default for Config {
95 pllsai2: None, 87 pllsai2: None,
96 #[cfg(crs)] 88 #[cfg(crs)]
97 hsi48: Some(Default::default()), 89 hsi48: Some(Default::default()),
98 #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
99 clk48_src: Clk48Src::HSI48,
100 ls: Default::default(), 90 ls: Default::default(),
101 #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
102 adc_clock_source: AdcClockSource::SYS,
103 #[cfg(any(stm32l0, stm32l1))] 91 #[cfg(any(stm32l0, stm32l1))]
104 voltage_scale: VoltageScale::RANGE1, 92 voltage_scale: VoltageScale::RANGE1,
93 mux: Default::default(),
105 } 94 }
106 } 95 }
107} 96}
@@ -118,7 +107,6 @@ pub const WPAN_DEFAULT: Config = Config {
118 hsi48: Some(super::Hsi48Config { sync_from_usb: false }), 107 hsi48: Some(super::Hsi48Config { sync_from_usb: false }),
119 msi: None, 108 msi: None,
120 hsi: false, 109 hsi: false,
121 clk48_src: Clk48Src::PLL1_Q,
122 110
123 ls: super::LsConfig::default_lse(), 111 ls: super::LsConfig::default_lse(),
124 112
@@ -137,7 +125,8 @@ pub const WPAN_DEFAULT: Config = Config {
137 shared_ahb_pre: AHBPrescaler::DIV1, 125 shared_ahb_pre: AHBPrescaler::DIV1,
138 apb1_pre: APBPrescaler::DIV1, 126 apb1_pre: APBPrescaler::DIV1,
139 apb2_pre: APBPrescaler::DIV1, 127 apb2_pre: APBPrescaler::DIV1,
140 adc_clock_source: AdcClockSource::SYS, 128
129 mux: super::mux::ClockMux::default(),
141}; 130};
142 131
143fn msi_enable(range: MSIRange) { 132fn msi_enable(range: MSIRange) {
@@ -267,21 +256,6 @@ pub(crate) unsafe fn init(config: Config) {
267 Sysclk::PLL1_R => pll.r.unwrap(), 256 Sysclk::PLL1_R => pll.r.unwrap(),
268 }; 257 };
269 258
270 #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
271 RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
272 #[cfg(any(rcc_l0_v2))]
273 let clk48 = match config.clk48_src {
274 Clk48Src::HSI48 => hsi48,
275 Clk48Src::PLL1_VCO_DIV_2 => pll.clk48,
276 };
277 #[cfg(any(stm32l4, stm32l5, stm32wb))]
278 let clk48 = match config.clk48_src {
279 Clk48Src::HSI48 => hsi48,
280 Clk48Src::MSI => msi,
281 Clk48Src::PLLSAI1_Q => pllsai1.q,
282 Clk48Src::PLL1_Q => pll.q,
283 };
284
285 #[cfg(rcc_l4plus)] 259 #[cfg(rcc_l4plus)]
286 assert!(sys_clk.0 <= 120_000_000); 260 assert!(sys_clk.0 <= 120_000_000);
287 #[cfg(all(stm32l4, not(rcc_l4plus)))] 261 #[cfg(all(stm32l4, not(rcc_l4plus)))]
@@ -357,9 +331,6 @@ pub(crate) unsafe fn init(config: Config) {
357 }); 331 });
358 while RCC.cfgr().read().sws() != config.sys {} 332 while RCC.cfgr().read().sws() != config.sys {}
359 333
360 #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
361 RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source));
362
363 #[cfg(any(stm32wl, stm32wb))] 334 #[cfg(any(stm32wl, stm32wb))]
364 { 335 {
365 RCC.extcfgr().modify(|w| { 336 RCC.extcfgr().modify(|w| {
@@ -372,6 +343,8 @@ pub(crate) unsafe fn init(config: Config) {
372 while !RCC.extcfgr().read().c2hpref() {} 343 while !RCC.extcfgr().read().c2hpref() {}
373 } 344 }
374 345
346 config.mux.init();
347
375 set_clocks!( 348 set_clocks!(
376 sys: Some(sys_clk), 349 sys: Some(sys_clk),
377 hclk1: Some(hclk1), 350 hclk1: Some(hclk1),
@@ -388,10 +361,11 @@ pub(crate) unsafe fn init(config: Config) {
388 hsi: hsi, 361 hsi: hsi,
389 hse: hse, 362 hse: hse,
390 msi: msi, 363 msi: msi,
391 #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
392 clk48: clk48,
393 hsi48: hsi48, 364 hsi48: hsi48,
394 365
366 #[cfg(any(stm32l0, stm32l1))]
367 pll1_vco_div_2: pll.vco.map(|c| c/2u32),
368
395 #[cfg(not(any(stm32l0, stm32l1)))] 369 #[cfg(not(any(stm32l0, stm32l1)))]
396 pll1_p: pll.p, 370 pll1_p: pll.p,
397 #[cfg(not(any(stm32l0, stm32l1)))] 371 #[cfg(not(any(stm32l0, stm32l1)))]
@@ -511,7 +485,7 @@ mod pll {
511 #[derive(Default)] 485 #[derive(Default)]
512 pub(super) struct PllOutput { 486 pub(super) struct PllOutput {
513 pub r: Option<Hertz>, 487 pub r: Option<Hertz>,
514 pub clk48: Option<Hertz>, 488 pub vco: Option<Hertz>,
515 } 489 }
516 490
517 pub(super) fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput { 491 pub(super) fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput {
@@ -528,7 +502,6 @@ mod pll {
528 let vco_freq = pll_src * pll.mul; 502 let vco_freq = pll_src * pll.mul;
529 503
530 let r = vco_freq / pll.div; 504 let r = vco_freq / pll.div;
531 let clk48 = (vco_freq == Hertz(96_000_000)).then_some(Hertz(48_000_000));
532 505
533 assert!(r <= Hertz(32_000_000)); 506 assert!(r <= Hertz(32_000_000));
534 507
@@ -541,7 +514,10 @@ mod pll {
541 // Enable PLL 514 // Enable PLL
542 pll_enable(instance, true); 515 pll_enable(instance, true);
543 516
544 PllOutput { r: Some(r), clk48 } 517 PllOutput {
518 r: Some(r),
519 vco: Some(vco_freq),
520 }
545 } 521 }
546} 522}
547 523
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index c8ca713de..910ebe205 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -31,9 +31,7 @@ mod _version;
31 31
32pub use _version::*; 32pub use _version::*;
33 33
34#[cfg(clock_mux)] 34pub use crate::_generated::{mux, Clocks};
35pub use crate::_generated::mux;
36pub use crate::_generated::Clocks;
37 35
38#[cfg(feature = "low-power")] 36#[cfg(feature = "low-power")]
39/// Must be written within a critical section 37/// Must be written within a critical section
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index c8814ed69..9533e16c4 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -85,6 +85,9 @@ pub struct Config {
85 /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits. 85 /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits.
86 pub voltage_range: VoltageScale, 86 pub voltage_range: VoltageScale,
87 pub ls: super::LsConfig, 87 pub ls: super::LsConfig,
88
89 /// Per-peripheral kernel clock selection muxes
90 pub mux: super::mux::ClockMux,
88} 91}
89 92
90impl Default for Config { 93impl Default for Config {
@@ -104,6 +107,7 @@ impl Default for Config {
104 apb3_pre: APBPrescaler::DIV1, 107 apb3_pre: APBPrescaler::DIV1,
105 voltage_range: VoltageScale::RANGE1, 108 voltage_range: VoltageScale::RANGE1,
106 ls: Default::default(), 109 ls: Default::default(),
110 mux: Default::default(),
107 } 111 }
108 } 112 }
109} 113}
@@ -259,6 +263,8 @@ pub(crate) unsafe fn init(config: Config) {
259 263
260 let rtc = config.ls.init(); 264 let rtc = config.ls.init();
261 265
266 config.mux.init();
267
262 set_clocks!( 268 set_clocks!(
263 sys: Some(sys_clk), 269 sys: Some(sys_clk),
264 hclk1: Some(hclk), 270 hclk1: Some(hclk),
@@ -289,7 +295,6 @@ pub(crate) unsafe fn init(config: Config) {
289 lse: None, 295 lse: None,
290 lsi: None, 296 lsi: None,
291 msik: None, 297 msik: None,
292 iclk: None,
293 shsi: None, 298 shsi: None,
294 shsi_div_2: None, 299 shsi_div_2: None,
295 ); 300 );
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
index 9d5dcfc4b..8e1779d7c 100644
--- a/embassy-stm32/src/rcc/wba.rs
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -1,8 +1,6 @@
1pub use crate::pac::pwr::vals::Vos as VoltageScale; 1pub use crate::pac::pwr::vals::Vos as VoltageScale;
2use crate::pac::rcc::regs::Cfgr1; 2use crate::pac::rcc::regs::Cfgr1;
3pub use crate::pac::rcc::vals::{ 3pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk};
4 Adcsel as AdcClockSource, Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk,
5};
6use crate::pac::{FLASH, RCC}; 4use crate::pac::{FLASH, RCC};
7use crate::time::Hertz; 5use crate::time::Hertz;
8 6
@@ -32,9 +30,10 @@ pub struct Config {
32 // low speed LSI/LSE/RTC 30 // low speed LSI/LSE/RTC
33 pub ls: super::LsConfig, 31 pub ls: super::LsConfig,
34 32
35 pub adc_clock_source: AdcClockSource,
36
37 pub voltage_scale: VoltageScale, 33 pub voltage_scale: VoltageScale,
34
35 /// Per-peripheral kernel clock selection muxes
36 pub mux: super::mux::ClockMux,
38} 37}
39 38
40impl Default for Config { 39impl Default for Config {
@@ -49,8 +48,8 @@ impl Default for Config {
49 apb2_pre: APBPrescaler::DIV1, 48 apb2_pre: APBPrescaler::DIV1,
50 apb7_pre: APBPrescaler::DIV1, 49 apb7_pre: APBPrescaler::DIV1,
51 ls: Default::default(), 50 ls: Default::default(),
52 adc_clock_source: AdcClockSource::HCLK4,
53 voltage_scale: VoltageScale::RANGE2, 51 voltage_scale: VoltageScale::RANGE2,
52 mux: Default::default(),
54 } 53 }
55 } 54 }
56} 55}
@@ -152,7 +151,7 @@ pub(crate) unsafe fn init(config: Config) {
152 w.set_ppre2(config.apb2_pre); 151 w.set_ppre2(config.apb2_pre);
153 }); 152 });
154 153
155 RCC.ccipr3().modify(|w| w.set_adcsel(config.adc_clock_source)); 154 config.mux.init();
156 155
157 set_clocks!( 156 set_clocks!(
158 sys: Some(sys_clk), 157 sys: Some(sys_clk),
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs
index 190fb274f..373697ec8 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb_otg/usb.rs
@@ -606,13 +606,6 @@ impl<'d, T: Instance> Bus<'d, T> {
606 // Wait for USB power to stabilize 606 // Wait for USB power to stabilize
607 while !crate::pac::PWR.cr3().read().usb33rdy() {} 607 while !crate::pac::PWR.cr3().read().usb33rdy() {}
608 608
609 // Use internal 48MHz HSI clock. Should be enabled in RCC by default.
610 critical_section::with(|_| {
611 crate::pac::RCC
612 .d2ccip2r()
613 .modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSI48))
614 });
615
616 // Enable ULPI clock if external PHY is used 609 // Enable ULPI clock if external PHY is used
617 let ulpien = !self.phy_type.internal(); 610 let ulpien = !self.phy_type.internal();
618 critical_section::with(|_| { 611 critical_section::with(|_| {
@@ -645,13 +638,6 @@ impl<'d, T: Instance> Bus<'d, T> {
645 638
646 // Wait for USB power to stabilize 639 // Wait for USB power to stabilize
647 while !crate::pac::PWR.svmsr().read().vddusbrdy() {} 640 while !crate::pac::PWR.svmsr().read().vddusbrdy() {}
648
649 // Select HSI48 as USB clock source.
650 critical_section::with(|_| {
651 crate::pac::RCC.ccipr1().modify(|w| {
652 w.set_iclksel(crate::pac::rcc::vals::Iclksel::HSI48);
653 })
654 });
655 } 641 }
656 642
657 <T as RccPeripheral>::enable_and_reset(); 643 <T as RccPeripheral>::enable_and_reset();
diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs
index 7c6d6cd71..e6d1a6c02 100644
--- a/examples/stm32f334/src/bin/pwm.rs
+++ b/examples/stm32f334/src/bin/pwm.rs
@@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) {
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 30
31 config.rcc.mux.hrtim1sw = Some(embassy_stm32::rcc::mux::Timsw::PLL1_P); 31 config.rcc.mux.hrtim1sw = embassy_stm32::rcc::mux::Timsw::PLL1_P;
32 } 32 }
33 let p = embassy_stm32::init(config); 33 let p = embassy_stm32::init(config);
34 34
diff --git a/examples/stm32g0/src/bin/hf_timer.rs b/examples/stm32g0/src/bin/hf_timer.rs
index 3f63d0dfd..647ff0419 100644
--- a/examples/stm32g0/src/bin/hf_timer.rs
+++ b/examples/stm32g0/src/bin/hf_timer.rs
@@ -4,37 +4,35 @@
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::gpio::OutputType; 6use embassy_stm32::gpio::OutputType;
7use embassy_stm32::pac::rcc::vals::Tim1sel;
8use embassy_stm32::rcc::{Config as RccConfig, PllConfig, PllSource, Pllm, Plln, Pllq, Pllr, Sysclk};
9use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
10use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; 8use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
11use embassy_stm32::timer::simple_pwm::PwmPin; 9use embassy_stm32::timer::simple_pwm::PwmPin;
12use embassy_stm32::timer::Channel; 10use embassy_stm32::timer::Channel;
13use embassy_stm32::{pac, Config as PeripheralConfig}; 11use embassy_stm32::Config as PeripheralConfig;
14use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
15 13
16#[embassy_executor::main] 14#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 15async fn main(_spawner: Spawner) {
18 let mut rcc_config = RccConfig::default(); 16 let mut config = PeripheralConfig::default();
19 rcc_config.sys = Sysclk::PLL(PllConfig { 17 {
20 source: PllSource::HSI, 18 use embassy_stm32::rcc::*;
21 m: Pllm::DIV1, 19
22 n: Plln::MUL16, 20 config.rcc.sys = Sysclk::PLL(PllConfig {
23 r: Pllr::DIV4, // CPU clock comes from PLLR (HSI (16MHz) / 1 * 16 / 4 = 64MHz) 21 source: PllSource::HSI,
24 q: Some(Pllq::DIV2), // TIM1 or TIM15 can be sourced from PLLQ (HSI (16MHz) / 1 * 16 / 2 = 128MHz) 22 m: Pllm::DIV1,
25 p: None, 23 n: Plln::MUL16,
26 }); 24 r: Pllr::DIV4, // CPU clock comes from PLLR (HSI (16MHz) / 1 * 16 / 4 = 64MHz)
27 25 q: Some(Pllq::DIV2), // TIM1 or TIM15 can be sourced from PLLQ (HSI (16MHz) / 1 * 16 / 2 = 128MHz)
28 let mut peripheral_config = PeripheralConfig::default(); 26 p: None,
29 peripheral_config.rcc = rcc_config; 27 });
30 28
31 let p = embassy_stm32::init(peripheral_config); 29 // configure TIM1 mux to select PLLQ as clock source
32 30 // https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
33 // configure TIM1 mux to select PLLQ as clock source 31 // RM0444 page 210
34 // https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf 32 // RCC - Peripherals Independent Clock Control Register - bit 22 -> 1
35 // RM0444 page 210 33 config.rcc.mux.tim1sel = embassy_stm32::rcc::mux::Tim1sel::PLL1_Q;
36 // RCC - Peripherals Independent Clock Control Register - bit 22 -> 1 34 }
37 pac::RCC.ccipr().modify(|w| w.set_tim1sel(Tim1sel::PLL1_Q)); 35 let p = embassy_stm32::init(config);
38 36
39 let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull); 37 let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull);
40 let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); 38 let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull);
diff --git a/examples/stm32g0/src/bin/usb_serial.rs b/examples/stm32g0/src/bin/usb_serial.rs
index f5aaa5624..8b9915626 100644
--- a/examples/stm32g0/src/bin/usb_serial.rs
+++ b/examples/stm32g0/src/bin/usb_serial.rs
@@ -4,7 +4,6 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_stm32::rcc::{Hsi48Config, UsbSrc};
8use embassy_stm32::usb::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
@@ -19,10 +18,11 @@ bind_interrupts!(struct Irqs {
19#[embassy_executor::main] 18#[embassy_executor::main]
20async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
21 let mut config = Config::default(); 20 let mut config = Config::default();
22 config.rcc.usb_src = Some(UsbSrc::Hsi48(Hsi48Config { 21 {
23 sync_from_usb: true, 22 use embassy_stm32::rcc::*;
24 ..Default::default() 23 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
25 })); 24 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
25 }
26 let p = embassy_stm32::init(config); 26 let p = embassy_stm32::init(config);
27 27
28 info!("Hello World!"); 28 info!("Hello World!");
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 6c6de1ffe..f81335f93 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::rcc::{AdcClockSource, Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk};
8use embassy_stm32::Config; 7use embassy_stm32::Config;
9use embassy_time::{Delay, Timer}; 8use embassy_time::{Delay, Timer};
10use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -12,20 +11,20 @@ use {defmt_rtt as _, panic_probe as _};
12#[embassy_executor::main] 11#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 13 let mut config = Config::default();
15 14 {
16 config.rcc.pll = Some(Pll { 15 use embassy_stm32::rcc::*;
17 source: Pllsrc::HSI, 16 config.rcc.pll = Some(Pll {
18 prediv: PllPreDiv::DIV4, 17 source: Pllsrc::HSI,
19 mul: PllMul::MUL85, 18 prediv: PllPreDiv::DIV4,
20 divp: None, 19 mul: PllMul::MUL85,
21 divq: None, 20 divp: None,
22 // Main system clock at 170 MHz 21 divq: None,
23 divr: Some(PllRDiv::DIV2), 22 // Main system clock at 170 MHz
24 }); 23 divr: Some(PllRDiv::DIV2),
25 24 });
26 config.rcc.adc12_clock_source = AdcClockSource::SYS; 25 config.rcc.mux.adc12sel = mux::Adcsel::SYS;
27 config.rcc.sys = Sysclk::PLL1_R; 26 config.rcc.sys = Sysclk::PLL1_R;
28 27 }
29 let mut p = embassy_stm32::init(config); 28 let mut p = embassy_stm32::init(config);
30 info!("Hello World!"); 29 info!("Hello World!");
31 30
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs
index a41f765c1..7551b2a55 100644
--- a/examples/stm32g4/src/bin/can.rs
+++ b/examples/stm32g4/src/bin/can.rs
@@ -3,6 +3,7 @@
3use defmt::*; 3use defmt::*;
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_stm32::peripherals::*; 5use embassy_stm32::peripherals::*;
6use embassy_stm32::time::Hertz;
6use embassy_stm32::{bind_interrupts, can, Config}; 7use embassy_stm32::{bind_interrupts, can, Config};
7use embassy_time::Timer; 8use embassy_time::Timer;
8use static_cell::StaticCell; 9use static_cell::StaticCell;
@@ -15,8 +16,24 @@ bind_interrupts!(struct Irqs {
15 16
16#[embassy_executor::main] 17#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
18 let config = Config::default(); 19 let mut config = Config::default();
19 20 {
21 use embassy_stm32::rcc::*;
22 config.rcc.hse = Some(Hse {
23 freq: Hertz(24_000_000),
24 mode: HseMode::Oscillator,
25 });
26 config.rcc.pll = Some(Pll {
27 source: Pllsrc::HSE,
28 prediv: PllPreDiv::DIV6,
29 mul: PllMul::MUL85,
30 divp: None,
31 divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan.
32 divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz
33 });
34 config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q;
35 config.rcc.sys = Sysclk::PLL1_R;
36 }
20 let peripherals = embassy_stm32::init(config); 37 let peripherals = embassy_stm32::init(config);
21 38
22 let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); 39 let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs
index 5274de79d..2609abfa2 100644
--- a/examples/stm32g4/src/bin/pll.rs
+++ b/examples/stm32g4/src/bin/pll.rs
@@ -12,6 +12,7 @@ use {defmt_rtt as _, panic_probe as _};
12async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
13 let mut config = Config::default(); 13 let mut config = Config::default();
14 14
15 config.rcc.hsi = true;
15 config.rcc.pll = Some(Pll { 16 config.rcc.pll = Some(Pll {
16 source: Pllsrc::HSI, 17 source: Pllsrc::HSI,
17 prediv: PllPreDiv::DIV4, 18 prediv: PllPreDiv::DIV4,
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs
index 989fef5b0..90caaae14 100644
--- a/examples/stm32g4/src/bin/usb_serial.rs
+++ b/examples/stm32g4/src/bin/usb_serial.rs
@@ -3,9 +3,6 @@
3 3
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::rcc::{
7 Clk48Src, Hse, HseMode, Hsi48Config, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, Pllsrc, Sysclk,
8};
9use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
10use embassy_stm32::usb::{self, Driver, Instance}; 7use embassy_stm32::usb::{self, Driver, Instance};
11use embassy_stm32::{bind_interrupts, peripherals, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, Config};
@@ -22,38 +19,27 @@ bind_interrupts!(struct Irqs {
22#[embassy_executor::main] 19#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 20async fn main(_spawner: Spawner) {
24 let mut config = Config::default(); 21 let mut config = Config::default();
25 22 {
26 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. 23 use embassy_stm32::rcc::*;
27 const USE_HSI48: bool = true;
28
29 let plldivq = if USE_HSI48 { None } else { Some(PllQDiv::DIV6) };
30
31 config.rcc.hse = Some(Hse {
32 freq: Hertz(8_000_000),
33 mode: HseMode::Oscillator,
34 });
35
36 config.rcc.pll = Some(Pll {
37 source: Pllsrc::HSE,
38 prediv: PllPreDiv::DIV2,
39 mul: PllMul::MUL72,
40 divp: None,
41 divq: plldivq,
42 // Main system clock at 144 MHz
43 divr: Some(PllRDiv::DIV2),
44 });
45
46 config.rcc.sys = Sysclk::PLL1_R;
47 config.rcc.boost = true; // BOOST!
48
49 if USE_HSI48 {
50 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. 24 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
51 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); 25 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
52 config.rcc.clk48_src = Clk48Src::HSI48; 26 config.rcc.hse = Some(Hse {
53 } else { 27 freq: Hertz(8_000_000),
54 config.rcc.clk48_src = Clk48Src::PLL1_Q; 28 mode: HseMode::Oscillator,
29 });
30 config.rcc.pll = Some(Pll {
31 source: Pllsrc::HSE,
32 prediv: PllPreDiv::DIV2,
33 mul: PllMul::MUL72,
34 divp: None,
35 divq: Some(PllQDiv::DIV6), // 48mhz
36 divr: Some(PllRDiv::DIV2), // Main system clock at 144 MHz
37 });
38 config.rcc.sys = Sysclk::PLL1_R;
39 config.rcc.boost = true; // BOOST!
40 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
41 //config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; // uncomment to use PLL1_Q instead.
55 } 42 }
56
57 let p = embassy_stm32::init(config); 43 let p = embassy_stm32::init(config);
58 44
59 info!("Hello World!"); 45 info!("Hello World!");
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs
index e5ccfe4f7..643df27f9 100644
--- a/examples/stm32h5/src/bin/can.rs
+++ b/examples/stm32h5/src/bin/can.rs
@@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) {
20 freq: embassy_stm32::time::Hertz(25_000_000), 20 freq: embassy_stm32::time::Hertz(25_000_000),
21 mode: rcc::HseMode::Oscillator, 21 mode: rcc::HseMode::Oscillator,
22 }); 22 });
23 config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; 23 config.rcc.mux.fdcan12sel = rcc::mux::Fdcansel::HSE;
24 24
25 let peripherals = embassy_stm32::init(config); 25 let peripherals = embassy_stm32::init(config);
26 26
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs
index 208493d8c..83477c8fa 100644
--- a/examples/stm32h5/src/bin/usb_serial.rs
+++ b/examples/stm32h5/src/bin/usb_serial.rs
@@ -5,7 +5,7 @@ use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
7use embassy_stm32::usb::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -41,15 +41,12 @@ async fn main(_spawner: Spawner) {
41 config.rcc.apb3_pre = APBPrescaler::DIV4; 41 config.rcc.apb3_pre = APBPrescaler::DIV4;
42 config.rcc.sys = Sysclk::PLL1_P; 42 config.rcc.sys = Sysclk::PLL1_P;
43 config.rcc.voltage_scale = VoltageScale::Scale0; 43 config.rcc.voltage_scale = VoltageScale::Scale0;
44 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
44 } 45 }
45 let p = embassy_stm32::init(config); 46 let p = embassy_stm32::init(config);
46 47
47 info!("Hello World!"); 48 info!("Hello World!");
48 49
49 pac::RCC.ccipr4().write(|w| {
50 w.set_usbsel(pac::rcc::vals::Usbsel::HSI48);
51 });
52
53 // Create the driver, from the HAL. 50 // Create the driver, from the HAL.
54 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); 51 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
55 52
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index f0278239f..a5594d10c 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) {
38 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 38 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
39 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 39 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
40 config.rcc.voltage_scale = VoltageScale::Scale1; 40 config.rcc.voltage_scale = VoltageScale::Scale1;
41 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 41 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
42 } 42 }
43 let mut p = embassy_stm32::init(config); 43 let mut p = embassy_stm32::init(config);
44 44
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs
index e5ccfe4f7..13a6a5051 100644
--- a/examples/stm32h7/src/bin/can.rs
+++ b/examples/stm32h7/src/bin/can.rs
@@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) {
20 freq: embassy_stm32::time::Hertz(25_000_000), 20 freq: embassy_stm32::time::Hertz(25_000_000),
21 mode: rcc::HseMode::Oscillator, 21 mode: rcc::HseMode::Oscillator,
22 }); 22 });
23 config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; 23 config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
24 24
25 let peripherals = embassy_stm32::init(config); 25 let peripherals = embassy_stm32::init(config);
26 26
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index a9bf46de0..a6f969aba 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -40,7 +40,7 @@ fn main() -> ! {
40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
42 config.rcc.voltage_scale = VoltageScale::Scale1; 42 config.rcc.voltage_scale = VoltageScale::Scale1;
43 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 43 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
44 } 44 }
45 let p = embassy_stm32::init(config); 45 let p = embassy_stm32::init(config);
46 46
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index d88bd838f..feec28993 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -42,7 +42,7 @@ async fn main(spawner: Spawner) {
42 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 42 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
43 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 43 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
44 config.rcc.voltage_scale = VoltageScale::Scale1; 44 config.rcc.voltage_scale = VoltageScale::Scale1;
45 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 45 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
46 } 46 }
47 47
48 // Initialize the board and obtain a Peripherals instance 48 // Initialize the board and obtain a Peripherals instance
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index 910944673..a9f4604aa 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::adc::{Adc, Resolution}; 5use embassy_stm32::adc::{Adc, Resolution};
6use embassy_stm32::pac; 6use embassy_stm32::Config;
7use embassy_time::Delay; 7use embassy_time::Delay;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -11,12 +11,12 @@ use {defmt_rtt as _, panic_probe as _};
11fn main() -> ! { 11fn main() -> ! {
12 info!("Hello World!"); 12 info!("Hello World!");
13 13
14 pac::RCC.ccipr().modify(|w| { 14 let mut config = Config::default();
15 w.set_adcsel(pac::rcc::vals::Adcsel::SYS); 15 {
16 }); 16 use embassy_stm32::rcc::*;
17 pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); 17 config.rcc.mux.adcsel = mux::Adcsel::SYS;
18 18 }
19 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(config);
20 20
21 let mut adc = Adc::new(p.ADC1, &mut Delay); 21 let mut adc = Adc::new(p.ADC1, &mut Delay);
22 //adc.enable_vref(); 22 //adc.enable_vref();
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index f21aa797c..dd78d7fb3 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -33,7 +33,7 @@ fn options() -> TestOptions {
33 freq: embassy_stm32::time::Hertz(25_000_000), 33 freq: embassy_stm32::time::Hertz(25_000_000),
34 mode: rcc::HseMode::Oscillator, 34 mode: rcc::HseMode::Oscillator,
35 }); 35 });
36 c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; 36 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
37 TestOptions { 37 TestOptions {
38 config: c, 38 config: c,
39 max_latency: Duration::from_micros(1200), 39 max_latency: Duration::from_micros(1200),
@@ -50,7 +50,7 @@ fn options() -> TestOptions {
50 freq: embassy_stm32::time::Hertz(25_000_000), 50 freq: embassy_stm32::time::Hertz(25_000_000),
51 mode: rcc::HseMode::Oscillator, 51 mode: rcc::HseMode::Oscillator,
52 }); 52 });
53 c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; 53 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
54 TestOptions { 54 TestOptions {
55 config: c, 55 config: c,
56 max_latency: Duration::from_micros(1200), 56 max_latency: Duration::from_micros(1200),
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 7b9585afd..cf3e04a4b 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -2,6 +2,8 @@
2 2
3pub use defmt::*; 3pub use defmt::*;
4#[allow(unused)] 4#[allow(unused)]
5use embassy_stm32::rcc::*;
6#[allow(unused)]
5use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
6use embassy_stm32::Config; 8use embassy_stm32::Config;
7use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -265,7 +267,6 @@ pub fn config() -> Config {
265 267
266 #[cfg(feature = "stm32f091rc")] 268 #[cfg(feature = "stm32f091rc")]
267 { 269 {
268 use embassy_stm32::rcc::*;
269 config.rcc.hse = Some(Hse { 270 config.rcc.hse = Some(Hse {
270 freq: Hertz(8_000_000), 271 freq: Hertz(8_000_000),
271 mode: HseMode::Bypass, 272 mode: HseMode::Bypass,
@@ -281,7 +282,6 @@ pub fn config() -> Config {
281 } 282 }
282 #[cfg(feature = "stm32f103c8")] 283 #[cfg(feature = "stm32f103c8")]
283 { 284 {
284 use embassy_stm32::rcc::*;
285 config.rcc.hse = Some(Hse { 285 config.rcc.hse = Some(Hse {
286 freq: Hertz(8_000_000), 286 freq: Hertz(8_000_000),
287 mode: HseMode::Oscillator, 287 mode: HseMode::Oscillator,
@@ -298,7 +298,6 @@ pub fn config() -> Config {
298 } 298 }
299 #[cfg(feature = "stm32f207zg")] 299 #[cfg(feature = "stm32f207zg")]
300 { 300 {
301 use embassy_stm32::rcc::*;
302 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) 301 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal)
303 config.rcc.hse = Some(Hse { 302 config.rcc.hse = Some(Hse {
304 freq: Hertz(8_000_000), 303 freq: Hertz(8_000_000),
@@ -327,7 +326,6 @@ pub fn config() -> Config {
327 326
328 #[cfg(feature = "stm32f303ze")] 327 #[cfg(feature = "stm32f303ze")]
329 { 328 {
330 use embassy_stm32::rcc::*;
331 config.rcc.hse = Some(Hse { 329 config.rcc.hse = Some(Hse {
332 freq: Hertz(8_000_000), 330 freq: Hertz(8_000_000),
333 mode: HseMode::Bypass, 331 mode: HseMode::Bypass,
@@ -345,7 +343,6 @@ pub fn config() -> Config {
345 343
346 #[cfg(feature = "stm32f429zi")] 344 #[cfg(feature = "stm32f429zi")]
347 { 345 {
348 use embassy_stm32::rcc::*;
349 config.rcc.hse = Some(Hse { 346 config.rcc.hse = Some(Hse {
350 freq: Hertz(8_000_000), 347 freq: Hertz(8_000_000),
351 mode: HseMode::Bypass, 348 mode: HseMode::Bypass,
@@ -366,7 +363,6 @@ pub fn config() -> Config {
366 363
367 #[cfg(feature = "stm32f446re")] 364 #[cfg(feature = "stm32f446re")]
368 { 365 {
369 use embassy_stm32::rcc::*;
370 config.rcc.hse = Some(Hse { 366 config.rcc.hse = Some(Hse {
371 freq: Hertz(8_000_000), 367 freq: Hertz(8_000_000),
372 mode: HseMode::Oscillator, 368 mode: HseMode::Oscillator,
@@ -387,7 +383,6 @@ pub fn config() -> Config {
387 383
388 #[cfg(feature = "stm32f767zi")] 384 #[cfg(feature = "stm32f767zi")]
389 { 385 {
390 use embassy_stm32::rcc::*;
391 config.rcc.hse = Some(Hse { 386 config.rcc.hse = Some(Hse {
392 freq: Hertz(8_000_000), 387 freq: Hertz(8_000_000),
393 mode: HseMode::Bypass, 388 mode: HseMode::Bypass,
@@ -408,7 +403,6 @@ pub fn config() -> Config {
408 403
409 #[cfg(feature = "stm32h563zi")] 404 #[cfg(feature = "stm32h563zi")]
410 { 405 {
411 use embassy_stm32::rcc::*;
412 config.rcc.hsi = None; 406 config.rcc.hsi = None;
413 config.rcc.hsi48 = Some(Default::default()); // needed for RNG 407 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
414 config.rcc.hse = Some(Hse { 408 config.rcc.hse = Some(Hse {
@@ -433,7 +427,6 @@ pub fn config() -> Config {
433 427
434 #[cfg(feature = "stm32h503rb")] 428 #[cfg(feature = "stm32h503rb")]
435 { 429 {
436 use embassy_stm32::rcc::*;
437 config.rcc.hsi = None; 430 config.rcc.hsi = None;
438 config.rcc.hsi48 = Some(Default::default()); // needed for RNG 431 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
439 config.rcc.hse = Some(Hse { 432 config.rcc.hse = Some(Hse {
@@ -456,9 +449,26 @@ pub fn config() -> Config {
456 config.rcc.voltage_scale = VoltageScale::Scale0; 449 config.rcc.voltage_scale = VoltageScale::Scale0;
457 } 450 }
458 451
452 #[cfg(feature = "stm32g491re")]
453 {
454 config.rcc.hse = Some(Hse {
455 freq: Hertz(24_000_000),
456 mode: HseMode::Oscillator,
457 });
458 config.rcc.pll = Some(Pll {
459 source: Pllsrc::HSE,
460 prediv: PllPreDiv::DIV6,
461 mul: PllMul::MUL85,
462 divp: None,
463 divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan.
464 divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz
465 });
466 config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q;
467 config.rcc.sys = Sysclk::PLL1_R;
468 }
469
459 #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] 470 #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))]
460 { 471 {
461 use embassy_stm32::rcc::*;
462 config.rcc.hsi = Some(HSIPrescaler::DIV1); 472 config.rcc.hsi = Some(HSIPrescaler::DIV1);
463 config.rcc.csi = true; 473 config.rcc.csi = true;
464 config.rcc.hsi48 = Some(Default::default()); // needed for RNG 474 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
@@ -485,7 +495,7 @@ pub fn config() -> Config {
485 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 495 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
486 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 496 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
487 config.rcc.voltage_scale = VoltageScale::Scale1; 497 config.rcc.voltage_scale = VoltageScale::Scale1;
488 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 498 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
489 #[cfg(any(feature = "stm32h755zi"))] 499 #[cfg(any(feature = "stm32h755zi"))]
490 { 500 {
491 config.rcc.supply_config = SupplyConfig::DirectSMPS; 501 config.rcc.supply_config = SupplyConfig::DirectSMPS;
@@ -494,7 +504,6 @@ pub fn config() -> Config {
494 504
495 #[cfg(any(feature = "stm32h7a3zi"))] 505 #[cfg(any(feature = "stm32h7a3zi"))]
496 { 506 {
497 use embassy_stm32::rcc::*;
498 config.rcc.hsi = Some(HSIPrescaler::DIV1); 507 config.rcc.hsi = Some(HSIPrescaler::DIV1);
499 config.rcc.csi = true; 508 config.rcc.csi = true;
500 config.rcc.hsi48 = Some(Default::default()); // needed for RNG 509 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
@@ -521,12 +530,11 @@ pub fn config() -> Config {
521 config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz 530 config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz
522 config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz 531 config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz
523 config.rcc.voltage_scale = VoltageScale::Scale0; 532 config.rcc.voltage_scale = VoltageScale::Scale0;
524 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 533 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
525 } 534 }
526 535
527 #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] 536 #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))]
528 { 537 {
529 use embassy_stm32::rcc::*;
530 config.rcc.sys = Sysclk::PLL1_R; 538 config.rcc.sys = Sysclk::PLL1_R;
531 config.rcc.hsi = true; 539 config.rcc.hsi = true;
532 config.rcc.pll = Some(Pll { 540 config.rcc.pll = Some(Pll {
@@ -541,7 +549,6 @@ pub fn config() -> Config {
541 549
542 #[cfg(feature = "stm32wl55jc")] 550 #[cfg(feature = "stm32wl55jc")]
543 { 551 {
544 use embassy_stm32::rcc::*;
545 config.rcc.hse = Some(Hse { 552 config.rcc.hse = Some(Hse {
546 freq: Hertz(32_000_000), 553 freq: Hertz(32_000_000),
547 mode: HseMode::Bypass, 554 mode: HseMode::Bypass,
@@ -560,7 +567,6 @@ pub fn config() -> Config {
560 567
561 #[cfg(any(feature = "stm32l552ze"))] 568 #[cfg(any(feature = "stm32l552ze"))]
562 { 569 {
563 use embassy_stm32::rcc::*;
564 config.rcc.hsi = true; 570 config.rcc.hsi = true;
565 config.rcc.sys = Sysclk::PLL1_R; 571 config.rcc.sys = Sysclk::PLL1_R;
566 config.rcc.pll = Some(Pll { 572 config.rcc.pll = Some(Pll {
@@ -576,7 +582,6 @@ pub fn config() -> Config {
576 582
577 #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] 583 #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))]
578 { 584 {
579 use embassy_stm32::rcc::*;
580 config.rcc.hsi = true; 585 config.rcc.hsi = true;
581 config.rcc.pll1 = Some(Pll { 586 config.rcc.pll1 = Some(Pll {
582 source: PllSource::HSI, // 16 MHz 587 source: PllSource::HSI, // 16 MHz
@@ -593,17 +598,12 @@ pub fn config() -> Config {
593 598
594 #[cfg(feature = "stm32wba52cg")] 599 #[cfg(feature = "stm32wba52cg")]
595 { 600 {
596 use embassy_stm32::rcc::*;
597 config.rcc.sys = Sysclk::HSI; 601 config.rcc.sys = Sysclk::HSI;
598 602 config.rcc.mux.rngsel = mux::Rngsel::HSI;
599 embassy_stm32::pac::RCC.ccipr2().write(|w| {
600 w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI);
601 });
602 } 603 }
603 604
604 #[cfg(feature = "stm32l073rz")] 605 #[cfg(feature = "stm32l073rz")]
605 { 606 {
606 use embassy_stm32::rcc::*;
607 config.rcc.hsi = true; 607 config.rcc.hsi = true;
608 config.rcc.pll = Some(Pll { 608 config.rcc.pll = Some(Pll {
609 source: PllSource::HSI, 609 source: PllSource::HSI,
@@ -615,7 +615,6 @@ pub fn config() -> Config {
615 615
616 #[cfg(any(feature = "stm32l152re"))] 616 #[cfg(any(feature = "stm32l152re"))]
617 { 617 {
618 use embassy_stm32::rcc::*;
619 config.rcc.hsi = true; 618 config.rcc.hsi = true;
620 config.rcc.pll = Some(Pll { 619 config.rcc.pll = Some(Pll {
621 source: PllSource::HSI, 620 source: PllSource::HSI,