diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-07-17 00:51:20 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-17 00:51:20 +0000 |
| commit | 0290c8565e9e3443d52edb5c250a53a50f6fc2a8 (patch) | |
| tree | fe90c3cbb54a8d0ddf1a5c93302feb926a9e4605 | |
| parent | 3b718b1e4d3aed9953717b460920a7736298a2a8 (diff) | |
| parent | f46bfd4c6ff50740b7177c054918da6a393ca7f1 (diff) | |
Merge pull request #4408 from leftger/feat/usb-stm32wba
Add STM32WBA USB_OTG_HS support
| -rw-r--r-- | embassy-stm32/src/usb/mod.rs | 28 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/otg.rs | 19 |
2 files changed, 43 insertions, 4 deletions
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index ae5963420..692897b59 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(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs)))] | 18 | #[cfg(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs), all(stm32wba, 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,7 +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(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs))))] | 28 | #[cfg(not(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))] |
| 29 | if freq.0.abs_diff(48_000_000) > 120_000 { | 29 | if freq.0.abs_diff(48_000_000) > 120_000 { |
| 30 | panic!( | 30 | panic!( |
| 31 | "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.", |
| @@ -102,6 +102,30 @@ fn common_init<T: Instance>() { | |||
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | #[cfg(stm32wba)] | ||
| 106 | { | ||
| 107 | // Enable USB power | ||
| 108 | critical_section::with(|_| { | ||
| 109 | crate::pac::PWR.svmcr().modify(|w| { | ||
| 110 | w.set_usv(crate::pac::pwr::vals::Usv::B_0X1); | ||
| 111 | // w.set_uvmen(true); | ||
| 112 | }) | ||
| 113 | }); | ||
| 114 | |||
| 115 | // Wait for USB power to stabilize | ||
| 116 | while !crate::pac::PWR.vosr().read().vdd11usbrdy() {} | ||
| 117 | |||
| 118 | // Now set up transceiver power if it's a OTG-HS | ||
| 119 | #[cfg(peri_usb_otg_hs)] | ||
| 120 | { | ||
| 121 | crate::pac::PWR.vosr().modify(|w| { | ||
| 122 | w.set_usbpwren(true); | ||
| 123 | w.set_usbboosten(true); | ||
| 124 | }); | ||
| 125 | while !crate::pac::PWR.vosr().read().usbboostrdy() {} | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 105 | T::Interrupt::unpend(); | 129 | T::Interrupt::unpend(); |
| 106 | unsafe { T::Interrupt::enable() }; | 130 | unsafe { T::Interrupt::enable() }; |
| 107 | 131 | ||
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index e9afc0c54..b074cfa1b 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs | |||
| @@ -105,7 +105,7 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 105 | config: Config, | 105 | config: Config, |
| 106 | ) -> Self { | 106 | ) -> Self { |
| 107 | // For STM32U5 High speed pins need to be left in analog mode | 107 | // For STM32U5 High speed pins need to be left in analog mode |
| 108 | #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] | 108 | #[cfg(not(any(all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))] |
| 109 | { | 109 | { |
| 110 | _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | 110 | _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); |
| 111 | _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); | 111 | _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); |
| @@ -327,6 +327,20 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 327 | }); | 327 | }); |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | #[cfg(all(stm32wba, peri_usb_otg_hs))] | ||
| 331 | { | ||
| 332 | crate::pac::SYSCFG.otghsphycr().modify(|w| { | ||
| 333 | w.set_en(true); | ||
| 334 | }); | ||
| 335 | |||
| 336 | critical_section::with(|_| { | ||
| 337 | crate::pac::RCC.ahb2enr().modify(|w| { | ||
| 338 | w.set_usb_otg_hsen(true); | ||
| 339 | w.set_otghsphyen(true); | ||
| 340 | }); | ||
| 341 | }); | ||
| 342 | } | ||
| 343 | |||
| 330 | let r = T::regs(); | 344 | let r = T::regs(); |
| 331 | let core_id = r.cid().read().0; | 345 | let core_id = r.cid().read().0; |
| 332 | trace!("Core id {:08x}", core_id); | 346 | trace!("Core id {:08x}", core_id); |
| @@ -468,6 +482,7 @@ foreach_interrupt!( | |||
| 468 | stm32f7, | 482 | stm32f7, |
| 469 | stm32l4, | 483 | stm32l4, |
| 470 | stm32u5, | 484 | stm32u5, |
| 485 | stm32wba, | ||
| 471 | ))] { | 486 | ))] { |
| 472 | const FIFO_DEPTH_WORDS: u16 = 320; | 487 | const FIFO_DEPTH_WORDS: u16 = 320; |
| 473 | const ENDPOINT_COUNT: usize = 6; | 488 | const ENDPOINT_COUNT: usize = 6; |
| @@ -477,7 +492,7 @@ foreach_interrupt!( | |||
| 477 | } else if #[cfg(any(stm32h7, stm32h7rs))] { | 492 | } else if #[cfg(any(stm32h7, stm32h7rs))] { |
| 478 | const FIFO_DEPTH_WORDS: u16 = 1024; | 493 | const FIFO_DEPTH_WORDS: u16 = 1024; |
| 479 | const ENDPOINT_COUNT: usize = 9; | 494 | const ENDPOINT_COUNT: usize = 9; |
| 480 | } else if #[cfg(stm32u5)] { | 495 | } else if #[cfg(any(stm32wba, stm32u5))] { |
| 481 | const FIFO_DEPTH_WORDS: u16 = 320; | 496 | const FIFO_DEPTH_WORDS: u16 = 320; |
| 482 | const ENDPOINT_COUNT: usize = 6; | 497 | const ENDPOINT_COUNT: usize = 6; |
| 483 | } else { | 498 | } else { |
