diff options
| -rw-r--r-- | embassy-stm32/Cargo.toml | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/h.rs | 32 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/mod.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/otg.rs | 2 | ||||
| -rw-r--r-- | embassy-usb-synopsys-otg/src/lib.rs | 29 | ||||
| -rw-r--r-- | examples/stm32h7rs/src/bin/usb_serial.rs | 1 |
6 files changed, 63 insertions, 17 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 2f7f373af..575c4f20c 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -72,8 +72,7 @@ rand_core = "0.6.3" | |||
| 72 | sdio-host = "0.5.0" | 72 | sdio-host = "0.5.0" |
| 73 | critical-section = "1.1" | 73 | critical-section = "1.1" |
| 74 | #stm32-metapac = { version = "15" } | 74 | #stm32-metapac = { version = "15" } |
| 75 | # stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad00827345b4b758b2453082809d6e3b634b5364" } | 75 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-acaf04256034066bd5b3a8426224ccf3e4cb7d19" } |
| 76 | stm32-metapac = { path = "../../stm32-data/build/stm32-metapac" } | ||
| 77 | 76 | ||
| 78 | vcell = "0.1.3" | 77 | vcell = "0.1.3" |
| 79 | nb = "1.0.0" | 78 | nb = "1.0.0" |
| @@ -100,8 +99,7 @@ proc-macro2 = "1.0.36" | |||
| 100 | quote = "1.0.15" | 99 | quote = "1.0.15" |
| 101 | 100 | ||
| 102 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 101 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 103 | # stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad00827345b4b758b2453082809d6e3b634b5364", default-features = false, features = ["metadata"] } | 102 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-acaf04256034066bd5b3a8426224ccf3e4cb7d19", default-features = false, features = ["metadata"] } |
| 104 | stm32-metapac = { path = "../../stm32-data/build/stm32-metapac", default-features = false, features = ["metadata"] } | ||
| 105 | 103 | ||
| 106 | [features] | 104 | [features] |
| 107 | default = ["rt"] | 105 | default = ["rt"] |
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))] |
| 38 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 38 | pub 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)] |
| 41 | pub enum HseMode { | 44 | pub 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") |
diff --git a/embassy-usb-synopsys-otg/src/lib.rs b/embassy-usb-synopsys-otg/src/lib.rs index 3ff965149..f90403936 100644 --- a/embassy-usb-synopsys-otg/src/lib.rs +++ b/embassy-usb-synopsys-otg/src/lib.rs | |||
| @@ -584,20 +584,27 @@ impl<'d, const MAX_EP_COUNT: usize> Bus<'d, MAX_EP_COUNT> { | |||
| 584 | }); | 584 | }); |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | /// Applies configuration specific to | ||
| 588 | /// Core ID 0x0000_5000 | ||
| 587 | pub fn config_v5(&mut self) { | 589 | pub fn config_v5(&mut self) { |
| 588 | let r = self.instance.regs; | 590 | let r = self.instance.regs; |
| 591 | let phy_type = self.instance.phy_type; | ||
| 589 | 592 | ||
| 590 | r.gccfg_v3().modify(|w| { | 593 | if phy_type == PhyType::InternalHighSpeed { |
| 591 | w.set_vbvaloven(true); | 594 | r.gccfg_v3().modify(|w| { |
| 592 | w.set_vbvaloval(true); | 595 | w.set_vbvaloven(!self.config.vbus_detection); |
| 593 | w.set_vbden(self.config.vbus_detection); | 596 | w.set_vbvaloval(!self.config.vbus_detection); |
| 594 | }); | 597 | w.set_vbden(self.config.vbus_detection); |
| 595 | 598 | }); | |
| 596 | // Force B-peripheral session | 599 | } else { |
| 597 | r.gotgctl().modify(|w| { | 600 | r.gotgctl().modify(|w| { |
| 598 | w.set_vbvaloen(!self.config.vbus_detection); | 601 | w.set_bvaloen(!self.config.vbus_detection); |
| 599 | w.set_bvaloval(true); | 602 | w.set_bvaloval(!self.config.vbus_detection); |
| 600 | }); | 603 | }); |
| 604 | r.gccfg_v3().modify(|w| { | ||
| 605 | w.set_vbden(self.config.vbus_detection); | ||
| 606 | }); | ||
| 607 | } | ||
| 601 | } | 608 | } |
| 602 | 609 | ||
| 603 | fn init(&mut self) { | 610 | fn init(&mut self) { |
diff --git a/examples/stm32h7rs/src/bin/usb_serial.rs b/examples/stm32h7rs/src/bin/usb_serial.rs index 5a234e898..6773f7843 100644 --- a/examples/stm32h7rs/src/bin/usb_serial.rs +++ b/examples/stm32h7rs/src/bin/usb_serial.rs | |||
| @@ -48,6 +48,7 @@ async fn main(_spawner: Spawner) { | |||
| 48 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 MHz | 48 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 MHz |
| 49 | config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 MHz | 49 | config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 MHz |
| 50 | config.rcc.voltage_scale = VoltageScale::HIGH; | 50 | config.rcc.voltage_scale = VoltageScale::HIGH; |
| 51 | config.rcc.mux.usbphycsel = mux::Usbphycsel::HSE; | ||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | let p = embassy_stm32::init(config); | 54 | let p = embassy_stm32::init(config); |
