From 7f7c14b7bce5b84eb27c8122535a96a6f0e5dd77 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Sep 2022 12:29:27 +0200 Subject: [PATCH 1/3] usb: split driver trait to separate crate. --- embassy-nrf/src/usb.rs | 17 +-- embassy-rp/src/usb.rs | 27 ++--- embassy-stm32/src/usb/usb.rs | 35 +++--- embassy-usb-driver/Cargo.toml | 16 +++ .../src/lib.rs | 107 +++++++++++++++++- embassy-usb/Cargo.toml | 4 + embassy-usb/src/builder.rs | 11 +- embassy-usb/src/control.rs | 5 +- embassy-usb/src/descriptor.rs | 7 +- embassy-usb/src/descriptor_reader.rs | 2 +- embassy-usb/src/lib.rs | 18 +-- embassy-usb/src/types.rs | 105 ----------------- 12 files changed, 189 insertions(+), 165 deletions(-) create mode 100644 embassy-usb-driver/Cargo.toml rename embassy-usb/src/driver.rs => embassy-usb-driver/src/lib.rs (72%) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 0685d419..20510eb4 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -10,8 +10,9 @@ use cortex_m::peripheral::NVIC; use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; pub use embassy_usb; -use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; -use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; +use embassy_usb::driver::{ + self, Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, +}; use pac::usbd::RegisterBlock; use crate::interrupt::{Interrupt, InterruptExt}; @@ -243,7 +244,7 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P> interval: u8, ) -> Result { let index = self.alloc_in.allocate(ep_type)?; - let ep_addr = EndpointAddress::from_parts(index, UsbDirection::In); + let ep_addr = EndpointAddress::from_parts(index, Direction::In); Ok(Endpoint::new(EndpointInfo { addr: ep_addr, ep_type, @@ -259,7 +260,7 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P> interval: u8, ) -> Result { let index = self.alloc_out.allocate(ep_type)?; - let ep_addr = EndpointAddress::from_parts(index, UsbDirection::Out); + let ep_addr = EndpointAddress::from_parts(index, Direction::Out); Ok(Endpoint::new(EndpointInfo { addr: ep_addr, ep_type, @@ -428,8 +429,8 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> { let regs = T::regs(); let i = ep_addr.index(); match ep_addr.direction() { - UsbDirection::Out => regs.halted.epout[i].read().getstatus().is_halted(), - UsbDirection::In => regs.halted.epin[i].read().getstatus().is_halted(), + Direction::Out => regs.halted.epout[i].read().getstatus().is_halted(), + Direction::In => regs.halted.epin[i].read().getstatus().is_halted(), } } @@ -442,7 +443,7 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> { debug!("endpoint_set_enabled {:?} {}", ep_addr, enabled); match ep_addr.direction() { - UsbDirection::In => { + Direction::In => { let mut was_enabled = false; regs.epinen.modify(|r, w| { let mut bits = r.bits(); @@ -466,7 +467,7 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> { In::waker(i).wake(); } - UsbDirection::Out => { + Direction::Out => { regs.epouten.modify(|r, w| { let mut bits = r.bits(); if enabled { diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index a7ec5fb7..ce473b21 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs @@ -7,8 +7,9 @@ use core::task::Poll; use atomic_polyfill::compiler_fence; use embassy_hal_common::into_ref; use embassy_sync::waitqueue::AtomicWaker; -use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported}; -use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; +use embassy_usb::driver::{ + self, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, +}; use crate::interrupt::{Interrupt, InterruptExt}; use crate::{pac, peripherals, Peripheral, RegExt}; @@ -204,8 +205,8 @@ impl<'d, T: Instance> Driver<'d, T> { ); let alloc = match D::dir() { - UsbDirection::Out => &mut self.ep_out, - UsbDirection::In => &mut self.ep_in, + Direction::Out => &mut self.ep_out, + Direction::In => &mut self.ep_in, }; let index = alloc.iter_mut().enumerate().find(|(i, ep)| { @@ -254,7 +255,7 @@ impl<'d, T: Instance> Driver<'d, T> { }; match D::dir() { - UsbDirection::Out => unsafe { + Direction::Out => unsafe { T::dpram().ep_out_control(index - 1).write(|w| { w.set_enable(false); w.set_buffer_address(addr); @@ -262,7 +263,7 @@ impl<'d, T: Instance> Driver<'d, T> { w.set_endpoint_type(ep_type_reg); }) }, - UsbDirection::In => unsafe { + Direction::In => unsafe { T::dpram().ep_in_control(index - 1).write(|w| { w.set_enable(false); w.set_buffer_address(addr); @@ -429,14 +430,14 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { let n = ep_addr.index(); match ep_addr.direction() { - UsbDirection::In => unsafe { + Direction::In => unsafe { T::dpram().ep_in_control(n - 1).modify(|w| w.set_enable(enabled)); T::dpram().ep_in_buffer_control(ep_addr.index()).write(|w| { w.set_pid(0, true); // first packet is DATA0, but PID is flipped before }); EP_IN_WAKERS[n].wake(); }, - UsbDirection::Out => unsafe { + Direction::Out => unsafe { T::dpram().ep_out_control(n - 1).modify(|w| w.set_enable(enabled)); T::dpram().ep_out_buffer_control(ep_addr.index()).write(|w| { @@ -474,14 +475,14 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { } trait Dir { - fn dir() -> UsbDirection; + fn dir() -> Direction; fn waker(i: usize) -> &'static AtomicWaker; } pub enum In {} impl Dir for In { - fn dir() -> UsbDirection { - UsbDirection::In + fn dir() -> Direction { + Direction::In } #[inline] @@ -492,8 +493,8 @@ impl Dir for In { pub enum Out {} impl Dir for Out { - fn dir() -> UsbDirection { - UsbDirection::Out + fn dir() -> Direction { + Direction::Out } #[inline] diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index e5ee1181..39809a3e 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -9,8 +9,9 @@ use atomic_polyfill::{AtomicBool, AtomicU8}; use embassy_hal_common::into_ref; use embassy_sync::waitqueue::AtomicWaker; use embassy_time::{block_for, Duration}; -use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported}; -use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; +use embassy_usb::driver::{ + self, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, +}; use pac::common::{Reg, RW}; use pac::usb::vals::{EpType, Stat}; @@ -279,8 +280,8 @@ impl<'d, T: Instance> Driver<'d, T> { } let used = ep.used_out || ep.used_in; let used_dir = match D::dir() { - UsbDirection::Out => ep.used_out, - UsbDirection::In => ep.used_in, + Direction::Out => ep.used_out, + Direction::In => ep.used_in, }; !used || (ep.ep_type == ep_type && !used_dir) }); @@ -293,7 +294,7 @@ impl<'d, T: Instance> Driver<'d, T> { ep.ep_type = ep_type; let buf = match D::dir() { - UsbDirection::Out => { + Direction::Out => { assert!(!ep.used_out); ep.used_out = true; @@ -312,7 +313,7 @@ impl<'d, T: Instance> Driver<'d, T> { _phantom: PhantomData, } } - UsbDirection::In => { + Direction::In => { assert!(!ep.used_in); ep.used_in = true; @@ -504,7 +505,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { // This can race, so do a retry loop. let reg = T::regs().epr(ep_addr.index() as _); match ep_addr.direction() { - UsbDirection::In => { + Direction::In => { loop { let r = unsafe { reg.read() }; match r.stat_tx() { @@ -523,7 +524,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { } EP_IN_WAKERS[ep_addr.index()].wake(); } - UsbDirection::Out => { + Direction::Out => { loop { let r = unsafe { reg.read() }; match r.stat_rx() { @@ -549,8 +550,8 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { let regs = T::regs(); let epr = unsafe { regs.epr(ep_addr.index() as _).read() }; match ep_addr.direction() { - UsbDirection::In => epr.stat_tx() == Stat::STALL, - UsbDirection::Out => epr.stat_rx() == Stat::STALL, + Direction::In => epr.stat_tx() == Stat::STALL, + Direction::Out => epr.stat_rx() == Stat::STALL, } } @@ -560,7 +561,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { let reg = T::regs().epr(ep_addr.index() as _); trace!("EPR before: {:04x}", unsafe { reg.read() }.0); match ep_addr.direction() { - UsbDirection::In => { + Direction::In => { loop { let want_stat = match enabled { false => Stat::DISABLED, @@ -576,7 +577,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { } EP_IN_WAKERS[ep_addr.index()].wake(); } - UsbDirection::Out => { + Direction::Out => { loop { let want_stat = match enabled { false => Stat::DISABLED, @@ -616,14 +617,14 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { } trait Dir { - fn dir() -> UsbDirection; + fn dir() -> Direction; fn waker(i: usize) -> &'static AtomicWaker; } pub enum In {} impl Dir for In { - fn dir() -> UsbDirection { - UsbDirection::In + fn dir() -> Direction { + Direction::In } #[inline] @@ -634,8 +635,8 @@ impl Dir for In { pub enum Out {} impl Dir for Out { - fn dir() -> UsbDirection { - UsbDirection::Out + fn dir() -> Direction { + Direction::Out } #[inline] diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml new file mode 100644 index 00000000..b525df33 --- /dev/null +++ b/embassy-usb-driver/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "embassy-usb-driver" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[package.metadata.embassy_docs] +src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-driver-v$VERSION/embassy-usb/src/" +src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-driver/src/" +features = ["defmt"] +target = "thumbv7em-none-eabi" + +[dependencies] +defmt = { version = "0.3", optional = true } +log = { version = "0.4.14", optional = true } \ No newline at end of file diff --git a/embassy-usb/src/driver.rs b/embassy-usb-driver/src/lib.rs similarity index 72% rename from embassy-usb/src/driver.rs rename to embassy-usb-driver/src/lib.rs index 7888f163..051190a4 100644 --- a/embassy-usb/src/driver.rs +++ b/embassy-usb-driver/src/lib.rs @@ -1,6 +1,111 @@ +#![no_std] + use core::future::Future; -use super::types::*; +/// Direction of USB traffic. Note that in the USB standard the direction is always indicated from +/// the perspective of the host, which is backward for devices, but the standard directions are used +/// for consistency. +/// +/// The values of the enum also match the direction bit used in endpoint addresses and control +/// request types. +#[repr(u8)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Direction { + /// Host to device (OUT) + Out = 0x00, + /// Device to host (IN) + In = 0x80, +} + +impl From for Direction { + fn from(value: u8) -> Self { + unsafe { core::mem::transmute(value & 0x80) } + } +} + +/// USB endpoint transfer type. The values of this enum can be directly cast into `u8` to get the +/// transfer bmAttributes transfer type bits. +#[repr(u8)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum EndpointType { + /// Control endpoint. Used for device management. Only the host can initiate requests. Usually + /// used only endpoint 0. + Control = 0b00, + /// Isochronous endpoint. Used for time-critical unreliable data. Not implemented yet. + Isochronous = 0b01, + /// Bulk endpoint. Used for large amounts of best-effort reliable data. + Bulk = 0b10, + /// Interrupt endpoint. Used for small amounts of time-critical reliable data. + Interrupt = 0b11, +} + +/// Type-safe endpoint address. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct EndpointAddress(u8); + +impl From for EndpointAddress { + #[inline] + fn from(addr: u8) -> EndpointAddress { + EndpointAddress(addr) + } +} + +impl From for u8 { + #[inline] + fn from(addr: EndpointAddress) -> u8 { + addr.0 + } +} + +impl EndpointAddress { + const INBITS: u8 = Direction::In as u8; + + /// Constructs a new EndpointAddress with the given index and direction. + #[inline] + pub fn from_parts(index: usize, dir: Direction) -> Self { + EndpointAddress(index as u8 | dir as u8) + } + + /// Gets the direction part of the address. + #[inline] + pub fn direction(&self) -> Direction { + if (self.0 & Self::INBITS) != 0 { + Direction::In + } else { + Direction::Out + } + } + + /// Returns true if the direction is IN, otherwise false. + #[inline] + pub fn is_in(&self) -> bool { + (self.0 & Self::INBITS) != 0 + } + + /// Returns true if the direction is OUT, otherwise false. + #[inline] + pub fn is_out(&self) -> bool { + (self.0 & Self::INBITS) == 0 + } + + /// Gets the index part of the endpoint address. + #[inline] + pub fn index(&self) -> usize { + (self.0 & !Self::INBITS) as usize + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct EndpointInfo { + pub addr: EndpointAddress, + pub ep_type: EndpointType, + pub max_packet_size: u16, + pub interval: u8, +} /// Driver for a specific USB peripheral. Implement this to add support for a new hardware /// platform. diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 8cad4d31..660ecc8c 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -9,8 +9,12 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb/s features = ["defmt"] target = "thumbv7em-none-eabi" +[features] +defmt = ["dep:defmt", "embassy-usb-driver/defmt"] + [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } +embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 6be88bc7..87a8333b 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -1,11 +1,10 @@ use heapless::Vec; -use super::control::ControlHandler; -use super::descriptor::{BosWriter, DescriptorWriter}; -use super::driver::{Driver, Endpoint}; -use super::types::*; -use super::{DeviceStateHandler, UsbDevice, MAX_INTERFACE_COUNT}; -use crate::{Interface, STRING_INDEX_CUSTOM_START}; +use crate::control::ControlHandler; +use crate::descriptor::{BosWriter, DescriptorWriter}; +use crate::driver::{Driver, Endpoint, EndpointType}; +use crate::types::*; +use crate::{DeviceStateHandler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 3e5749a0..9e0dee88 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -1,7 +1,8 @@ //! USB control data types. use core::mem; -use super::types::*; +use crate::driver::Direction; +use crate::types::StringIndex; /// Control request type. #[repr(u8)] @@ -42,7 +43,7 @@ pub enum Recipient { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Request { /// Direction of the request. - pub direction: UsbDirection, + pub direction: Direction, /// Type of the request. pub request_type: RequestType, /// Recipient of the request. diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index b94a4b16..497f0319 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -1,6 +1,7 @@ -use super::builder::Config; -use super::types::*; -use super::CONFIGURATION_VALUE; +use crate::builder::Config; +use crate::driver::EndpointInfo; +use crate::types::*; +use crate::CONFIGURATION_VALUE; /// Standard descriptor types #[allow(missing_docs)] diff --git a/embassy-usb/src/descriptor_reader.rs b/embassy-usb/src/descriptor_reader.rs index 0a12b566..d64bcb73 100644 --- a/embassy-usb/src/descriptor_reader.rs +++ b/embassy-usb/src/descriptor_reader.rs @@ -1,5 +1,5 @@ use crate::descriptor::descriptor_type; -use crate::types::EndpointAddress; +use crate::driver::EndpointAddress; #[derive(Copy, Clone, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 6f58c953..e1a99cfa 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -4,23 +4,23 @@ // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; +pub use embassy_usb_driver as driver; + mod builder; pub mod control; pub mod descriptor; mod descriptor_reader; -pub mod driver; pub mod types; use embassy_futures::select::{select, Either}; use heapless::Vec; -pub use self::builder::{Builder, Config}; -use self::control::*; -use self::descriptor::*; -use self::driver::{Bus, Driver, Event}; -use self::types::*; +pub use crate::builder::{Builder, Config}; +use crate::control::*; +use crate::descriptor::*; use crate::descriptor_reader::foreach_endpoint; -use crate::driver::ControlPipe; +use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; +use crate::types::*; /// The global state of the USB device. /// @@ -250,8 +250,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { trace!("control request: {:?}", req); match req.direction { - UsbDirection::In => self.handle_control_in(req).await, - UsbDirection::Out => self.handle_control_out(req).await, + Direction::In => self.handle_control_in(req).await, + Direction::Out => self.handle_control_out(req).await, } if self.inner.set_address_pending { diff --git a/embassy-usb/src/types.rs b/embassy-usb/src/types.rs index b8717ffa..aeab063d 100644 --- a/embassy-usb/src/types.rs +++ b/embassy-usb/src/types.rs @@ -1,108 +1,3 @@ -/// Direction of USB traffic. Note that in the USB standard the direction is always indicated from -/// the perspective of the host, which is backward for devices, but the standard directions are used -/// for consistency. -/// -/// The values of the enum also match the direction bit used in endpoint addresses and control -/// request types. -#[repr(u8)] -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum UsbDirection { - /// Host to device (OUT) - Out = 0x00, - /// Device to host (IN) - In = 0x80, -} - -impl From for UsbDirection { - fn from(value: u8) -> Self { - unsafe { core::mem::transmute(value & 0x80) } - } -} - -/// USB endpoint transfer type. The values of this enum can be directly cast into `u8` to get the -/// transfer bmAttributes transfer type bits. -#[repr(u8)] -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum EndpointType { - /// Control endpoint. Used for device management. Only the host can initiate requests. Usually - /// used only endpoint 0. - Control = 0b00, - /// Isochronous endpoint. Used for time-critical unreliable data. Not implemented yet. - Isochronous = 0b01, - /// Bulk endpoint. Used for large amounts of best-effort reliable data. - Bulk = 0b10, - /// Interrupt endpoint. Used for small amounts of time-critical reliable data. - Interrupt = 0b11, -} - -/// Type-safe endpoint address. -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct EndpointAddress(u8); - -impl From for EndpointAddress { - #[inline] - fn from(addr: u8) -> EndpointAddress { - EndpointAddress(addr) - } -} - -impl From for u8 { - #[inline] - fn from(addr: EndpointAddress) -> u8 { - addr.0 - } -} - -impl EndpointAddress { - const INBITS: u8 = UsbDirection::In as u8; - - /// Constructs a new EndpointAddress with the given index and direction. - #[inline] - pub fn from_parts(index: usize, dir: UsbDirection) -> Self { - EndpointAddress(index as u8 | dir as u8) - } - - /// Gets the direction part of the address. - #[inline] - pub fn direction(&self) -> UsbDirection { - if (self.0 & Self::INBITS) != 0 { - UsbDirection::In - } else { - UsbDirection::Out - } - } - - /// Returns true if the direction is IN, otherwise false. - #[inline] - pub fn is_in(&self) -> bool { - (self.0 & Self::INBITS) != 0 - } - - /// Returns true if the direction is OUT, otherwise false. - #[inline] - pub fn is_out(&self) -> bool { - (self.0 & Self::INBITS) == 0 - } - - /// Gets the index part of the endpoint address. - #[inline] - pub fn index(&self) -> usize { - (self.0 & !Self::INBITS) as usize - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct EndpointInfo { - pub addr: EndpointAddress, - pub ep_type: EndpointType, - pub max_packet_size: u16, - pub interval: u8, -} - /// A handle for a USB interface that contains its number. #[derive(Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] From f4f58249722bc656a13865e06535d208440c3e4a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Sep 2022 12:35:33 +0200 Subject: [PATCH 2/3] usb: do not allow converting Directon to/from u8 --- embassy-usb-driver/src/lib.rs | 11 ++--------- embassy-usb/src/control.rs | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/embassy-usb-driver/src/lib.rs b/embassy-usb-driver/src/lib.rs index 051190a4..fc29786f 100644 --- a/embassy-usb-driver/src/lib.rs +++ b/embassy-usb-driver/src/lib.rs @@ -8,20 +8,13 @@ use core::future::Future; /// /// The values of the enum also match the direction bit used in endpoint addresses and control /// request types. -#[repr(u8)] #[derive(Copy, Clone, Eq, PartialEq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Direction { /// Host to device (OUT) - Out = 0x00, + Out, /// Device to host (IN) - In = 0x80, -} - -impl From for Direction { - fn from(value: u8) -> Self { - unsafe { core::mem::transmute(value & 0x80) } - } + In, } /// USB endpoint transfer type. The values of this enum can be directly cast into `u8` to get the diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 9e0dee88..d6d0c656 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -106,7 +106,7 @@ impl Request { let recipient = rt & 0b11111; Request { - direction: rt.into(), + direction: if rt & 0x80 == 0 { Direction::Out } else { Direction::In }, request_type: unsafe { mem::transmute((rt >> 5) & 0b11) }, recipient: if recipient <= 3 { unsafe { mem::transmute(recipient) } From f27a47a37b59bf3b9079f4d4d5f43caf7b7872f8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Sep 2022 13:00:21 +0200 Subject: [PATCH 3/3] usb: move classes into the `embassy-usb` crate. --- embassy-usb-hid/Cargo.toml | 24 -- embassy-usb-hid/src/fmt.rs | 225 ------------------ embassy-usb-ncm/Cargo.toml | 17 -- embassy-usb-ncm/src/fmt.rs | 225 ------------------ embassy-usb-serial/Cargo.toml | 17 -- embassy-usb-serial/src/fmt.rs | 225 ------------------ embassy-usb/Cargo.toml | 9 +- .../src/class/cdc_acm.rs | 15 +- .../src/class/cdc_ncm.rs | 13 +- .../lib.rs => embassy-usb/src/class/hid.rs | 23 +- embassy-usb/src/class/mod.rs | 3 + embassy-usb/src/lib.rs | 1 + examples/nrf/Cargo.toml | 5 +- examples/nrf/src/bin/usb_ethernet.rs | 2 +- examples/nrf/src/bin/usb_hid_keyboard.rs | 4 +- examples/nrf/src/bin/usb_hid_mouse.rs | 4 +- examples/nrf/src/bin/usb_serial.rs | 2 +- examples/nrf/src/bin/usb_serial_multitask.rs | 2 +- examples/rp/Cargo.toml | 2 - examples/rp/src/bin/usb_ethernet.rs | 2 +- examples/rp/src/bin/usb_serial.rs | 2 +- examples/stm32f1/Cargo.toml | 1 - examples/stm32f1/src/bin/usb_serial.rs | 2 +- examples/stm32f3/Cargo.toml | 2 - examples/stm32f3/src/bin/usb_serial.rs | 2 +- examples/stm32l5/Cargo.toml | 3 - examples/stm32l5/src/bin/usb_ethernet.rs | 2 +- examples/stm32l5/src/bin/usb_hid_mouse.rs | 4 +- examples/stm32l5/src/bin/usb_serial.rs | 2 +- 29 files changed, 45 insertions(+), 795 deletions(-) delete mode 100644 embassy-usb-hid/Cargo.toml delete mode 100644 embassy-usb-hid/src/fmt.rs delete mode 100644 embassy-usb-ncm/Cargo.toml delete mode 100644 embassy-usb-ncm/src/fmt.rs delete mode 100644 embassy-usb-serial/Cargo.toml delete mode 100644 embassy-usb-serial/src/fmt.rs rename embassy-usb-serial/src/lib.rs => embassy-usb/src/class/cdc_acm.rs (96%) rename embassy-usb-ncm/src/lib.rs => embassy-usb/src/class/cdc_ncm.rs (97%) rename embassy-usb-hid/src/lib.rs => embassy-usb/src/class/hid.rs (96%) create mode 100644 embassy-usb/src/class/mod.rs diff --git a/embassy-usb-hid/Cargo.toml b/embassy-usb-hid/Cargo.toml deleted file mode 100644 index 2f7733dc..00000000 --- a/embassy-usb-hid/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "embassy-usb-hid" -version = "0.1.0" -edition = "2021" - -[package.metadata.embassy_docs] -src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-hid-v$VERSION/embassy-usb-hid/src/" -src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-hid/src/" -features = ["defmt"] -target = "thumbv7em-none-eabi" - -[features] -default = ["usbd-hid"] -usbd-hid = ["dep:usbd-hid", "ssmarshal"] - -[dependencies] -embassy-sync = { version = "0.1.0", path = "../embassy-sync" } -embassy-usb = { version = "0.1.0", path = "../embassy-usb" } - -defmt = { version = "0.3", optional = true } -log = { version = "0.4.14", optional = true } -usbd-hid = { version = "0.6.0", optional = true } -ssmarshal = { version = "1.0", default-features = false, optional = true } -futures-util = { version = "0.3.21", default-features = false } diff --git a/embassy-usb-hid/src/fmt.rs b/embassy-usb-hid/src/fmt.rs deleted file mode 100644 index 06697081..00000000 --- a/embassy-usb-hid/src/fmt.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![macro_use] -#![allow(unused_macros)] - -#[cfg(all(feature = "defmt", feature = "log"))] -compile_error!("You may not enable both `defmt` and `log` features."); - -macro_rules! assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); - } - }; -} - -macro_rules! assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); - } - }; -} - -macro_rules! assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); - } - }; -} - -macro_rules! debug_assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); - } - }; -} - -macro_rules! debug_assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); - } - }; -} - -macro_rules! debug_assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); - } - }; -} - -macro_rules! todo { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); - } - }; -} - -macro_rules! unreachable { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); - } - }; -} - -macro_rules! panic { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); - } - }; -} - -macro_rules! trace { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! debug { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! info { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! warn { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! error { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -#[cfg(feature = "defmt")] -macro_rules! unwrap { - ($($x:tt)*) => { - ::defmt::unwrap!($($x)*) - }; -} - -#[cfg(not(feature = "defmt"))] -macro_rules! unwrap { - ($arg:expr) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); - } - } - }; - ($arg:expr, $($msg:expr),+ $(,)? ) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); - } - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct NoneError; - -pub trait Try { - type Ok; - type Error; - fn into_result(self) -> Result; -} - -impl Try for Option { - type Ok = T; - type Error = NoneError; - - #[inline] - fn into_result(self) -> Result { - self.ok_or(NoneError) - } -} - -impl Try for Result { - type Ok = T; - type Error = E; - - #[inline] - fn into_result(self) -> Self { - self - } -} diff --git a/embassy-usb-ncm/Cargo.toml b/embassy-usb-ncm/Cargo.toml deleted file mode 100644 index 15d3db96..00000000 --- a/embassy-usb-ncm/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "embassy-usb-ncm" -version = "0.1.0" -edition = "2021" - -[package.metadata.embassy_docs] -src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-ncm-v$VERSION/embassy-usb-ncm/src/" -src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-ncm/src/" -features = ["defmt"] -target = "thumbv7em-none-eabi" - -[dependencies] -embassy-sync = { version = "0.1.0", path = "../embassy-sync" } -embassy-usb = { version = "0.1.0", path = "../embassy-usb" } - -defmt = { version = "0.3", optional = true } -log = { version = "0.4.14", optional = true } diff --git a/embassy-usb-ncm/src/fmt.rs b/embassy-usb-ncm/src/fmt.rs deleted file mode 100644 index 06697081..00000000 --- a/embassy-usb-ncm/src/fmt.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![macro_use] -#![allow(unused_macros)] - -#[cfg(all(feature = "defmt", feature = "log"))] -compile_error!("You may not enable both `defmt` and `log` features."); - -macro_rules! assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); - } - }; -} - -macro_rules! assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); - } - }; -} - -macro_rules! assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); - } - }; -} - -macro_rules! debug_assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); - } - }; -} - -macro_rules! debug_assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); - } - }; -} - -macro_rules! debug_assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); - } - }; -} - -macro_rules! todo { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); - } - }; -} - -macro_rules! unreachable { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); - } - }; -} - -macro_rules! panic { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); - } - }; -} - -macro_rules! trace { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! debug { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! info { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! warn { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! error { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -#[cfg(feature = "defmt")] -macro_rules! unwrap { - ($($x:tt)*) => { - ::defmt::unwrap!($($x)*) - }; -} - -#[cfg(not(feature = "defmt"))] -macro_rules! unwrap { - ($arg:expr) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); - } - } - }; - ($arg:expr, $($msg:expr),+ $(,)? ) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); - } - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct NoneError; - -pub trait Try { - type Ok; - type Error; - fn into_result(self) -> Result; -} - -impl Try for Option { - type Ok = T; - type Error = NoneError; - - #[inline] - fn into_result(self) -> Result { - self.ok_or(NoneError) - } -} - -impl Try for Result { - type Ok = T; - type Error = E; - - #[inline] - fn into_result(self) -> Self { - self - } -} diff --git a/embassy-usb-serial/Cargo.toml b/embassy-usb-serial/Cargo.toml deleted file mode 100644 index 9788588e..00000000 --- a/embassy-usb-serial/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "embassy-usb-serial" -version = "0.1.0" -edition = "2021" - -[package.metadata.embassy_docs] -src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-serial-v$VERSION/embassy-usb-serial/src/" -src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-serial/src/" -features = ["defmt"] -target = "thumbv7em-none-eabi" - -[dependencies] -embassy-sync = { version = "0.1.0", path = "../embassy-sync" } -embassy-usb = { version = "0.1.0", path = "../embassy-usb" } - -defmt = { version = "0.3", optional = true } -log = { version = "0.4.14", optional = true } diff --git a/embassy-usb-serial/src/fmt.rs b/embassy-usb-serial/src/fmt.rs deleted file mode 100644 index 06697081..00000000 --- a/embassy-usb-serial/src/fmt.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![macro_use] -#![allow(unused_macros)] - -#[cfg(all(feature = "defmt", feature = "log"))] -compile_error!("You may not enable both `defmt` and `log` features."); - -macro_rules! assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); - } - }; -} - -macro_rules! assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); - } - }; -} - -macro_rules! assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); - } - }; -} - -macro_rules! debug_assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); - } - }; -} - -macro_rules! debug_assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); - } - }; -} - -macro_rules! debug_assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); - } - }; -} - -macro_rules! todo { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); - } - }; -} - -macro_rules! unreachable { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); - } - }; -} - -macro_rules! panic { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); - } - }; -} - -macro_rules! trace { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! debug { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! info { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! warn { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! error { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -#[cfg(feature = "defmt")] -macro_rules! unwrap { - ($($x:tt)*) => { - ::defmt::unwrap!($($x)*) - }; -} - -#[cfg(not(feature = "defmt"))] -macro_rules! unwrap { - ($arg:expr) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); - } - } - }; - ($arg:expr, $($msg:expr),+ $(,)? ) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); - } - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct NoneError; - -pub trait Try { - type Ok; - type Error; - fn into_result(self) -> Result; -} - -impl Try for Option { - type Ok = T; - type Error = NoneError; - - #[inline] - fn into_result(self) -> Result { - self.ok_or(NoneError) - } -} - -impl Try for Result { - type Ok = T; - type Error = E; - - #[inline] - fn into_result(self) -> Self { - self - } -} diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 660ecc8c..aad54dba 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -11,11 +11,18 @@ target = "thumbv7em-none-eabi" [features] defmt = ["dep:defmt", "embassy-usb-driver/defmt"] +usbd-hid = ["dep:usbd-hid", "dep:ssmarshal"] +default = ["usbd-hid"] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } +embassy-sync = { version = "0.1.0", path = "../embassy-sync" } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -heapless = "0.7.10" \ No newline at end of file +heapless = "0.7.10" + +# for HID +usbd-hid = { version = "0.6.0", optional = true } +ssmarshal = { version = "1.0", default-features = false, optional = true } diff --git a/embassy-usb-serial/src/lib.rs b/embassy-usb/src/class/cdc_acm.rs similarity index 96% rename from embassy-usb-serial/src/lib.rs rename to embassy-usb/src/class/cdc_acm.rs index 15c2bb0a..09bb1cc8 100644 --- a/embassy-usb-serial/src/lib.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -1,18 +1,13 @@ -#![no_std] -#![feature(type_alias_impl_trait)] - -// This mod MUST go first, so that the others see its macros. -pub(crate) mod fmt; - use core::cell::Cell; use core::mem::{self, MaybeUninit}; use core::sync::atomic::{AtomicBool, Ordering}; use embassy_sync::blocking_mutex::CriticalSectionMutex; -use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request}; -use embassy_usb::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use embassy_usb::types::*; -use embassy_usb::Builder; + +use crate::control::{self, ControlHandler, InResponse, OutResponse, Request}; +use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; +use crate::types::*; +use crate::Builder; /// This should be used as `device_class` when building the `UsbDevice`. pub const USB_CLASS_CDC: u8 = 0x02; diff --git a/embassy-usb-ncm/src/lib.rs b/embassy-usb/src/class/cdc_ncm.rs similarity index 97% rename from embassy-usb-ncm/src/lib.rs rename to embassy-usb/src/class/cdc_ncm.rs index e796af28..a39b87e9 100644 --- a/embassy-usb-ncm/src/lib.rs +++ b/embassy-usb/src/class/cdc_ncm.rs @@ -1,15 +1,10 @@ -#![no_std] - -// This mod MUST go first, so that the others see its macros. -pub(crate) mod fmt; - use core::intrinsics::copy_nonoverlapping; use core::mem::{size_of, MaybeUninit}; -use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request}; -use embassy_usb::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use embassy_usb::types::*; -use embassy_usb::Builder; +use crate::control::{self, ControlHandler, InResponse, OutResponse, Request}; +use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; +use crate::types::*; +use crate::Builder; /// This should be used as `device_class` when building the `UsbDevice`. pub const USB_CLASS_CDC: u8 = 0x02; diff --git a/embassy-usb-hid/src/lib.rs b/embassy-usb/src/class/hid.rs similarity index 96% rename from embassy-usb-hid/src/lib.rs rename to embassy-usb/src/class/hid.rs index 8b181aec..4d1fa995 100644 --- a/embassy-usb-hid/src/lib.rs +++ b/embassy-usb/src/class/hid.rs @@ -1,23 +1,16 @@ -#![no_std] -#![feature(type_alias_impl_trait)] - -//! Implements HID functionality for a usb-device device. - -// This mod MUST go first, so that the others see its macros. -pub(crate) mod fmt; - use core::mem::MaybeUninit; use core::ops::Range; use core::sync::atomic::{AtomicUsize, Ordering}; -use embassy_usb::control::{ControlHandler, InResponse, OutResponse, Request, RequestType}; -use embassy_usb::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use embassy_usb::Builder; #[cfg(feature = "usbd-hid")] use ssmarshal::serialize; #[cfg(feature = "usbd-hid")] use usbd_hid::descriptor::AsInputReport; +use crate::control::{ControlHandler, InResponse, OutResponse, Request, RequestType}; +use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; +use crate::Builder; + const USB_CLASS_HID: u8 = 0x03; const USB_SUBCLASS_NONE: u8 = 0x00; const USB_PROTOCOL_NONE: u8 = 0x00; @@ -204,9 +197,9 @@ pub enum ReadError { Sync(Range), } -impl From for ReadError { - fn from(val: embassy_usb::driver::EndpointError) -> Self { - use embassy_usb::driver::EndpointError::*; +impl From for ReadError { + fn from(val: EndpointError) -> Self { + use EndpointError::*; match val { BufferOverflow => ReadError::BufferOverflow, Disabled => ReadError::Disabled, @@ -437,7 +430,7 @@ impl<'d> ControlHandler for Control<'d> { } } - fn control_out(&mut self, req: embassy_usb::control::Request, data: &[u8]) -> OutResponse { + fn control_out(&mut self, req: Request, data: &[u8]) -> OutResponse { trace!("HID control_out {:?} {=[u8]:x}", req, data); if let RequestType::Class = req.request_type { match req.request { diff --git a/embassy-usb/src/class/mod.rs b/embassy-usb/src/class/mod.rs new file mode 100644 index 00000000..af27577a --- /dev/null +++ b/embassy-usb/src/class/mod.rs @@ -0,0 +1,3 @@ +pub mod cdc_acm; +pub mod cdc_ncm; +pub mod hid; diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index e1a99cfa..661b8411 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -7,6 +7,7 @@ pub(crate) mod fmt; pub use embassy_usb_driver as driver; mod builder; +pub mod class; pub mod control; pub mod descriptor; mod descriptor_reader; diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index dbc659cd..a5d340c6 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" [features] default = ["nightly"] -nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net"] +nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embedded-io/async", "embassy-net"] [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } @@ -15,9 +15,6 @@ embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["de embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true } -embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"], optional = true } -embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"], optional = true } -embassy-usb-ncm = { version = "0.1.0", path = "../../embassy-usb-ncm", features = ["defmt"], optional = true } embedded-io = "0.3.0" defmt = "0.3" diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs index 33ca380f..de93a2b4 100644 --- a/examples/nrf/src/bin/usb_ethernet.rs +++ b/examples/nrf/src/bin/usb_ethernet.rs @@ -15,8 +15,8 @@ use embassy_nrf::usb::{Driver, PowerUsb}; use embassy_nrf::{interrupt, pac, peripherals}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; +use embassy_usb::class::cdc_ncm::{CdcNcmClass, Receiver, Sender, State}; use embassy_usb::{Builder, Config, UsbDevice}; -use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; use embedded_io::asynch::Write; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs index 4eb7d37c..76e19871 100644 --- a/examples/nrf/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf/src/bin/usb_hid_keyboard.rs @@ -14,9 +14,9 @@ use embassy_nrf::usb::{Driver, PowerUsb}; use embassy_nrf::{interrupt, pac}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::signal::Signal; +use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config, DeviceStateHandler}; -use embassy_usb_hid::{HidReaderWriter, ReportId, RequestHandler, State}; use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { ); // Create classes on the builder. - let config = embassy_usb_hid::Config { + let config = embassy_usb::class::hid::Config { report_descriptor: KeyboardReport::desc(), request_handler: Some(&request_handler), poll_ms: 60, diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs index 65fbda1c..4916a38d 100644 --- a/examples/nrf/src/bin/usb_hid_mouse.rs +++ b/examples/nrf/src/bin/usb_hid_mouse.rs @@ -10,9 +10,9 @@ use embassy_futures::join::join; use embassy_nrf::usb::{Driver, PowerUsb}; use embassy_nrf::{interrupt, pac}; use embassy_time::{Duration, Timer}; +use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config}; -use embassy_usb_hid::{HidWriter, ReportId, RequestHandler, State}; use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; @@ -59,7 +59,7 @@ async fn main(_spawner: Spawner) { ); // Create classes on the builder. - let config = embassy_usb_hid::Config { + let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), request_handler: Some(&request_handler), poll_ms: 60, diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs index a740b4e0..7c9c4184 100644 --- a/examples/nrf/src/bin/usb_serial.rs +++ b/examples/nrf/src/bin/usb_serial.rs @@ -9,9 +9,9 @@ use embassy_executor::Spawner; use embassy_futures::join::join; use embassy_nrf::usb::{Driver, Instance, PowerUsb, UsbSupply}; use embassy_nrf::{interrupt, pac}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::{Builder, Config}; -use embassy_usb_serial::{CdcAcmClass, State}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs index c646c0bb..93efc2fe 100644 --- a/examples/nrf/src/bin/usb_serial_multitask.rs +++ b/examples/nrf/src/bin/usb_serial_multitask.rs @@ -8,9 +8,9 @@ use defmt::{info, panic, unwrap}; use embassy_executor::Spawner; use embassy_nrf::usb::{Driver, PowerUsb}; use embassy_nrf::{interrupt, pac, peripherals}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::{Builder, Config, UsbDevice}; -use embassy_usb_serial::{CdcAcmClass, State}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 24c3cdd6..3c8f923e 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -10,9 +10,7 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] } -embassy-usb-ncm = { version = "0.1.0", path = "../../embassy-usb-ncm", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index 166ffe17..1057fe7f 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -13,8 +13,8 @@ use embassy_rp::usb::Driver; use embassy_rp::{interrupt, peripherals}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; +use embassy_usb::class::cdc_ncm::{CdcNcmClass, Receiver, Sender, State}; use embassy_usb::{Builder, Config, UsbDevice}; -use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; use embedded_io::asynch::Write; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index bf92a163..b7d6493b 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -7,9 +7,9 @@ use embassy_executor::Spawner; use embassy_futures::join::join; use embassy_rp::interrupt; use embassy_rp::usb::{Driver, Instance}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::{Builder, Config}; -use embassy_usb_serial::{CdcAcmClass, State}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 895e043d..e6553789 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -9,7 +9,6 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index a14e728b..ad92cdeb 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs @@ -10,9 +10,9 @@ use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use embassy_usb_serial::{CdcAcmClass, State}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 27f5c260..f5b0b880 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -9,8 +9,6 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } -embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index b9fd20e2..f6d27c86 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs @@ -10,9 +10,9 @@ use embassy_stm32::time::mhz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use embassy_usb_serial::{CdcAcmClass, State}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 05945f6b..9ebab647 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -11,9 +11,6 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } -embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"] } -embassy-usb-ncm = { version = "0.1.0", path = "../../embassy-usb-ncm", features = ["defmt"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.6.0" diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index c96a83ea..4f36d3f5 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -15,8 +15,8 @@ use embassy_stm32::usb::Driver; use embassy_stm32::{interrupt, Config}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; +use embassy_usb::class::cdc_ncm::{CdcNcmClass, Receiver, Sender, State}; use embassy_usb::{Builder, UsbDevice}; -use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; use embedded_io::asynch::Write; use rand_core::RngCore; use static_cell::StaticCell; diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index fa92ceae..d38ed749 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -9,9 +9,9 @@ use embassy_stm32::rcc::*; use embassy_stm32::usb::Driver; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; +use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::Builder; -use embassy_usb_hid::{HidWriter, ReportId, RequestHandler, State}; use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { ); // Create classes on the builder. - let config = embassy_usb_hid::Config { + let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), request_handler: Some(&request_handler), poll_ms: 60, diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 7484dc83..7562a4e9 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -8,9 +8,9 @@ use embassy_futures::join::join; use embassy_stm32::rcc::*; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{interrupt, Config}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use embassy_usb_serial::{CdcAcmClass, State}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main]