From 81bef219e315aca005e50143757c681d5bc122ee Mon Sep 17 00:00:00 2001 From: Gerzain Mata Date: Sun, 27 Jul 2025 16:44:43 -0700 Subject: Working USB_OTG_HS example for STM32WBA --- examples/stm32wba/src/bin/usb_hs_serial.rs | 25 ++---- examples/stm32wba/src/bin/usb_serial.rs | 119 ----------------------------- 2 files changed, 6 insertions(+), 138 deletions(-) delete mode 100644 examples/stm32wba/src/bin/usb_serial.rs (limited to 'examples') diff --git a/examples/stm32wba/src/bin/usb_hs_serial.rs b/examples/stm32wba/src/bin/usb_hs_serial.rs index 2e17e52d1..20bdeaac3 100644 --- a/examples/stm32wba/src/bin/usb_hs_serial.rs +++ b/examples/stm32wba/src/bin/usb_hs_serial.rs @@ -21,24 +21,16 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); - { use embassy_stm32::rcc::*; - // External HSE (32 MHz) setup - // config.rcc.hse = Some(Hse { - // prescaler: HsePrescaler::DIV2, - // }); - - // Fine-tune PLL1 dividers/multipliers config.rcc.pll1 = Some(Pll { source: PllSource::HSI, - prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz - mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO - divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk) - divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz (NOT USED) - // divq: None, - divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USBOTG) - frac: Some(0), // Fractional part (enabled) + prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz + mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO + divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk) + divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz + divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USB_OTG_HS) + frac: Some(0), // Fractional part (disabled) }); config.rcc.ahb_pre = AHBPrescaler::DIV1; @@ -54,11 +46,6 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(config); - // TRDT set to 5 - // ASVLD set to 1 - // BSVLD set to 1 - - // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); diff --git a/examples/stm32wba/src/bin/usb_serial.rs b/examples/stm32wba/src/bin/usb_serial.rs deleted file mode 100644 index 8d60aed8c..000000000 --- a/examples/stm32wba/src/bin/usb_serial.rs +++ /dev/null @@ -1,119 +0,0 @@ -#![no_std] -#![no_main] - -use defmt::{panic, *}; -use defmt_rtt as _; // global logger -use embassy_executor::Spawner; -use embassy_futures::join::join; -use embassy_stm32::usb::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; -use embassy_usb::driver::EndpointError; -use embassy_usb::Builder; -use panic_probe as _; - -bind_interrupts!(struct Irqs { - OTG_HS => usb::InterruptHandler; -}); - -#[embassy_executor::main] -async fn main(_spawner: Spawner) { - info!("Hello World!"); - - let mut config = Config::default(); - { - use embassy_stm32::rcc::*; - config.rcc.hsi = true; - config.rcc.pll1 = Some(Pll { - source: PllSource::HSI, // 16 MHz - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL10, - divp: None, - divq: None, - divr: Some(PllDiv::DIV1), // 160 MHz - }); - config.rcc.sys = Sysclk::PLL1_R; - config.rcc.voltage_range = VoltageScale::RANGE1; - config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB - config.rcc.mux.iclksel = mux::Iclksel::HSI48; // USB uses ICLK - } - - let p = embassy_stm32::init(config); - - // Create the driver, from the HAL. - let mut ep_out_buffer = [0u8; 256]; - let mut config = embassy_stm32::usb::Config::default(); - // Do not enable vbus_detection. This is a safe default that works in all boards. - // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need - // to enable vbus_detection to comply with the USB spec. If you enable it, the board - // has to support it or USB won't work at all. See docs on `vbus_detection` for details. - config.vbus_detection = false; - let driver = Driver::new_hs(p.USB_OTG_HS, Irqs, p.PD6, p.PD7, &mut ep_out_buffer, config); - - // Create embassy-usb Config - let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); - config.manufacturer = Some("Embassy"); - config.product = Some("USB-serial example"); - config.serial_number = Some("12345678"); - - // Create embassy-usb DeviceBuilder using the driver and config. - // It needs some buffers for building the descriptors. - let mut config_descriptor = [0; 256]; - let mut bos_descriptor = [0; 256]; - let mut control_buf = [0; 64]; - - let mut state = State::new(); - - let mut builder = Builder::new( - driver, - config, - &mut config_descriptor, - &mut bos_descriptor, - &mut [], // no msos descriptors - &mut control_buf, - ); - - // Create classes on the builder. - let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); - - // Build the builder. - let mut usb = builder.build(); - - // Run the USB device. - let usb_fut = usb.run(); - - // Do stuff with the class! - let echo_fut = async { - loop { - class.wait_connection().await; - info!("Connected"); - let _ = echo(&mut class).await; - info!("Disconnected"); - } - }; - - // Run everything concurrently. - // If we had made everything `'static` above instead, we could do this using separate tasks instead. - join(usb_fut, echo_fut).await; -} - -struct Disconnected {} - -impl From for Disconnected { - fn from(val: EndpointError) -> Self { - match val { - EndpointError::BufferOverflow => panic!("Buffer overflow"), - EndpointError::Disabled => Disconnected {}, - } - } -} - -async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { - let mut buf = [0; 64]; - loop { - let n = class.read_packet(&mut buf).await?; - let data = &buf[..n]; - info!("data: {:x}", data); - class.write_packet(data).await?; - } -} -- cgit