diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index fe5236ed6..ee224da67 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -826,20 +826,20 @@ fn main() { (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), (("usb", "DP"), quote!(crate::usb::DpPin)), (("usb", "DM"), quote!(crate::usb::DmPin)), - (("otg", "DP"), quote!(crate::usb_otg::DpPin)), - (("otg", "DM"), quote!(crate::usb_otg::DmPin)), - (("otg", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)), - (("otg", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)), - (("otg", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)), - (("otg", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)), - (("otg", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)), - (("otg", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)), - (("otg", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)), - (("otg", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)), - (("otg", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)), - (("otg", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)), - (("otg", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)), - (("otg", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)), + (("otg", "DP"), quote!(crate::usb::DpPin)), + (("otg", "DM"), quote!(crate::usb::DmPin)), + (("otg", "ULPI_CK"), quote!(crate::usb::UlpiClkPin)), + (("otg", "ULPI_DIR"), quote!(crate::usb::UlpiDirPin)), + (("otg", "ULPI_NXT"), quote!(crate::usb::UlpiNxtPin)), + (("otg", "ULPI_STP"), quote!(crate::usb::UlpiStpPin)), + (("otg", "ULPI_D0"), quote!(crate::usb::UlpiD0Pin)), + (("otg", "ULPI_D1"), quote!(crate::usb::UlpiD1Pin)), + (("otg", "ULPI_D2"), quote!(crate::usb::UlpiD2Pin)), + (("otg", "ULPI_D3"), quote!(crate::usb::UlpiD3Pin)), + (("otg", "ULPI_D4"), quote!(crate::usb::UlpiD4Pin)), + (("otg", "ULPI_D5"), quote!(crate::usb::UlpiD5Pin)), + (("otg", "ULPI_D6"), quote!(crate::usb::UlpiD6Pin)), + (("otg", "ULPI_D7"), quote!(crate::usb::UlpiD7Pin)), (("can", "TX"), quote!(crate::can::TxPin)), (("can", "RX"), quote!(crate::can::RxPin)), (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)), diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index b38b5c29d..9e26a3513 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -79,10 +79,8 @@ pub mod ucpd; pub mod uid; #[cfg(usart)] pub mod usart; -#[cfg(usb)] +#[cfg(any(usb, otg))] pub mod usb; -#[cfg(otg)] -pub mod usb_otg; #[cfg(iwdg)] pub mod wdg; @@ -107,10 +105,10 @@ pub use crate::_generated::interrupt; /// Example of how to bind one interrupt: /// /// ```rust,ignore -/// use embassy_stm32::{bind_interrupts, usb_otg, peripherals}; +/// use embassy_stm32::{bind_interrupts, usb, peripherals}; /// /// bind_interrupts!(struct Irqs { -/// OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; +/// OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; /// }); /// ``` /// diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index 4debd4e54..788f61f16 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs @@ -1,37 +1,69 @@ //! Universal Serial Bus (USB) -use crate::interrupt; -use crate::rcc::RccPeripheral; +#[cfg_attr(usb, path = "usb.rs")] +#[cfg_attr(otg, path = "otg.rs")] +mod _version; +pub use _version::*; -mod usb; -pub use usb::*; +use crate::interrupt::typelevel::Interrupt; +use crate::rcc::sealed::RccPeripheral; -pub(crate) mod sealed { - pub trait Instance { - fn regs() -> crate::pac::usb::Usb; +/// clock, power initialization stuff that's common for USB and OTG. +fn common_init<T: Instance>() { + // Check the USB clock is enabled and running at exactly 48 MHz. + // frequency() will panic if not enabled + let freq = T::frequency(); + // 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). + 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.", + freq.0 + ) } + + #[cfg(any(stm32l4, stm32l5, stm32wb))] + critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); + + #[cfg(pwr_h5)] + critical_section::with(|_| crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true))); + + #[cfg(stm32h7)] + { + // If true, VDD33USB is generated by internal regulator from VDD50USB + // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo) + // TODO: unhardcode + let internal_regulator = false; + + // Enable USB power + critical_section::with(|_| { + crate::pac::PWR.cr3().modify(|w| { + w.set_usb33den(true); + w.set_usbregen(internal_regulator); + }) + }); + + // Wait for USB power to stabilize + while !crate::pac::PWR.cr3().read().usb33rdy() {} + } + + #[cfg(stm32u5)] + { + // Enable USB power + critical_section::with(|_| { + crate::pac::PWR.svmcr().modify(|w| { + w.set_usv(true); + w.set_uvmen(true); + }) + }); + + // Wait for USB power to stabilize + while !crate::pac::PWR.svmsr().read().vddusbrdy() {} + } + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + <T as RccPeripheral>::enable_and_reset(); } - -/// USB instance trait. -pub trait Instance: sealed::Instance + RccPeripheral + 'static { - /// Interrupt for this USB instance. - type Interrupt: interrupt::typelevel::Interrupt; -} - -// Internal PHY pins -pin_trait!(DpPin, Instance); -pin_trait!(DmPin, Instance); - -foreach_interrupt!( - ($inst:ident, usb, $block:ident, LP, $irq:ident) => { - impl sealed::Instance for crate::peripherals::$inst { - fn regs() -> crate::pac::usb::Usb { - crate::pac::$inst - } - } - - impl Instance for crate::peripherals::$inst { - type Interrupt = crate::interrupt::typelevel::$irq; - } - }; -); diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb/otg.rs similarity index 90% rename from embassy-stm32/src/usb_otg/usb.rs rename to embassy-stm32/src/usb/otg.rs index 373697ec8..80a08f3c5 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb/otg.rs @@ -11,7 +11,6 @@ use embassy_usb_driver::{ }; use futures::future::poll_fn; -use super::*; use crate::gpio::sealed::AFType; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; @@ -561,8 +560,7 @@ impl<'d, T: Instance> Bus<'d, T> { impl<'d, T: Instance> Bus<'d, T> { fn init(&mut self) { - #[cfg(stm32l4)] - critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); + super::common_init::<T>(); #[cfg(stm32f7)] { @@ -590,22 +588,6 @@ impl<'d, T: Instance> Bus<'d, T> { #[cfg(stm32h7)] { - // If true, VDD33USB is generated by internal regulator from VDD50USB - // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo) - // TODO: unhardcode - let internal_regulator = false; - - // Enable USB power - critical_section::with(|_| { - crate::pac::PWR.cr3().modify(|w| { - w.set_usb33den(true); - w.set_usbregen(internal_regulator); - }) - }); - - // Wait for USB power to stabilize - while !crate::pac::PWR.cr3().read().usb33rdy() {} - // Enable ULPI clock if external PHY is used let ulpien = !self.phy_type.internal(); critical_section::with(|_| { @@ -626,25 +608,6 @@ impl<'d, T: Instance> Bus<'d, T> { }); } - #[cfg(stm32u5)] - { - // Enable USB power - critical_section::with(|_| { - crate::pac::PWR.svmcr().modify(|w| { - w.set_usv(true); - w.set_uvmen(true); - }) - }); - - // Wait for USB power to stabilize - while !crate::pac::PWR.svmsr().read().vddusbrdy() {} - } - - <T as RccPeripheral>::enable_and_reset(); - - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; - let r = T::regs(); let core_id = r.cid().read().0; trace!("Core id {:08x}", core_id); @@ -1469,3 +1432,159 @@ fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 { fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { r.cid().read().0 & 0xf000 == 0x1000 } + +// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps +const MAX_EP_COUNT: usize = 9; + +pub(crate) mod sealed { + pub trait Instance { + const HIGH_SPEED: bool; + const FIFO_DEPTH_WORDS: u16; + const ENDPOINT_COUNT: usize; + + fn regs() -> crate::pac::otg::Otg; + fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>; + } +} + +/// USB instance trait. +pub trait Instance: sealed::Instance + RccPeripheral + 'static { + /// Interrupt for this USB instance. + type Interrupt: interrupt::typelevel::Interrupt; +} + +// Internal PHY pins +pin_trait!(DpPin, Instance); +pin_trait!(DmPin, Instance); + +// External PHY pins +pin_trait!(UlpiClkPin, Instance); +pin_trait!(UlpiDirPin, Instance); +pin_trait!(UlpiNxtPin, Instance); +pin_trait!(UlpiStpPin, Instance); +pin_trait!(UlpiD0Pin, Instance); +pin_trait!(UlpiD1Pin, Instance); +pin_trait!(UlpiD2Pin, Instance); +pin_trait!(UlpiD3Pin, Instance); +pin_trait!(UlpiD4Pin, Instance); +pin_trait!(UlpiD5Pin, Instance); +pin_trait!(UlpiD6Pin, Instance); +pin_trait!(UlpiD7Pin, Instance); + +foreach_interrupt!( + (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { + impl sealed::Instance for crate::peripherals::USB_OTG_FS { + const HIGH_SPEED: bool = false; + + cfg_if::cfg_if! { + if #[cfg(stm32f1)] { + const FIFO_DEPTH_WORDS: u16 = 128; + const ENDPOINT_COUNT: usize = 8; + } else if #[cfg(any( + stm32f2, + stm32f401, + stm32f405, + stm32f407, + stm32f411, + stm32f415, + stm32f417, + stm32f427, + stm32f429, + stm32f437, + stm32f439, + ))] { + const FIFO_DEPTH_WORDS: u16 = 320; + const ENDPOINT_COUNT: usize = 4; + } else if #[cfg(any( + stm32f412, + stm32f413, + stm32f423, + stm32f446, + stm32f469, + stm32f479, + stm32f7, + stm32l4, + stm32u5, + ))] { + const FIFO_DEPTH_WORDS: u16 = 320; + const ENDPOINT_COUNT: usize = 6; + } else if #[cfg(stm32g0x1)] { + const FIFO_DEPTH_WORDS: u16 = 512; + const ENDPOINT_COUNT: usize = 8; + } else if #[cfg(stm32h7)] { + const FIFO_DEPTH_WORDS: u16 = 1024; + const ENDPOINT_COUNT: usize = 9; + } else if #[cfg(stm32u5)] { + const FIFO_DEPTH_WORDS: u16 = 320; + const ENDPOINT_COUNT: usize = 6; + } else { + compile_error!("USB_OTG_FS peripheral is not supported by this chip."); + } + } + + fn regs() -> crate::pac::otg::Otg { + crate::pac::USB_OTG_FS + } + + fn state() -> &'static State<MAX_EP_COUNT> { + static STATE: State<MAX_EP_COUNT> = State::new(); + &STATE + } + } + + impl Instance for crate::peripherals::USB_OTG_FS { + type Interrupt = crate::interrupt::typelevel::$irq; + } + }; + + (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { + impl sealed::Instance for crate::peripherals::USB_OTG_HS { + const HIGH_SPEED: bool = true; + + cfg_if::cfg_if! { + if #[cfg(any( + stm32f2, + stm32f405, + stm32f407, + stm32f415, + stm32f417, + stm32f427, + stm32f429, + stm32f437, + stm32f439, + ))] { + const FIFO_DEPTH_WORDS: u16 = 1024; + const ENDPOINT_COUNT: usize = 6; + } else if #[cfg(any( + stm32f446, + stm32f469, + stm32f479, + stm32f7, + stm32h7, + ))] { + const FIFO_DEPTH_WORDS: u16 = 1024; + const ENDPOINT_COUNT: usize = 9; + } else if #[cfg(stm32u5)] { + const FIFO_DEPTH_WORDS: u16 = 1024; + const ENDPOINT_COUNT: usize = 9; + } else { + compile_error!("USB_OTG_HS peripheral is not supported by this chip."); + } + } + + fn regs() -> crate::pac::otg::Otg { + // OTG HS registers are a superset of FS registers + unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } + } + + fn state() -> &'static State<MAX_EP_COUNT> { + static STATE: State<MAX_EP_COUNT> = State::new(); + &STATE + } + } + + impl Instance for crate::peripherals::USB_OTG_HS { + type Interrupt = crate::interrupt::typelevel::$irq; + } + }; +); diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index be321a19b..1fb2c9ebb 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -12,8 +12,6 @@ use embassy_usb_driver::{ Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, }; -use super::{DmPin, DpPin, Instance}; -use crate::interrupt::typelevel::Interrupt; use crate::pac::usb::regs; use crate::pac::usb::vals::{EpType, Stat}; use crate::pac::USBRAM; @@ -259,19 +257,11 @@ impl<'d, T: Instance> Driver<'d, T> { dm: impl Peripheral<P = impl DmPin<T>> + 'd, ) -> Self { into_ref!(dp, dm); - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; + + super::common_init::<T>(); let regs = T::regs(); - #[cfg(any(stm32l4, stm32l5, stm32wb))] - crate::pac::PWR.cr2().modify(|w| w.set_usv(true)); - - #[cfg(pwr_h5)] - crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)); - - <T as RccPeripheral>::enable_and_reset(); - regs.cntr().write(|w| { w.set_pdwn(false); w.set_fres(true); @@ -1057,3 +1047,33 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { }); } } + +pub(crate) mod sealed { + pub trait Instance { + fn regs() -> crate::pac::usb::Usb; + } +} + +/// USB instance trait. +pub trait Instance: sealed::Instance + RccPeripheral + 'static { + /// Interrupt for this USB instance. + type Interrupt: interrupt::typelevel::Interrupt; +} + +// Internal PHY pins +pin_trait!(DpPin, Instance); +pin_trait!(DmPin, Instance); + +foreach_interrupt!( + ($inst:ident, usb, $block:ident, LP, $irq:ident) => { + impl sealed::Instance for crate::peripherals::$inst { + fn regs() -> crate::pac::usb::Usb { + crate::pac::$inst + } + } + + impl Instance for crate::peripherals::$inst { + type Interrupt = crate::interrupt::typelevel::$irq; + } + }; +); diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs deleted file mode 100644 index 0649e684b..000000000 --- a/embassy-stm32/src/usb_otg/mod.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! USB On The Go (OTG) - -use crate::rcc::RccPeripheral; -use crate::{interrupt, peripherals}; - -mod usb; -pub use usb::*; - -// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps -const MAX_EP_COUNT: usize = 9; - -pub(crate) mod sealed { - pub trait Instance { - const HIGH_SPEED: bool; - const FIFO_DEPTH_WORDS: u16; - const ENDPOINT_COUNT: usize; - - fn regs() -> crate::pac::otg::Otg; - fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>; - } -} - -/// USB OTG instance. -pub trait Instance: sealed::Instance + RccPeripheral { - /// Interrupt for this USB OTG instance. - type Interrupt: interrupt::typelevel::Interrupt; -} - -// Internal PHY pins -pin_trait!(DpPin, Instance); -pin_trait!(DmPin, Instance); - -// External PHY pins -pin_trait!(UlpiClkPin, Instance); -pin_trait!(UlpiDirPin, Instance); -pin_trait!(UlpiNxtPin, Instance); -pin_trait!(UlpiStpPin, Instance); -pin_trait!(UlpiD0Pin, Instance); -pin_trait!(UlpiD1Pin, Instance); -pin_trait!(UlpiD2Pin, Instance); -pin_trait!(UlpiD3Pin, Instance); -pin_trait!(UlpiD4Pin, Instance); -pin_trait!(UlpiD5Pin, Instance); -pin_trait!(UlpiD6Pin, Instance); -pin_trait!(UlpiD7Pin, Instance); - -foreach_interrupt!( - (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { - impl sealed::Instance for peripherals::USB_OTG_FS { - const HIGH_SPEED: bool = false; - - cfg_if::cfg_if! { - if #[cfg(stm32f1)] { - const FIFO_DEPTH_WORDS: u16 = 128; - const ENDPOINT_COUNT: usize = 8; - } else if #[cfg(any( - stm32f2, - stm32f401, - stm32f405, - stm32f407, - stm32f411, - stm32f415, - stm32f417, - stm32f427, - stm32f429, - stm32f437, - stm32f439, - ))] { - const FIFO_DEPTH_WORDS: u16 = 320; - const ENDPOINT_COUNT: usize = 4; - } else if #[cfg(any( - stm32f412, - stm32f413, - stm32f423, - stm32f446, - stm32f469, - stm32f479, - stm32f7, - stm32l4, - stm32u5, - ))] { - const FIFO_DEPTH_WORDS: u16 = 320; - const ENDPOINT_COUNT: usize = 6; - } else if #[cfg(stm32g0x1)] { - const FIFO_DEPTH_WORDS: u16 = 512; - const ENDPOINT_COUNT: usize = 8; - } else if #[cfg(stm32h7)] { - const FIFO_DEPTH_WORDS: u16 = 1024; - const ENDPOINT_COUNT: usize = 9; - } else if #[cfg(stm32u5)] { - const FIFO_DEPTH_WORDS: u16 = 320; - const ENDPOINT_COUNT: usize = 6; - } else { - compile_error!("USB_OTG_FS peripheral is not supported by this chip."); - } - } - - fn regs() -> crate::pac::otg::Otg { - crate::pac::USB_OTG_FS - } - - fn state() -> &'static State<MAX_EP_COUNT> { - static STATE: State<MAX_EP_COUNT> = State::new(); - &STATE - } - } - - impl Instance for peripherals::USB_OTG_FS { - type Interrupt = crate::interrupt::typelevel::$irq; - } - }; - - (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { - impl sealed::Instance for peripherals::USB_OTG_HS { - const HIGH_SPEED: bool = true; - - cfg_if::cfg_if! { - if #[cfg(any( - stm32f2, - stm32f405, - stm32f407, - stm32f415, - stm32f417, - stm32f427, - stm32f429, - stm32f437, - stm32f439, - ))] { - const FIFO_DEPTH_WORDS: u16 = 1024; - const ENDPOINT_COUNT: usize = 6; - } else if #[cfg(any( - stm32f446, - stm32f469, - stm32f479, - stm32f7, - stm32h7, - ))] { - const FIFO_DEPTH_WORDS: u16 = 1024; - const ENDPOINT_COUNT: usize = 9; - } else if #[cfg(stm32u5)] { - const FIFO_DEPTH_WORDS: u16 = 1024; - const ENDPOINT_COUNT: usize = 9; - } else { - compile_error!("USB_OTG_HS peripheral is not supported by this chip."); - } - } - - fn regs() -> crate::pac::otg::Otg { - // OTG HS registers are a superset of FS registers - unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } - } - - fn state() -> &'static State<MAX_EP_COUNT> { - static STATE: State<MAX_EP_COUNT> = State::new(); - &STATE - } - } - - impl Instance for peripherals::USB_OTG_HS { - type Interrupt = crate::interrupt::typelevel::$irq; - } - }; -); diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index a196259a8..405cce6bc 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -7,8 +7,8 @@ use embassy_net::tcp::TcpSocket; use embassy_net::{Stack, StackResources}; use embassy_stm32::rng::{self, Rng}; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::Driver; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +use embassy_stm32::usb::Driver; +use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; use embassy_usb::{Builder, UsbDevice}; @@ -36,7 +36,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { } bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; HASH_RNG => rng::InterruptHandler<peripherals::RNG>; }); @@ -63,13 +63,14 @@ async fn main(spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } let p = embassy_stm32::init(config); // Create the driver, from the HAL. static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; - let mut config = embassy_stm32::usb_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index 19b5971fb..6c25a0a64 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs @@ -8,8 +8,8 @@ use embassy_executor::Spawner; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::Pull; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::Driver; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +use embassy_stm32::usb::Driver; +use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Handler}; @@ -18,7 +18,7 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -42,12 +42,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs index c98792880..d4725d597 100644 --- a/examples/stm32f4/src/bin/usb_hid_mouse.rs +++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs @@ -4,8 +4,8 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::Driver; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +use embassy_stm32::usb::Driver; +use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; @@ -15,7 +15,7 @@ use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index afff55187..15a98ff8b 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -52,8 +52,8 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::Driver; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +use embassy_stm32::usb::Driver; +use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; use embassy_usb::msos::{self, windows_version}; use embassy_usb::types::InterfaceNumber; @@ -66,7 +66,7 @@ use {defmt_rtt as _, panic_probe as _}; const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -92,12 +92,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 58d994a61..6080b34a8 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -4,8 +4,8 @@ use defmt::{panic, *}; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +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; @@ -13,7 +13,7 @@ use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 97daf6bd1..26ecf3bc8 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -4,8 +4,8 @@ use defmt::{panic, *}; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; -use embassy_stm32::usb_otg::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +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; @@ -13,7 +13,7 @@ use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index d81efb541..c3ddda72a 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -3,8 +3,8 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::usb_otg::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +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; @@ -12,7 +12,7 @@ use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -40,12 +40,13 @@ async fn main(_spawner: Spawner) { config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.voltage_scale = VoltageScale::Scale1; + config.rcc.mux.usbsel = mux::Usbsel::HSI48; } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 9247e56a1..047234d60 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -4,9 +4,8 @@ use defmt::{panic, *}; use defmt_rtt as _; // global logger use embassy_executor::Spawner; -use embassy_stm32::rcc::*; -use embassy_stm32::usb_otg::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +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; @@ -14,7 +13,7 @@ use futures::future::join; use panic_probe as _; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -22,23 +21,26 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB - config.rcc.sys = Sysclk::PLL1_R; - config.rcc.hsi = true; - config.rcc.pll = Some(Pll { - source: PllSource::HSI, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL10, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) - }); - + { + use embassy_stm32::rcc::*; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) + }); + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; + } 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = true; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index f6d8b16d0..dc1e7022d 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -5,7 +5,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_net::tcp::TcpSocket; use embassy_net::{Stack, StackResources}; -use embassy_stm32::rcc::*; use embassy_stm32::rng::Rng; use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; @@ -44,17 +43,22 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi = true; - config.rcc.sys = Sysclk::PLL1_R; - config.rcc.pll = Some(Pll { - // 80Mhz clock (16 / 1 * 10 / 2) - source: PllSource::HSI, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL10, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), - }); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = true; + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PllSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index c51ed96e0..b86fba455 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -4,7 +4,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_stm32::rcc::*; use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_time::Timer; @@ -21,17 +20,22 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi = true; - config.rcc.sys = Sysclk::PLL1_R; - config.rcc.pll = Some(Pll { - // 80Mhz clock (16 / 1 * 10 / 2) - source: PllSource::HSI, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL10, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), - }); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = true; + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PllSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 87987f2ce..5e2378b58 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -4,7 +4,6 @@ use defmt::{panic, *}; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_stm32::rcc::*; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; @@ -19,17 +18,22 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi = true; - config.rcc.sys = Sysclk::PLL1_R; - config.rcc.pll = Some(Pll { - // 80Mhz clock (16 / 1 * 10 / 2) - source: PllSource::HSI, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL10, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), - }); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = true; + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PllSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 61851e5a2..33e02ce3b 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -4,8 +4,8 @@ use defmt::{panic, *}; use defmt_rtt as _; // global logger use embassy_executor::Spawner; -use embassy_stm32::usb_otg::{Driver, Instance}; -use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +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; @@ -13,7 +13,7 @@ use futures::future::join; use panic_probe as _; bind_interrupts!(struct Irqs { - OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; + OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); #[embassy_executor::main] @@ -35,13 +35,14 @@ async fn main(_spawner: Spawner) { 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_otg::Config::default(); + let mut config = embassy_stm32::usb::Config::default(); config.vbus_detection = false; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);