aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Drees <[email protected]>2024-12-06 16:22:08 +0100
committerMarvin Drees <[email protected]>2024-12-10 13:10:06 +0100
commita0e056a629c166b38c536c68afbf852819f10143 (patch)
tree2c5279a1542d87e28aa2788292bb9c9c4aa79ee6
parent501d3942e8b6b04fd1cb4c14728ba4c2e118d8b5 (diff)
Update STM32U5 OTG HS clock handling
Signed-off-by: Marvin Drees <[email protected]>
-rw-r--r--embassy-stm32/src/rcc/u5.rs29
-rw-r--r--embassy-stm32/src/usb/mod.rs14
-rw-r--r--embassy-stm32/src/usb/otg.rs2
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 @@
1pub use crate::pac::pwr::vals::Vos as VoltageScale; 1pub use crate::pac::pwr::vals::Vos as VoltageScale;
2#[cfg(all(peri_usb_otg_hs))]
3pub use crate::pac::rcc::vals::Otghssel;
2pub use crate::pac::rcc::vals::{ 4pub 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};
6use crate::pac::rcc::vals::{Hseext, Msirgsel, Pllmboost, Pllrge}; 8use crate::pac::rcc::vals::{Hseext, Msirgsel, Pllmboost, Pllrge};
9#[cfg(all(peri_usb_otg_hs))]
10pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG};
7use crate::pac::{FLASH, PWR, RCC}; 11use crate::pac::{FLASH, PWR, RCC};
8use crate::rcc::LSI_FREQ; 12use crate::rcc::LSI_FREQ;
9use crate::time::Hertz; 13use 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