Merge pull request #4408 from leftger/feat/usb-stm32wba

Add STM32WBA USB_OTG_HS support
This commit is contained in:
Dario Nieuwenhuis 2025-07-17 00:51:20 +00:00 committed by GitHub
commit 0290c8565e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 4 deletions

View File

@ -15,7 +15,7 @@ fn common_init<T: Instance>() {
let freq = T::frequency();
// 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
#[cfg(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs)))]
#[cfg(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs)))]
if ![16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000].contains(&freq.0) {
panic!(
"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>() {
// Check frequency is within the 0.25% tolerance allowed by the spec.
// Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user
// has tight clock restrictions due to something else (like audio).
#[cfg(not(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs))))]
#[cfg(not(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))]
if freq.0.abs_diff(48_000_000) > 120_000 {
panic!(
"USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
@ -102,6 +102,30 @@ fn common_init<T: Instance>() {
}
}
#[cfg(stm32wba)]
{
// Enable USB power
critical_section::with(|_| {
crate::pac::PWR.svmcr().modify(|w| {
w.set_usv(crate::pac::pwr::vals::Usv::B_0X1);
// w.set_uvmen(true);
})
});
// Wait for USB power to stabilize
while !crate::pac::PWR.vosr().read().vdd11usbrdy() {}
// Now set up transceiver power if it's a OTG-HS
#[cfg(peri_usb_otg_hs)]
{
crate::pac::PWR.vosr().modify(|w| {
w.set_usbpwren(true);
w.set_usbboosten(true);
});
while !crate::pac::PWR.vosr().read().usbboostrdy() {}
}
}
T::Interrupt::unpend();
unsafe { T::Interrupt::enable() };

View File

@ -105,7 +105,7 @@ impl<'d, T: Instance> Driver<'d, T> {
config: Config,
) -> Self {
// For STM32U5 High speed pins need to be left in analog mode
#[cfg(not(all(stm32u5, peri_usb_otg_hs)))]
#[cfg(not(any(all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))]
{
_dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
_dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
@ -327,6 +327,20 @@ impl<'d, T: Instance> Bus<'d, T> {
});
}
#[cfg(all(stm32wba, peri_usb_otg_hs))]
{
crate::pac::SYSCFG.otghsphycr().modify(|w| {
w.set_en(true);
});
critical_section::with(|_| {
crate::pac::RCC.ahb2enr().modify(|w| {
w.set_usb_otg_hsen(true);
w.set_otghsphyen(true);
});
});
}
let r = T::regs();
let core_id = r.cid().read().0;
trace!("Core id {:08x}", core_id);
@ -468,6 +482,7 @@ foreach_interrupt!(
stm32f7,
stm32l4,
stm32u5,
stm32wba,
))] {
const FIFO_DEPTH_WORDS: u16 = 320;
const ENDPOINT_COUNT: usize = 6;
@ -477,7 +492,7 @@ foreach_interrupt!(
} else if #[cfg(any(stm32h7, stm32h7rs))] {
const FIFO_DEPTH_WORDS: u16 = 1024;
const ENDPOINT_COUNT: usize = 9;
} else if #[cfg(stm32u5)] {
} else if #[cfg(any(stm32wba, stm32u5))] {
const FIFO_DEPTH_WORDS: u16 = 320;
const ENDPOINT_COUNT: usize = 6;
} else {