diff options
| author | Dave Marples <[email protected]> | 2024-12-05 16:35:56 +0000 |
|---|---|---|
| committer | Marvin Drees <[email protected]> | 2024-12-10 10:51:28 +0100 |
| commit | 501d3942e8b6b04fd1cb4c14728ba4c2e118d8b5 (patch) | |
| tree | d8b71167fc51871c4d2ab44203076e2c0d241b85 /embassy-stm32/src/usb | |
| parent | 86578acaa4d4dbed06ed4fcecec25884f6883e82 (diff) | |
Add support for stm32u595/5a5 OTG_HS in client mode
Diffstat (limited to 'embassy-stm32/src/usb')
| -rw-r--r-- | embassy-stm32/src/usb/mod.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/otg.rs | 32 |
2 files changed, 45 insertions, 7 deletions
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index a473285bf..9737b9b3f 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs | |||
| @@ -26,6 +26,7 @@ fn common_init<T: Instance>() { | |||
| 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(stm32h7rs))] |
| 29 | #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] | ||
| 29 | if freq.0.abs_diff(48_000_000) > 120_000 { | 30 | if freq.0.abs_diff(48_000_000) > 120_000 { |
| 30 | panic!( | 31 | panic!( |
| 31 | "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.", | 32 | "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.", |
| @@ -33,6 +34,15 @@ fn common_init<T: Instance>() { | |||
| 33 | ) | 34 | ) |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 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 | |||
| 36 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))] | 46 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))] |
| 37 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); | 47 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); |
| 38 | 48 | ||
| @@ -90,6 +100,16 @@ fn common_init<T: Instance>() { | |||
| 90 | 100 | ||
| 91 | // Wait for USB power to stabilize | 101 | // Wait for USB power to stabilize |
| 92 | while !crate::pac::PWR.svmsr().read().vddusbrdy() {} | 102 | while !crate::pac::PWR.svmsr().read().vddusbrdy() {} |
| 103 | |||
| 104 | // Now set up transceiver power if it's a OTG-HS | ||
| 105 | #[cfg(peri_usb_otg_hs)] | ||
| 106 | { | ||
| 107 | crate::pac::PWR.vosr().modify(|w| { | ||
| 108 | w.set_usbpwren(true); | ||
| 109 | w.set_usbboosten(true); | ||
| 110 | }); | ||
| 111 | while !crate::pac::PWR.vosr().read().usbboostrdy() {} | ||
| 112 | } | ||
| 93 | } | 113 | } |
| 94 | 114 | ||
| 95 | T::Interrupt::unpend(); | 115 | T::Interrupt::unpend(); |
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index 6ca28b156..d1b38a558 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs | |||
| @@ -26,7 +26,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 26 | unsafe fn on_interrupt() { | 26 | unsafe fn on_interrupt() { |
| 27 | let r = T::regs(); | 27 | let r = T::regs(); |
| 28 | let state = T::state(); | 28 | let state = T::state(); |
| 29 | |||
| 30 | on_interrupt_impl(r, state, T::ENDPOINT_COUNT); | 29 | on_interrupt_impl(r, state, T::ENDPOINT_COUNT); |
| 31 | } | 30 | } |
| 32 | } | 31 | } |
| @@ -103,15 +102,18 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 103 | pub fn new_hs( | 102 | pub fn new_hs( |
| 104 | _peri: impl Peripheral<P = T> + 'd, | 103 | _peri: impl Peripheral<P = T> + 'd, |
| 105 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 104 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 106 | dp: impl Peripheral<P = impl DpPin<T>> + 'd, | 105 | _dp: impl Peripheral<P = impl DpPin<T>> + 'd, |
| 107 | dm: impl Peripheral<P = impl DmPin<T>> + 'd, | 106 | _dm: impl Peripheral<P = impl DmPin<T>> + 'd, |
| 108 | ep_out_buffer: &'d mut [u8], | 107 | ep_out_buffer: &'d mut [u8], |
| 109 | config: Config, | 108 | config: Config, |
| 110 | ) -> Self { | 109 | ) -> Self { |
| 111 | into_ref!(dp, dm); | 110 | // For STM32U5 High speed pins need to be left in analog mode |
| 112 | 111 | #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] | |
| 113 | dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | 112 | { |
| 114 | dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | 113 | into_ref!(_dp, _dm); |
| 114 | _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | ||
| 115 | _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | ||
| 116 | } | ||
| 115 | 117 | ||
| 116 | let instance = OtgInstance { | 118 | let instance = OtgInstance { |
| 117 | regs: T::regs(), | 119 | regs: T::regs(), |
| @@ -311,6 +313,22 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 311 | }); | 313 | }); |
| 312 | }); | 314 | }); |
| 313 | 315 | ||
| 316 | #[cfg(all(stm32u5, peri_usb_otg_hs))] | ||
| 317 | { | ||
| 318 | // Only the 32MHz clock is suitable here, which the magic number represents | ||
| 319 | crate::pac::SYSCFG.otghsphycr().modify(|w| { | ||
| 320 | w.set_clksel(11); | ||
| 321 | w.set_en(true); | ||
| 322 | }); | ||
| 323 | |||
| 324 | critical_section::with(|_| { | ||
| 325 | crate::pac::RCC.ahb2enr1().modify(|w| { | ||
| 326 | w.set_usb_otg_hsen(true); | ||
| 327 | w.set_usb_otg_hs_phyen(true); | ||
| 328 | }); | ||
| 329 | }); | ||
| 330 | } | ||
| 331 | |||
| 314 | let r = T::regs(); | 332 | let r = T::regs(); |
| 315 | let core_id = r.cid().read().0; | 333 | let core_id = r.cid().read().0; |
| 316 | trace!("Core id {:08x}", core_id); | 334 | trace!("Core id {:08x}", core_id); |
