diff options
| author | Marvin Drees <[email protected]> | 2024-12-06 16:22:08 +0100 |
|---|---|---|
| committer | Marvin Drees <[email protected]> | 2024-12-10 13:10:06 +0100 |
| commit | a0e056a629c166b38c536c68afbf852819f10143 (patch) | |
| tree | 2c5279a1542d87e28aa2788292bb9c9c4aa79ee6 | |
| parent | 501d3942e8b6b04fd1cb4c14728ba4c2e118d8b5 (diff) | |
Update STM32U5 OTG HS clock handling
Signed-off-by: Marvin Drees <[email protected]>
| -rw-r--r-- | embassy-stm32/src/rcc/u5.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/mod.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/otg.rs | 2 |
3 files changed, 31 insertions, 14 deletions
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index af99c77bc..dc77dc540 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -1,9 +1,13 @@ | |||
| 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 2 | #[cfg(all(peri_usb_otg_hs))] | ||
| 3 | pub use crate::pac::rcc::vals::Otghssel; | ||
| 2 | pub use crate::pac::rcc::vals::{ | 4 | pub use crate::pac::rcc::vals::{ |
| 3 | Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, | 5 | Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, |
| 4 | Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, | 6 | Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, |
| 5 | }; | 7 | }; |
| 6 | use crate::pac::rcc::vals::{Hseext, Msirgsel, Pllmboost, Pllrge}; | 8 | use crate::pac::rcc::vals::{Hseext, Msirgsel, Pllmboost, Pllrge}; |
| 9 | #[cfg(all(peri_usb_otg_hs))] | ||
| 10 | pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG}; | ||
| 7 | use crate::pac::{FLASH, PWR, RCC}; | 11 | use crate::pac::{FLASH, PWR, RCC}; |
| 8 | use crate::rcc::LSI_FREQ; | 12 | use crate::rcc::LSI_FREQ; |
| 9 | use crate::time::Hertz; | 13 | use crate::time::Hertz; |
| @@ -295,6 +299,31 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 295 | 299 | ||
| 296 | let rtc = config.ls.init(); | 300 | let rtc = config.ls.init(); |
| 297 | 301 | ||
| 302 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | ||
| 303 | let usb_refck = match config.mux.otghssel { | ||
| 304 | Otghssel::HSE => hse, | ||
| 305 | Otghssel::HSE_DIV_2 => hse.map(|hse_val| hse_val / 2u8), | ||
| 306 | Otghssel::PLL1_P => pll1.p, | ||
| 307 | Otghssel::PLL1_P_DIV_2 => pll1.p.map(|pll1p_val| pll1p_val / 2u8), | ||
| 308 | }; | ||
| 309 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | ||
| 310 | let usb_refck_sel = match usb_refck { | ||
| 311 | Some(clk_val) => match clk_val { | ||
| 312 | Hertz(16_000_000) => Usbrefcksel::MHZ16, | ||
| 313 | Hertz(19_200_000) => Usbrefcksel::MHZ19_2, | ||
| 314 | Hertz(20_000_000) => Usbrefcksel::MHZ20, | ||
| 315 | Hertz(24_000_000) => Usbrefcksel::MHZ24, | ||
| 316 | Hertz(26_000_000) => Usbrefcksel::MHZ26, | ||
| 317 | Hertz(32_000_000) => Usbrefcksel::MHZ32, | ||
| 318 | _ => panic!("cannot select OTG_HS reference clock with source frequency of {} Hz, must be one of 16, 19.2, 20, 24, 26, 32 MHz", clk_val), | ||
| 319 | }, | ||
| 320 | None => Usbrefcksel::MHZ24, | ||
| 321 | }; | ||
| 322 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | ||
| 323 | SYSCFG.otghsphycr().modify(|w| { | ||
| 324 | w.set_clksel(usb_refck_sel); | ||
| 325 | }); | ||
| 326 | |||
| 298 | let lse = config.ls.lse.map(|l| l.frequency); | 327 | let lse = config.ls.lse.map(|l| l.frequency); |
| 299 | let lsi = config.ls.lsi.then_some(LSI_FREQ); | 328 | let lsi = config.ls.lsi.then_some(LSI_FREQ); |
| 300 | 329 | ||
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index 9737b9b3f..ae5963420 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs | |||
| @@ -15,7 +15,7 @@ fn common_init<T: Instance>() { | |||
| 15 | let freq = T::frequency(); | 15 | let freq = T::frequency(); |
| 16 | 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 | 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)] | 18 | #[cfg(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs)))] |
| 19 | if ![16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000].contains(&freq.0) { | 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!( | 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.", | 21 | "USB clock should be one of 16, 19.2, 20, 24, 26, 32Mhz but is {} Hz. Please double-check your RCC settings.", |
| @@ -25,8 +25,7 @@ fn common_init<T: Instance>() { | |||
| 25 | // 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. |
| 26 | // 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 |
| 27 | // 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))] | 28 | #[cfg(not(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs))))] |
| 29 | #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] | ||
| 30 | if freq.0.abs_diff(48_000_000) > 120_000 { | 29 | if freq.0.abs_diff(48_000_000) > 120_000 { |
| 31 | panic!( | 30 | panic!( |
| 32 | "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.", |
| @@ -34,15 +33,6 @@ fn common_init<T: Instance>() { | |||
| 34 | ) | 33 | ) |
| 35 | } | 34 | } |
| 36 | 35 | ||
| 37 | // For OTG-HS on STM32U5 only the 32MHz clock is fast enough (Table 762, Sect 73.14.4) | ||
| 38 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | ||
| 39 | if freq.0.abs_diff(32_000_000) > 120_000 { | ||
| 40 | panic!( | ||
| 41 | "USB clock should be 32Mhz but is {} Hz. Please double-check your RCC settings.", | ||
| 42 | freq.0 | ||
| 43 | ) | ||
| 44 | } | ||
| 45 | |||
| 46 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))] | 36 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))] |
| 47 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); | 37 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); |
| 48 | 38 | ||
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index d1b38a558..d3c7978e4 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs | |||
| @@ -315,9 +315,7 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 315 | 315 | ||
| 316 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | 316 | #[cfg(all(stm32u5, peri_usb_otg_hs))] |
| 317 | { | 317 | { |
| 318 | // Only the 32MHz clock is suitable here, which the magic number represents | ||
| 319 | crate::pac::SYSCFG.otghsphycr().modify(|w| { | 318 | crate::pac::SYSCFG.otghsphycr().modify(|w| { |
| 320 | w.set_clksel(11); | ||
| 321 | w.set_en(true); | 319 | w.set_en(true); |
| 322 | }); | 320 | }); |
| 323 | 321 | ||
