diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index ddfa97b2..dbfc1370 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -277,22 +277,20 @@ fn main() { (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), (("usb", "DP"), quote!(crate::usb::DpPin)), (("usb", "DM"), quote!(crate::usb::DmPin)), - (("otgfs", "DP"), quote!(crate::usb_otg::DpPin)), - (("otgfs", "DM"), quote!(crate::usb_otg::DmPin)), - (("otghs", "DP"), quote!(crate::usb_otg::DpPin)), - (("otghs", "DM"), quote!(crate::usb_otg::DmPin)), - (("otghs", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)), - (("otghs", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)), - (("otghs", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)), - (("otghs", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)), - (("otghs", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)), - (("otghs", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)), - (("otghs", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)), - (("otghs", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)), - (("otghs", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)), - (("otghs", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)), - (("otghs", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)), - (("otghs", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)), + (("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)), (("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 16c46ca2..610c2488 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -58,7 +58,7 @@ pub mod spi; pub mod usart; #[cfg(all(usb, feature = "time"))] pub mod usb; -#[cfg(any(otgfs, otghs))] +#[cfg(otg)] pub mod usb_otg; #[cfg(iwdg)] diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 062c7ef7..03e792a2 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -154,6 +154,7 @@ impl<'d, T: Instance> Driver<'d, T> { block_for(Duration::from_millis(100)); + #[cfg(not(usb_v4))] regs.btable().write(|w| w.set_btable(0)); dp.set_as_af(dp.af_num(), AFType::OutputPushPull); diff --git a/embassy-stm32/src/usb_otg.rs b/embassy-stm32/src/usb_otg.rs deleted file mode 100644 index f7faf12a..00000000 --- a/embassy-stm32/src/usb_otg.rs +++ /dev/null @@ -1,213 +0,0 @@ -use core::marker::PhantomData; - -use embassy_hal_common::into_ref; - -use crate::gpio::sealed::AFType; -use crate::rcc::RccPeripheral; -use crate::{peripherals, Peripheral}; - -macro_rules! config_ulpi_pins { - ($($pin:ident),*) => { - into_ref!($($pin),*); - // NOTE(unsafe) Exclusive access to the registers - critical_section::with(|_| unsafe { - $( - $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); - #[cfg(gpio_v2)] - $pin.set_speed(crate::gpio::Speed::VeryHigh); - )* - }) - }; -} - -/// USB PHY type -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PhyType { - /// Internal Full-Speed PHY - /// - /// Available on most High-Speed peripherals. - InternalFullSpeed, - /// Internal High-Speed PHY - /// - /// Available on a few STM32 chips. - InternalHighSpeed, - /// External ULPI High-Speed PHY - ExternalHighSpeed, -} - -pub struct UsbOtg<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, - _phy_type: PhyType, -} - -impl<'d, T: Instance> UsbOtg<'d, T> { - /// Initializes USB OTG peripheral with internal Full-Speed PHY - pub fn new_fs( - _peri: impl Peripheral

+ 'd, - dp: impl Peripheral

> + 'd, - dm: impl Peripheral

> + 'd, - ) -> Self { - into_ref!(dp, dm); - - unsafe { - dp.set_as_af(dp.af_num(), AFType::OutputPushPull); - dm.set_as_af(dm.af_num(), AFType::OutputPushPull); - } - - Self { - phantom: PhantomData, - _phy_type: PhyType::InternalFullSpeed, - } - } - - /// Initializes USB OTG peripheral with external High-Speed PHY - pub fn new_hs_ulpi( - _peri: impl Peripheral

+ 'd, - ulpi_clk: impl Peripheral

> + 'd, - ulpi_dir: impl Peripheral

> + 'd, - ulpi_nxt: impl Peripheral

> + 'd, - ulpi_stp: impl Peripheral

> + 'd, - ulpi_d0: impl Peripheral

> + 'd, - ulpi_d1: impl Peripheral

> + 'd, - ulpi_d2: impl Peripheral

> + 'd, - ulpi_d3: impl Peripheral

> + 'd, - ulpi_d4: impl Peripheral

> + 'd, - ulpi_d5: impl Peripheral

> + 'd, - ulpi_d6: impl Peripheral

> + 'd, - ulpi_d7: impl Peripheral

> + 'd, - ) -> Self { - config_ulpi_pins!( - ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, - ulpi_d7 - ); - - Self { - phantom: PhantomData, - _phy_type: PhyType::ExternalHighSpeed, - } - } -} - -impl<'d, T: Instance> Drop for UsbOtg<'d, T> { - fn drop(&mut self) { - T::reset(); - T::disable(); - } -} - -pub(crate) mod sealed { - pub trait Instance { - const REGISTERS: *const (); - const HIGH_SPEED: bool; - const FIFO_DEPTH_WORDS: usize; - const ENDPOINT_COUNT: usize; - } -} - -pub trait Instance: sealed::Instance + RccPeripheral {} - -// 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_peripheral!( - (otgfs, $inst:ident) => { - impl sealed::Instance for peripherals::$inst { - const REGISTERS: *const () = crate::pac::$inst.0 as *const (); - const HIGH_SPEED: bool = false; - - cfg_if::cfg_if! { - if #[cfg(stm32f1)] { - const FIFO_DEPTH_WORDS: usize = 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: usize = 320; - const ENDPOINT_COUNT: usize = 4; - } else if #[cfg(any( - stm32f412, - stm32f413, - stm32f423, - stm32f446, - stm32f469, - stm32f479, - stm32f7, - stm32l4, - stm32u5, - ))] { - const FIFO_DEPTH_WORDS: usize = 320; - const ENDPOINT_COUNT: usize = 6; - } else if #[cfg(stm32g0x1)] { - const FIFO_DEPTH_WORDS: usize = 512; - const ENDPOINT_COUNT: usize = 8; - } else { - compile_error!("USB_OTG_FS peripheral is not supported by this chip."); - } - } - } - - impl Instance for peripherals::$inst {} - }; - - (otghs, $inst:ident) => { - impl sealed::Instance for peripherals::$inst { - const REGISTERS: *const () = crate::pac::$inst.0 as *const (); - 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: usize = 1024; - const ENDPOINT_COUNT: usize = 6; - } else if #[cfg(any( - stm32f446, - stm32f469, - stm32f479, - stm32f7, - stm32h7, - ))] { - const FIFO_DEPTH_WORDS: usize = 1024; - const ENDPOINT_COUNT: usize = 9; - } else { - compile_error!("USB_OTG_HS peripheral is not supported by this chip."); - } - } - } - - impl Instance for peripherals::$inst {} - }; -); diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs new file mode 100644 index 00000000..2ee2891d --- /dev/null +++ b/embassy-stm32/src/usb_otg/mod.rs @@ -0,0 +1,138 @@ +use embassy_cortex_m::interrupt::Interrupt; + +use crate::peripherals; +use crate::rcc::RccPeripheral; + +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; + } +} + +pub trait Instance: sealed::Instance + RccPeripheral { + type Interrupt: 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 { + compile_error!("USB_OTG_FS peripheral is not supported by this chip."); + } + } + + fn regs() -> crate::pac::otg::Otg { + crate::pac::USB_OTG_FS + } + } + + impl Instance for peripherals::USB_OTG_FS { + type Interrupt = crate::interrupt::$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 { + 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 + crate::pac::otg::Otg(crate::pac::USB_OTG_HS.0) + } + } + + impl Instance for peripherals::USB_OTG_HS { + type Interrupt = crate::interrupt::$irq; + } + }; +); diff --git a/stm32-data b/stm32-data index 14a448c3..844793fc 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit 14a448c318192fe9da1c95a4de1beb4ec4892f1c +Subproject commit 844793fc3da2ba3f12ab6a69b78cd8e6fb5497b4