diff --git a/Cargo.toml b/Cargo.toml index 8e02f57..4cc3196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,52 +12,19 @@ keywords = ["no-std", "embedded", "usb"] [dependencies] vcell = "0.1.2" cortex-m = "0.6.1" -stm32f0xx-hal = { version = "0.15", features = ["rt"], optional = true } -stm32f1xx-hal = { version = "0.4", features = ["rt"], optional = true } -stm32f3xx-hal = { version = "0.3", features = ["rt"], optional = true } -stm32l0xx-hal = { version = "0.3", features = ["rt"], optional = true } -stm32l4xx-hal = { version = "0.5", features = ["rt"], optional = true } usb-device = "0.2.3" -[features] -# Device family -stm32f0 = ['stm32f0xx-hal', 'family-selected'] -stm32f1 = ['stm32f1xx-hal', 'family-selected'] -stm32f3 = ['stm32f3xx-hal', 'family-selected'] -stm32l0 = ['stm32l0xx-hal', 'family-selected'] -stm32l4 = ['stm32l4xx-hal', 'family-selected'] - -# Dedicated USB RAM size -ram_size_512 = [] -ram_size_1024 = [] +[dev-dependencies] +stm32f1xx-hal = { version = "0.4.0", features = ["stm32f103"] } +[features] # USB RAM access scheme ram_access_1x16 = [] ram_access_2x16 = [] -# USB peripheral features -lpm_support = [] -bcd_support = [] -dp_pull_up_support = [] - -# Hacks -ram_addr_40006c00 = [] -delay_workaround = [] # deprecated: cortex-m 0.6.1 contains a fix - -# Known devices -stm32f042xx = ['stm32f0', 'stm32f0xx-hal/stm32f042', 'new_gen'] -stm32f048xx = ['stm32f0', 'stm32f0xx-hal/stm32f048', 'new_gen'] -stm32f072xx = ['stm32f0', 'stm32f0xx-hal/stm32f072', 'new_gen'] -stm32f078xx = ['stm32f0', 'stm32f0xx-hal/stm32f078', 'new_gen'] -stm32f103xx = ['stm32f1', 'stm32f1xx-hal/stm32f103', 'old_gen'] -stm32f303xc = ['stm32f3', 'stm32f3xx-hal/stm32f303', 'old_gen'] -stm32l0x2xx = ['stm32l0', 'stm32l0xx-hal/stm32l0x2', 'new_gen'] -stm32l4x2xx = ['stm32l4', 'stm32l4xx-hal/stm32l4x2', 'new_gen', 'ram_addr_40006c00'] - -# Auxiliary features -old_gen = ['ram_size_512', 'ram_access_1x16'] -new_gen = ['ram_size_1024', 'ram_access_2x16', 'lpm_support', 'bcd_support', 'dp_pull_up_support'] -family-selected = [] - [package.metadata.docs.rs] -features = ["stm32f103xx"] +features = ["ram_access_2x16"] + +[[example]] +name = "hal" +required-features = ["ram_access_1x16"] diff --git a/README.md b/README.md index 607b01f..bbf6647 100644 --- a/README.md +++ b/README.md @@ -21,57 +21,18 @@ This repository is a fork of the [mvirkkunen/stm32f103xx-usb](https://github.com * `STM32L4x2xx` * And others... -## Feature flags +## Usage -To use this crate you need to set proper feature flags. -All the feature flags are listed in `Cargo.toml` under different sections. - -If your target MCU matches one of the feature flags listed under the -`Known devices` section of `Cargo.toml`, you can use just that feature flag. For example: - -```toml -[dependencies] -stm32-usbd = { version = "0.3", features = ["stm32f103xx"] } -``` - -For other cases, you have to figure out different properties -of your MCU and USB peripheral implemented in it. -Each property has a corresponding feature flag that you should -set to indicate that property. - -Device family: -* `stm32f0` -* `stm32f1` -* `stm32f3` -* `stm32l0` -* `stm32l4` - -Size of dedicated packet buffer memory SRAM: -* `ram_size_512` -* `ram_size_1024` - -Dedicated packet buffer memory SRAM access scheme: +This driver is intended for use through a device hal library. +Such hal library should implement `UsbPeripheral` for the corresponding USB peripheral object. +This trait declares all the peripheral properties that may vary from one device family to the other. +Additionally, hal should pass `ram_access_1x16` of `ram_access_2x16` feature to the `stm32-usbd` library to +define endpoint memory access scheme: * `ram_access_1x16` - for "1x16 bits/word" access scheme * `ram_access_2x16` - for "2x16 bits/word" access scheme -USB peripheral features: -* `lpm_support` - USB 2.0 Link Power Management (LPM) support -* `bcd_support` - Battery Charging Detection (BCD) support -* `dp_pull_up_support` - Embedded pull-up resistor on USB_DP line - -Various hacks: -* `ram_addr_40006c00` if dedicated SRAM address is equal to `0x4000_6c00` -instead of `0x4000_6000` - -```toml -[dependencies] -# An example feature set for STM32F303CB MCU -stm32-usbd = { version = "0.3", features = ["stm32f3", "ram_size_512", "ram_access_1x16"] } -stm32f3xx-hal = { version = "0.1.4", features = ["rt", "stm32f3xx-hal/stm32f303"] } -``` - -Note that you also need to set the device feature for `stm32*-hal` crate. - ## Examples See the [stm32-usbd-examples](https://github.com/stm32-rs/stm32-usbd-examples) repo for different device-specific examples. + +See the `hal` example for the reference hal implementation. diff --git a/ci/script.sh b/ci/script.sh index 20869be..83d549a 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -2,11 +2,6 @@ set -euxo pipefail -cargo check --no-default-features --features stm32f042xx -#cargo check --no-default-features --features stm32f048xx -#cargo check --no-default-features --features stm32f072xx -#cargo check --no-default-features --features stm32f078xx -cargo check --no-default-features --features stm32f103xx -cargo check --no-default-features --features stm32f303xc -cargo check --no-default-features --features stm32l0x2xx -cargo check --no-default-features --features stm32l4x2xx +cargo check --features ram_access_1x16 +cargo check --features ram_access_2x16 +cargo check --example hal --features ram_access_1x16 diff --git a/examples/hal.rs b/examples/hal.rs new file mode 100644 index 0000000..833cb8a --- /dev/null +++ b/examples/hal.rs @@ -0,0 +1,48 @@ +//! USB peripheral + +use stm32_usbd::UsbPeripheral; +use stm32f1xx_hal::pac::{RCC, USB}; + +pub use stm32_usbd::UsbBus; +use stm32f1xx_hal::gpio::gpioa::{PA11, PA12}; +use stm32f1xx_hal::gpio::{Floating, Input}; + +pub struct Peripheral { + pub usb: USB, + pub pin_dm: PA11>, + pub pin_dp: PA12>, +} + +unsafe impl Sync for Peripheral {} + +unsafe impl UsbPeripheral for Peripheral { + const REGISTERS: *const () = USB::ptr() as *const (); + const DP_PULL_UP_FEATURE: bool = false; + const EP_MEMORY: *const () = 0x4000_6000 as _; + const EP_MEMORY_SIZE: usize = 512; + + fn enable() { + let rcc = unsafe { (&*RCC::ptr()) }; + + cortex_m::interrupt::free(|_| { + // Enable USB peripheral + rcc.apb1enr.modify(|_, w| w.usben().set_bit()); + + // Reset USB peripheral + rcc.apb1rstr.modify(|_, w| w.usbrst().set_bit()); + rcc.apb1rstr.modify(|_, w| w.usbrst().clear_bit()); + }); + } + + fn startup_delay() { + // There is a chip specific startup delay. For STM32F103xx it's 1µs and this should wait for + // at least that long. + cortex_m::asm::delay(72); + } +} + +pub type UsbBusType = UsbBus; + +fn main() -> ! { + loop {} +} diff --git a/src/bus.rs b/src/bus.rs index 5edde03..931f916 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,50 +1,54 @@ //! USB peripheral driver. -use core::marker::PhantomData; -use core::mem; -use cortex_m::asm::delay; +use core::mem::{self, MaybeUninit}; use cortex_m::interrupt::{self, Mutex}; use usb_device::bus::{PollResult, UsbBusAllocator}; use usb_device::endpoint::{EndpointAddress, EndpointType}; use usb_device::{Result, UsbDirection, UsbError}; -use crate::endpoint::{calculate_count_rx, Endpoint, EndpointStatus}; +use crate::endpoint::{calculate_count_rx, Endpoint, EndpointStatus, NUM_ENDPOINTS}; use crate::endpoint_memory::EndpointMemoryAllocator; -use crate::target::{apb_usb_enable, UsbPins, UsbRegisters, NUM_ENDPOINTS, USB}; +use crate::registers::UsbRegisters; +use crate::UsbPeripheral; /// USB peripheral driver for STM32 microcontrollers. -pub struct UsbBus { - regs: Mutex, - endpoints: [Endpoint; NUM_ENDPOINTS], - ep_allocator: EndpointMemoryAllocator, +pub struct UsbBus { + peripheral: USB, + regs: Mutex>, + endpoints: [Endpoint; NUM_ENDPOINTS], + ep_allocator: EndpointMemoryAllocator, max_endpoint: usize, - pins: PhantomData, } -impl UsbBus { +impl UsbBus { /// Constructs a new USB peripheral driver. - pub fn new(regs: USB, _pins: PINS) -> UsbBusAllocator { - apb_usb_enable(); + pub fn new(peripheral: USB) -> UsbBusAllocator { + USB::enable(); let bus = UsbBus { - regs: Mutex::new(UsbRegisters::new(regs)), + peripheral, + regs: Mutex::new(UsbRegisters::new()), ep_allocator: EndpointMemoryAllocator::new(), max_endpoint: 0, - endpoints: unsafe { - let mut endpoints: [Endpoint; NUM_ENDPOINTS] = mem::uninitialized(); + endpoints: { + let mut endpoints: [MaybeUninit>; NUM_ENDPOINTS] = + unsafe { MaybeUninit::uninit().assume_init() }; for i in 0..NUM_ENDPOINTS { - endpoints[i] = Endpoint::new(i as u8); + endpoints[i] = MaybeUninit::new(Endpoint::new(i as u8)); } - endpoints + unsafe { mem::transmute::<_, [Endpoint; NUM_ENDPOINTS]>(endpoints) } }, - pins: PhantomData, }; UsbBusAllocator::new(bus) } + pub fn free(self) -> USB { + self.peripheral + } + /// Simulates a disconnect from the USB bus, causing the host to reset and re-enumerate the /// device. /// @@ -69,7 +73,7 @@ impl UsbBus { } } -impl usb_device::bus::UsbBus for UsbBus { +impl usb_device::bus::UsbBus for UsbBus { fn alloc_ep( &mut self, ep_dir: UsbDirection, @@ -136,9 +140,7 @@ impl usb_device::bus::UsbBus for UsbBus { regs.cntr.modify(|_, w| w.pdwn().clear_bit()); - // There is a chip specific startup delay. For STM32F103xx it's 1µs and this should wait for - // at least that long. - delay(72); + USB::startup_delay(); regs.btable.modify(|_, w| w.btable().bits(0)); regs.cntr.modify(|_, w| { w @@ -150,8 +152,9 @@ impl usb_device::bus::UsbBus for UsbBus { }); regs.istr.modify(|_, w| unsafe { w.bits(0) }); - #[cfg(feature = "dp_pull_up_support")] - regs.bcdr.modify(|_, w| w.dppu().set_bit()); + if USB::DP_PULL_UP_FEATURE { + regs.bcdr.modify(|_, w| w.dppu().set_bit()); + } }); } diff --git a/src/endpoint.rs b/src/endpoint.rs index 8d2aa34..22ed60f 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -1,17 +1,27 @@ -use crate::endpoint_memory::{BufferDescriptor, EndpointBuffer, EndpointMemoryAllocator}; -use crate::target::{usb, UsbAccessType, UsbRegisters}; +use crate::endpoint_memory::{BufferDescriptor, EndpointBuffer, EndpointMemoryAllocator, UsbAccessType}; +use crate::registers::UsbRegisters; +use crate::UsbPeripheral; +use core::marker::PhantomData; use core::mem; use cortex_m::interrupt::{self, CriticalSection, Mutex}; use usb_device::endpoint::EndpointType; use usb_device::{Result, UsbError}; +// Use bundled register definitions instead of device-specific ones +// This should work because register definitions from newer chips seem to be +// compatible with definitions for older ones. +pub use crate::pac::usb; + +pub const NUM_ENDPOINTS: usize = 8; + /// Arbitrates access to the endpoint-specific registers and packet buffer memory. #[derive(Default)] -pub struct Endpoint { +pub struct Endpoint { out_buf: Option>, in_buf: Option>, ep_type: Option, index: u8, + _marker: PhantomData, } pub fn calculate_count_rx(mut size: usize) -> Result<(usize, u16)> { @@ -34,13 +44,14 @@ pub fn calculate_count_rx(mut size: usize) -> Result<(usize, u16)> { } } -impl Endpoint { - pub fn new(index: u8) -> Endpoint { - Endpoint { +impl Endpoint { + pub fn new(index: u8) -> Self { + Self { out_buf: None, in_buf: None, ep_type: None, index, + _marker: PhantomData, } } @@ -57,7 +68,7 @@ impl Endpoint { } pub fn set_out_buf(&mut self, buffer: EndpointBuffer, size_bits: u16) { - let offset = buffer.offset(); + let offset = buffer.offset::(); self.out_buf = Some(Mutex::new(buffer)); let descr = self.descr(); @@ -70,7 +81,7 @@ impl Endpoint { } pub fn set_in_buf(&mut self, buffer: EndpointBuffer) { - let offset = buffer.offset(); + let offset = buffer.offset::(); self.in_buf = Some(Mutex::new(buffer)); let descr = self.descr(); @@ -79,11 +90,11 @@ impl Endpoint { } fn descr(&self) -> &'static BufferDescriptor { - EndpointMemoryAllocator::buffer_descriptor(self.index) + EndpointMemoryAllocator::::buffer_descriptor(self.index) } fn reg(&self) -> &'static usb::EPR { - UsbRegisters::ep_register(self.index) + UsbRegisters::::ep_register(self.index) } #[rustfmt::skip] diff --git a/src/endpoint_memory.rs b/src/endpoint_memory.rs index e96b540..ea62f86 100644 --- a/src/endpoint_memory.rs +++ b/src/endpoint_memory.rs @@ -1,16 +1,23 @@ -use crate::target::{UsbAccessType, EP_MEM_ADDR, EP_MEM_SIZE, NUM_ENDPOINTS}; +use crate::endpoint::NUM_ENDPOINTS; +use crate::UsbPeripheral; +use core::marker::PhantomData; use core::{mem, slice}; use usb_device::{Result, UsbError}; use vcell::VolatileCell; -const EP_MEM_PTR: *mut VolatileCell = EP_MEM_ADDR as *mut VolatileCell; +#[cfg(feature = "ram_access_1x16")] +pub type UsbAccessType = u32; +#[cfg(feature = "ram_access_2x16")] +pub type UsbAccessType = u16; pub struct EndpointBuffer(&'static mut [VolatileCell]); impl EndpointBuffer { - pub fn new(offset_bytes: usize, size_bytes: usize) -> Self { + pub fn new(offset_bytes: usize, size_bytes: usize) -> Self { + let ep_mem_ptr = USB::EP_MEMORY as *mut VolatileCell; + let mem = - unsafe { slice::from_raw_parts_mut(EP_MEM_PTR.offset((offset_bytes >> 1) as isize), size_bytes >> 1) }; + unsafe { slice::from_raw_parts_mut(ep_mem_ptr.offset((offset_bytes >> 1) as isize), size_bytes >> 1) }; Self(mem) } @@ -59,9 +66,9 @@ impl EndpointBuffer { } } - pub fn offset(&self) -> usize { + pub fn offset(&self) -> usize { let buffer_address = self.0.as_ptr() as usize; - let index = (buffer_address - EP_MEM_ADDR) / mem::size_of::(); + let index = (buffer_address - USB::EP_MEMORY as usize) / mem::size_of::(); index << 1 } @@ -78,32 +85,34 @@ pub struct BufferDescriptor { pub count_rx: VolatileCell, } -pub struct EndpointMemoryAllocator { +pub struct EndpointMemoryAllocator { next_free_offset: usize, + _marker: PhantomData, } -impl EndpointMemoryAllocator { +impl EndpointMemoryAllocator { pub fn new() -> Self { Self { next_free_offset: NUM_ENDPOINTS * 8, + _marker: PhantomData, } } pub fn allocate_buffer(&mut self, size: usize) -> Result { - assert!(size & 1 == 0); - assert!(size < EP_MEM_SIZE); + assert_eq!(size & 1, 0); + assert!(size < USB::EP_MEMORY_SIZE); let offset = self.next_free_offset; - if offset as usize + size > EP_MEM_SIZE { + if offset as usize + size > USB::EP_MEMORY_SIZE { return Err(UsbError::EndpointMemoryOverflow); } self.next_free_offset += size; - Ok(EndpointBuffer::new(offset, size)) + Ok(EndpointBuffer::new::(offset, size)) } pub fn buffer_descriptor(index: u8) -> &'static BufferDescriptor { - unsafe { &*(EP_MEM_ADDR as *const BufferDescriptor).offset(index as isize) } + unsafe { &*(USB::EP_MEMORY as *const BufferDescriptor).offset(index as isize) } } } diff --git a/src/lib.rs b/src/lib.rs index 5bd5692..8836c22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,29 +5,41 @@ #![no_std] -#[cfg(not(feature = "family-selected"))] -compile_error!( - "This crate requires one of the device family features enabled. -Check Cargo.toml for supported families ('Device family' section)" -); +#[cfg(not(any(feature = "ram_access_1x16", feature = "ram_access_2x16")))] +compile_error!("This crate requires one of the ram_access features enabled"); +#[cfg(all(feature = "ram_access_1x16", feature = "ram_access_2x16"))] +compile_error!("Multiple ram_access features are specified. Only a single feature can be specified."); -#[cfg(feature = "family-selected")] +pub mod bus; mod endpoint; - -#[cfg(feature = "family-selected")] mod endpoint_memory; +mod registers; +pub use crate::bus::UsbBus; -#[cfg(feature = "family-selected")] -mod target; +mod pac; -#[cfg(feature = "family-selected")] -pub mod bus; +/// A trait for device-specific USB peripherals. Implement this to add support for a new hardware +/// platform. Peripherals that have this trait must have the same register block as STM32 USBFS +/// peripherals. +pub unsafe trait UsbPeripheral: Send + Sync { + /// Pointer to the register block + const REGISTERS: *const (); -#[cfg(feature = "family-selected")] -pub use crate::bus::UsbBus; -#[cfg(feature = "family-selected")] -pub use crate::target::usb_pins::UsbPinsType; -#[cfg(feature = "family-selected")] -pub type UsbBusType = UsbBus; + /// Embedded pull-up resistor on USB_DP line + const DP_PULL_UP_FEATURE: bool; -mod pac; + /// Pointer to the endpoint memory + const EP_MEMORY: *const (); + + /// Endpoint memory size in bytes + const EP_MEMORY_SIZE: usize; + + /// Enables USB device on its peripheral bus + fn enable(); + + /// Performs a chip specific startup delay + /// + /// This function is called in `UsbBus::enable()` after deasserting the `pdwn` bit and before + /// peripheral initialization. + fn startup_delay(); +} diff --git a/src/registers.rs b/src/registers.rs new file mode 100644 index 0000000..5df40c9 --- /dev/null +++ b/src/registers.rs @@ -0,0 +1,28 @@ +use crate::pac::usb::{RegisterBlock, EPR}; +use crate::UsbPeripheral; +use core::marker::PhantomData; + +/// A proxy type that provides unified register interface +pub struct UsbRegisters { + _marker: PhantomData, +} + +impl core::ops::Deref for UsbRegisters { + type Target = RegisterBlock; + + fn deref(&self) -> &Self::Target { + let ptr = USB::REGISTERS as *const Self::Target; + unsafe { &*ptr } + } +} + +impl UsbRegisters { + pub fn new() -> Self { + Self { _marker: PhantomData } + } + + pub fn ep_register(index: u8) -> &'static EPR { + let usb_ptr = USB::REGISTERS as *const RegisterBlock; + unsafe { &(*usb_ptr).epr[index as usize] } + } +} diff --git a/src/target.rs b/src/target.rs deleted file mode 100644 index e493fcb..0000000 --- a/src/target.rs +++ /dev/null @@ -1,133 +0,0 @@ -//! Target-specific definitions - -// Export HAL -#[cfg(feature = "stm32f0")] -pub use stm32f0xx_hal as hal; -#[cfg(feature = "stm32f1")] -pub use stm32f1xx_hal as hal; -#[cfg(feature = "stm32f3")] -pub use stm32f3xx_hal as hal; -#[cfg(feature = "stm32l0")] -pub use stm32l0xx_hal as hal; -#[cfg(feature = "stm32l4")] -pub use stm32l4xx_hal as hal; - -// USB PAC reexports -#[cfg(feature = "stm32f0")] -pub use hal::stm32::USB; -#[cfg(feature = "stm32f1")] -pub use hal::stm32::USB; -#[cfg(feature = "stm32f3")] -pub use hal::stm32::USB; -#[cfg(feature = "stm32l0")] -pub use hal::stm32::USB; -#[cfg(feature = "stm32l4")] -pub use hal::stm32::USB; - -// Use bundled register definitions instead of device-specific ones -// This should work because register definitions from newer chips seem to be -// compatible with definitions for older ones. -pub use crate::pac::usb; - -#[cfg(feature = "ram_access_1x16")] -pub type UsbAccessType = u32; -#[cfg(feature = "ram_access_2x16")] -pub type UsbAccessType = u16; - -#[cfg(not(feature = "ram_addr_40006c00"))] -pub const EP_MEM_ADDR: usize = 0x4000_6000; -#[cfg(feature = "ram_addr_40006c00")] -pub const EP_MEM_ADDR: usize = 0x4000_6C00; - -#[cfg(feature = "ram_size_512")] -pub const EP_MEM_SIZE: usize = 512; -#[cfg(feature = "ram_size_1024")] -pub const EP_MEM_SIZE: usize = 1024; - -pub const NUM_ENDPOINTS: usize = 8; - -/// Enables USB peripheral -pub fn apb_usb_enable() { - cortex_m::interrupt::free(|_| { - let rcc = unsafe { (&*hal::stm32::RCC::ptr()) }; - match () { - #[cfg(any(feature = "stm32f0", feature = "stm32f1", feature = "stm32f3", feature = "stm32l0"))] - () => rcc.apb1enr.modify(|_, w| w.usben().set_bit()), - #[cfg(feature = "stm32l4")] - () => rcc.apb1enr1.modify(|_, w| w.usbfsen().set_bit()), - } - }); -} - -/// Wrapper around device-specific peripheral that provides unified register interface -pub struct UsbRegisters(USB); - -impl core::ops::Deref for UsbRegisters { - type Target = usb::RegisterBlock; - - fn deref(&self) -> &Self::Target { - let ptr = USB::ptr() as *const Self::Target; - unsafe { &*ptr } - } -} - -impl UsbRegisters { - pub fn new(usb: USB) -> Self { - Self(usb) - } - - pub fn ep_register(index: u8) -> &'static usb::EPR { - let usb_ptr = USB::ptr() as *const usb::RegisterBlock; - unsafe { &(*usb_ptr).epr[index as usize] } - } -} - -pub trait UsbPins: Send {} - -#[cfg(feature = "stm32f0")] -pub mod usb_pins { - use super::hal::gpio::gpioa::{PA11, PA12}; - use super::hal::gpio::{Floating, Input}; - - pub type UsbPinsType = (PA11>, PA12>); - impl super::UsbPins for UsbPinsType {} -} - -#[cfg(feature = "stm32f1")] -pub mod usb_pins { - use super::hal::gpio::gpioa::{PA11, PA12}; - use super::hal::gpio::{Floating, Input}; - - pub type UsbPinsType = (PA11>, PA12>); - impl super::UsbPins for UsbPinsType {} -} - -#[cfg(feature = "stm32f3")] -pub mod usb_pins { - use super::hal::gpio::gpioa::{PA11, PA12}; - use super::hal::gpio::AF14; - - pub type UsbPinsType = (PA11, PA12); - impl super::UsbPins for UsbPinsType {} -} - -#[cfg(feature = "stm32l0")] -pub mod usb_pins { - use super::hal::gpio::gpioa::{PA11, PA12}; - use super::hal::gpio::{Floating, Input}; - - pub type UsbPinsType = (PA11>, PA12>); - impl super::UsbPins for UsbPinsType {} -} - -#[cfg(feature = "stm32l4")] -pub mod usb_pins { - use super::hal::gpio::gpioa::{PA11, PA12}; - use super::hal::gpio::{Alternate, Floating, Input, AF10}; - - pub type UsbPinsType = ( - PA11>>, - PA12>>, - ); - impl super::UsbPins for UsbPinsType {} -}