aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorKevin <[email protected]>2024-09-15 20:09:42 +0200
committerKevin <[email protected]>2024-09-22 00:23:07 +0200
commit6d9af8304cf88dbfa3713acfef4d89ba3a95c2d8 (patch)
tree92aa105670259bfd9aa9b60209c62eb2f3cdaa23 /embassy-stm32/src
parent2f60d78ea318f51ff59868c348b77cf880012198 (diff)
Add USBPHYC clock configuration for H7RS series
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/rcc/h.rs32
-rw-r--r--embassy-stm32/src/usb/mod.rs10
-rw-r--r--embassy-stm32/src/usb/otg.rs2
3 files changed, 42 insertions, 2 deletions
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 27fc2b8d7..cd1c10407 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -35,7 +35,10 @@ pub enum VoltageScale {
35 Scale3, 35 Scale3,
36} 36}
37#[cfg(any(stm32h7rs))] 37#[cfg(any(stm32h7rs))]
38pub use crate::pac::pwr::vals::Vos as VoltageScale; 38pub use crate::pac::{
39 pwr::vals::Vos as VoltageScale,
40 rcc::vals::{Usbphycsel, Usbrefcksel},
41};
39 42
40#[derive(Clone, Copy, Eq, PartialEq)] 43#[derive(Clone, Copy, Eq, PartialEq)]
41pub enum HseMode { 44pub enum HseMode {
@@ -557,6 +560,27 @@ pub(crate) unsafe fn init(config: Config) {
557 560
558 let rtc = config.ls.init(); 561 let rtc = config.ls.init();
559 562
563 #[cfg(stm32h7rs)]
564 let usb_refck = match config.mux.usbphycsel {
565 Usbphycsel::HSE => hse,
566 Usbphycsel::HSE_DIV_2 => hse.map(|hse_val| hse_val / 2u8),
567 Usbphycsel::PLL3_Q => pll3.q,
568 _ => None,
569 };
570 #[cfg(stm32h7rs)]
571 let usb_refck_sel = match usb_refck {
572 Some(clk_val) => match clk_val {
573 Hertz(16_000_000) => Usbrefcksel::MHZ16,
574 Hertz(19_200_000) => Usbrefcksel::MHZ19_2,
575 Hertz(20_000_000) => Usbrefcksel::MHZ20,
576 Hertz(24_000_000) => Usbrefcksel::MHZ24,
577 Hertz(26_000_000) => Usbrefcksel::MHZ26,
578 Hertz(32_000_000) => Usbrefcksel::MHZ32,
579 _ => panic!("cannot select USBPHYC reference clock with source frequency of {} Hz, must be one of 16, 19.2, 20, 24, 26, 32 MHz", clk_val),
580 },
581 None => Usbrefcksel::MHZ24,
582 };
583
560 #[cfg(stm32h7)] 584 #[cfg(stm32h7)]
561 { 585 {
562 RCC.d1cfgr().modify(|w| { 586 RCC.d1cfgr().modify(|w| {
@@ -593,6 +617,10 @@ pub(crate) unsafe fn init(config: Config) {
593 w.set_ppre4(config.apb4_pre); 617 w.set_ppre4(config.apb4_pre);
594 w.set_ppre5(config.apb5_pre); 618 w.set_ppre5(config.apb5_pre);
595 }); 619 });
620
621 RCC.ahbperckselr().modify(|w| {
622 w.set_usbrefcksel(usb_refck_sel);
623 });
596 } 624 }
597 #[cfg(stm32h5)] 625 #[cfg(stm32h5)]
598 { 626 {
@@ -698,6 +726,8 @@ pub(crate) unsafe fn init(config: Config) {
698 #[cfg(stm32h7rs)] 726 #[cfg(stm32h7rs)]
699 clk48mohci: None, // TODO 727 clk48mohci: None, // TODO
700 #[cfg(stm32h7rs)] 728 #[cfg(stm32h7rs)]
729 hse_div_2: hse.map(|clk| clk / 2u32),
730 #[cfg(stm32h7rs)]
701 usb: Some(Hertz(48_000_000)), 731 usb: Some(Hertz(48_000_000)),
702 ); 732 );
703} 733}
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs
index 7d8c79618..a473285bf 100644
--- a/embassy-stm32/src/usb/mod.rs
+++ b/embassy-stm32/src/usb/mod.rs
@@ -13,9 +13,19 @@ fn common_init<T: Instance>() {
13 // Check the USB clock is enabled and running at exactly 48 MHz. 13 // Check the USB clock is enabled and running at exactly 48 MHz.
14 // frequency() will panic if not enabled 14 // frequency() will panic if not enabled
15 let freq = T::frequency(); 15 let freq = T::frequency();
16
17 // On the H7RS, the USBPHYC embeds a PLL accepting one of the input frequencies listed below and providing 48MHz to OTG_FS and 60MHz to OTG_HS internally
18 #[cfg(stm32h7rs)]
19 if ![16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000].contains(&freq.0) {
20 panic!(
21 "USB clock should be one of 16, 19.2, 20, 24, 26, 32Mhz but is {} Hz. Please double-check your RCC settings.",
22 freq.0
23 )
24 }
16 // Check frequency is within the 0.25% tolerance allowed by the spec. 25 // Check frequency is within the 0.25% tolerance allowed by the spec.
17 // Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user 26 // Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user
18 // has tight clock restrictions due to something else (like audio). 27 // has tight clock restrictions due to something else (like audio).
28 #[cfg(not(stm32h7rs))]
19 if freq.0.abs_diff(48_000_000) > 120_000 { 29 if freq.0.abs_diff(48_000_000) > 120_000 {
20 panic!( 30 panic!(
21 "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.", 31 "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index 59b5401cc..00cafe6e4 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -554,7 +554,7 @@ fn calculate_trdt<T: Instance>(speed: Dspd) -> u8 {
554 match speed { 554 match speed {
555 Dspd::HIGH_SPEED => { 555 Dspd::HIGH_SPEED => {
556 // From RM0431 (F72xx), RM0090 (F429), RM0390 (F446) 556 // From RM0431 (F72xx), RM0090 (F429), RM0390 (F446)
557 if ahb_freq >= 30_000_000 { 557 if ahb_freq >= 30_000_000 || cfg!(stm32h7rs) {
558 0x9 558 0x9
559 } else { 559 } else {
560 panic!("AHB frequency is too low") 560 panic!("AHB frequency is too low")