diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-26 03:28:27 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-03-01 23:54:37 +0100 |
| commit | 95234cddbac6f21fce0f5df510d49816f343b87d (patch) | |
| tree | a9daf8a1bb9449191a7174269bc348f3ce61bfef | |
| parent | d5c9c611fa317e066d6cf7c5af0513b40bd69d8c (diff) | |
stm32: autogenerate mux config for all chips.
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" | |||
| 70 | sdio-host = "0.5.0" | 70 | sdio-host = "0.5.0" |
| 71 | critical-section = "1.1" | 71 | critical-section = "1.1" |
| 72 | #stm32-metapac = { version = "15" } | 72 | #stm32-metapac = { version = "15" } |
| 73 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7462d805ef05892531a83cd9ad60c9cba568d54" } | 73 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e853cf944b150898312984d092d63926970c340d" } |
| 74 | vcell = "0.1.3" | 74 | vcell = "0.1.3" |
| 75 | bxcan = "0.7.0" | 75 | bxcan = "0.7.0" |
| 76 | nb = "1.0.0" | 76 | nb = "1.0.0" |
| @@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 94 | proc-macro2 = "1.0.36" | 94 | proc-macro2 = "1.0.36" |
| 95 | quote = "1.0.15" | 95 | quote = "1.0.15" |
| 96 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 96 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 97 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7462d805ef05892531a83cd9ad60c9cba568d54", default-features = false, features = ["metadata"]} | 97 | stm32-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 | ||
| 6 | use proc_macro2::{Ident, TokenStream}; | 6 | use proc_macro2::{Ident, TokenStream}; |
| 7 | use quote::{format_ident, quote}; | 7 | use quote::{format_ident, quote}; |
| 8 | use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccKernelClock, StopMode, METADATA}; | 8 | use stm32_metapac::metadata::{ |
| 9 | MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA, | ||
| 10 | }; | ||
| 9 | 11 | ||
| 10 | fn main() { | 12 | fn 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; | |||
| 7 | use self::sealed::Instance; | 7 | use self::sealed::Instance; |
| 8 | use crate::interrupt; | 8 | use crate::interrupt; |
| 9 | use crate::interrupt::typelevel::Interrupt; | 9 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel}; | ||
| 11 | use crate::peripherals::IPCC; | 10 | use crate::peripherals::IPCC; |
| 12 | use crate::rcc::sealed::RccPeripheral; | 11 | use 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 | |||
| 275 | fn _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 | ||
| 26 | impl Default for Config { | 29 | impl 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))] | ||
| 76 | pub 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 |
| 91 | pub struct Config { | 75 | pub 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 | ||
| 101 | impl Default for Config { | 87 | impl 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 @@ | |||
| 1 | use stm32_metapac::flash::vals::Latency; | 1 | use stm32_metapac::flash::vals::Latency; |
| 2 | use stm32_metapac::rcc::vals::{Adcsel, Sw}; | 2 | use stm32_metapac::rcc::vals::Sw; |
| 3 | use stm32_metapac::FLASH; | 3 | use stm32_metapac::FLASH; |
| 4 | 4 | ||
| 5 | pub use crate::pac::rcc::vals::{ | 5 | pub 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 | }; |
| 10 | use crate::pac::{PWR, RCC}; | 9 | use crate::pac::{PWR, RCC}; |
| 11 | use crate::time::Hertz; | 10 | use 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 | ||
| 105 | impl Default for Config { | 95 | impl 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 | ||
| 3 | use crate::pac; | 3 | use crate::pac; |
| 4 | use crate::pac::pwr::vals::Vos; | 4 | use crate::pac::pwr::vals::Vos; |
| 5 | #[cfg(stm32h5)] | ||
| 6 | pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource; | ||
| 7 | #[cfg(stm32h7)] | ||
| 8 | pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; | ||
| 9 | pub use crate::pac::rcc::vals::{ | 5 | pub 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 | }; |
| 13 | use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre}; | 8 | use crate::pac::rcc::vals::{Pllrge, Pllvcosel, Timpre}; |
| 14 | use crate::pac::{FLASH, PWR, RCC}; | 9 | use crate::pac::{FLASH, PWR, RCC}; |
| 15 | use crate::time::Hertz; | 10 | use 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 | ||
| 209 | impl Default for Config { | 203 | impl 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))] |
| 2 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 2 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 3 | use crate::pac::rcc::regs::Cfgr; | 3 | use crate::pac::rcc::regs::Cfgr; |
| 4 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | ||
| 5 | pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; | ||
| 6 | #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] | ||
| 7 | pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; | ||
| 8 | #[cfg(any(stm32wb, stm32wl))] | 4 | #[cfg(any(stm32wb, stm32wl))] |
| 9 | pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; | 5 | pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; |
| 10 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as Sysclk}; | 6 | pub 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 | ||
| 76 | impl Default for Config { | 68 | impl 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 | ||
| 143 | fn msi_enable(range: MSIRange) { | 132 | fn 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 | ||
| 32 | pub use _version::*; | 32 | pub use _version::*; |
| 33 | 33 | ||
| 34 | #[cfg(clock_mux)] | 34 | pub use crate::_generated::{mux, Clocks}; |
| 35 | pub use crate::_generated::mux; | ||
| 36 | pub 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 | ||
| 90 | impl Default for Config { | 93 | impl 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 @@ | |||
| 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 2 | use crate::pac::rcc::regs::Cfgr1; | 2 | use crate::pac::rcc::regs::Cfgr1; |
| 3 | pub use crate::pac::rcc::vals::{ | 3 | pub 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 | }; | ||
| 6 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 7 | use crate::time::Hertz; | 5 | use 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 | ||
| 40 | impl Default for Config { | 39 | impl 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 @@ | |||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::OutputType; | 6 | use embassy_stm32::gpio::OutputType; |
| 7 | use embassy_stm32::pac::rcc::vals::Tim1sel; | ||
| 8 | use embassy_stm32::rcc::{Config as RccConfig, PllConfig, PllSource, Pllm, Plln, Pllq, Pllr, Sysclk}; | ||
| 9 | use embassy_stm32::time::khz; | 7 | use embassy_stm32::time::khz; |
| 10 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | 8 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; |
| 11 | use embassy_stm32::timer::simple_pwm::PwmPin; | 9 | use embassy_stm32::timer::simple_pwm::PwmPin; |
| 12 | use embassy_stm32::timer::Channel; | 10 | use embassy_stm32::timer::Channel; |
| 13 | use embassy_stm32::{pac, Config as PeripheralConfig}; | 11 | use embassy_stm32::Config as PeripheralConfig; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 15 | 13 | ||
| 16 | #[embassy_executor::main] | 14 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 15 | async 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 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_stm32::rcc::{Hsi48Config, UsbSrc}; | ||
| 8 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| @@ -19,10 +18,11 @@ bind_interrupts!(struct Irqs { | |||
| 19 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 19 | async 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 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::rcc::{AdcClockSource, Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk}; | ||
| 8 | use embassy_stm32::Config; | 7 | use embassy_stm32::Config; |
| 9 | use embassy_time::{Delay, Timer}; | 8 | use embassy_time::{Delay, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {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] |
| 13 | async fn main(_spawner: Spawner) { | 12 | async 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 @@ | |||
| 3 | use defmt::*; | 3 | use defmt::*; |
| 4 | use embassy_executor::Spawner; | 4 | use embassy_executor::Spawner; |
| 5 | use embassy_stm32::peripherals::*; | 5 | use embassy_stm32::peripherals::*; |
| 6 | use embassy_stm32::time::Hertz; | ||
| 6 | use embassy_stm32::{bind_interrupts, can, Config}; | 7 | use embassy_stm32::{bind_interrupts, can, Config}; |
| 7 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 8 | use static_cell::StaticCell; | 9 | use static_cell::StaticCell; |
| @@ -15,8 +16,24 @@ bind_interrupts!(struct Irqs { | |||
| 15 | 16 | ||
| 16 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 18 | async 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 _}; | |||
| 12 | async fn main(_spawner: Spawner) { | 12 | async 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 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::rcc::{ | ||
| 7 | Clk48Src, Hse, HseMode, Hsi48Config, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, Pllsrc, Sysclk, | ||
| 8 | }; | ||
| 9 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 10 | use embassy_stm32::usb::{self, Driver, Instance}; | 7 | use embassy_stm32::usb::{self, Driver, Instance}; |
| 11 | use embassy_stm32::{bind_interrupts, peripherals, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, Config}; |
| @@ -22,38 +19,27 @@ bind_interrupts!(struct Irqs { | |||
| 22 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 23 | async fn main(_spawner: Spawner) { | 20 | async 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, *}; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 11 | use 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 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_stm32::adc::{Adc, Resolution}; | 5 | use embassy_stm32::adc::{Adc, Resolution}; |
| 6 | use embassy_stm32::pac; | 6 | use embassy_stm32::Config; |
| 7 | use embassy_time::Delay; | 7 | use embassy_time::Delay; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -11,12 +11,12 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 11 | fn main() -> ! { | 11 | fn 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 | ||
| 3 | pub use defmt::*; | 3 | pub use defmt::*; |
| 4 | #[allow(unused)] | 4 | #[allow(unused)] |
| 5 | use embassy_stm32::rcc::*; | ||
| 6 | #[allow(unused)] | ||
| 5 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 6 | use embassy_stm32::Config; | 8 | use embassy_stm32::Config; |
| 7 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {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, |
