diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index 6386e2096c..8ca6fdf948 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs @@ -67,7 +67,7 @@ impl UsbLogger { config.device_protocol = 0x01; config.composite_with_iads = true; - let mut builder = Builder::new( + let mut builder = Builder::<'d, D, 2>::new( driver, config, &mut state.device_descriptor, diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 87a8333bb0..b0e862cc1d 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -4,7 +4,7 @@ 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}; +use crate::{DeviceStateHandler, Interface, UsbDevice, STRING_INDEX_CUSTOM_START}; #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -118,10 +118,10 @@ impl<'a> Config<'a> { } /// [`UsbDevice`] builder. -pub struct Builder<'d, D: Driver<'d>> { +pub struct Builder<'d, D: Driver<'d>, const I: usize> { config: Config<'d>, handler: Option<&'d dyn DeviceStateHandler>, - interfaces: Vec, MAX_INTERFACE_COUNT>, + interfaces: Vec, I>, control_buf: &'d mut [u8], driver: D, @@ -132,7 +132,7 @@ pub struct Builder<'d, D: Driver<'d>> { bos_descriptor: BosWriter<'d>, } -impl<'d, D: Driver<'d>> Builder<'d, D> { +impl<'d, D: Driver<'d>, const I: usize> Builder<'d, D, I> { /// Creates a builder for constructing a new [`UsbDevice`]. /// /// `control_buf` is a buffer used for USB control request data. It should be sized @@ -186,7 +186,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { } /// Creates the [`UsbDevice`] instance with the configuration in this builder. - pub fn build(mut self) -> UsbDevice<'d, D> { + pub fn build(mut self) -> UsbDevice<'d, D, I> { self.config_descriptor.end_configuration(); self.bos_descriptor.end_bos(); @@ -214,7 +214,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { /// with the given class/subclass/protocol, associating all the child interfaces. /// /// If it's not set, no IAD descriptor is added. - pub fn function(&mut self, class: u8, subclass: u8, protocol: u8) -> FunctionBuilder<'_, 'd, D> { + pub fn function(&mut self, class: u8, subclass: u8, protocol: u8) -> FunctionBuilder<'_, 'd, D, I> { let iface_count_index = if self.config.composite_with_iads { self.config_descriptor.iad( InterfaceNumber::new(self.interfaces.len() as _), @@ -241,16 +241,16 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { /// A function is a logical grouping of interfaces that perform a given USB function. /// If [`Config::composite_with_iads`] is set, each function will have an IAD descriptor. /// If not, functions will not be visible as descriptors. -pub struct FunctionBuilder<'a, 'd, D: Driver<'d>> { - builder: &'a mut Builder<'d, D>, +pub struct FunctionBuilder<'a, 'd, D: Driver<'d>, const I: usize> { + builder: &'a mut Builder<'d, D, I>, iface_count_index: Option, } -impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { +impl<'a, 'd, D: Driver<'d>, const I: usize> FunctionBuilder<'a, 'd, D, I> { /// Add an interface to the function. /// /// Interface numbers are guaranteed to be allocated consecutively, starting from 0. - pub fn interface(&mut self) -> InterfaceBuilder<'_, 'd, D> { + pub fn interface(&mut self) -> InterfaceBuilder<'_, 'd, D, I> { if let Some(i) = self.iface_count_index { self.builder.config_descriptor.buf[i] += 1; } @@ -276,13 +276,13 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { } /// Interface builder. -pub struct InterfaceBuilder<'a, 'd, D: Driver<'d>> { - builder: &'a mut Builder<'d, D>, +pub struct InterfaceBuilder<'a, 'd, D: Driver<'d>, const I: usize> { + builder: &'a mut Builder<'d, D, I>, interface_number: InterfaceNumber, next_alt_setting_number: u8, } -impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { +impl<'a, 'd, D: Driver<'d>, const I: usize> InterfaceBuilder<'a, 'd, D, I> { /// Get the interface number. pub fn interface_number(&self) -> InterfaceNumber { self.interface_number @@ -306,7 +306,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { /// Alternate setting numbers are guaranteed to be allocated consecutively, starting from 0. /// /// The first alternate setting, with number 0, is the default one. - pub fn alt_setting(&mut self, class: u8, subclass: u8, protocol: u8) -> InterfaceAltBuilder<'_, 'd, D> { + pub fn alt_setting(&mut self, class: u8, subclass: u8, protocol: u8) -> InterfaceAltBuilder<'_, 'd, D, I> { let number = self.next_alt_setting_number; self.next_alt_setting_number += 1; self.builder.interfaces[self.interface_number.0 as usize].num_alt_settings += 1; @@ -324,13 +324,13 @@ impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { } /// Interface alternate setting builder. -pub struct InterfaceAltBuilder<'a, 'd, D: Driver<'d>> { - builder: &'a mut Builder<'d, D>, +pub struct InterfaceAltBuilder<'a, 'd, D: Driver<'d>, const I: usize> { + builder: &'a mut Builder<'d, D, I>, interface_number: InterfaceNumber, alt_setting_number: u8, } -impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { +impl<'a, 'd, D: Driver<'d>, const I: usize> InterfaceAltBuilder<'a, 'd, D, I> { /// Get the interface number. pub fn interface_number(&self) -> InterfaceNumber { self.interface_number diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 09bb1cc8dc..5d4b852ad5 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -158,7 +158,11 @@ impl<'d> ControlHandler for Control<'d> { impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { /// Creates a new CdcAcmClass with the provided UsbBus and max_packet_size in bytes. For /// full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64. - pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State<'d>, max_packet_size: u16) -> Self { + pub fn new( + builder: &mut Builder<'d, D, I>, + state: &'d mut State<'d>, + max_packet_size: u16, + ) -> Self { let control = state.control.write(Control { shared: &state.shared }); let control_shared = &state.shared; diff --git a/embassy-usb/src/class/cdc_ncm.rs b/embassy-usb/src/class/cdc_ncm.rs index a39b87e9b3..5e51fe5c02 100644 --- a/embassy-usb/src/class/cdc_ncm.rs +++ b/embassy-usb/src/class/cdc_ncm.rs @@ -218,8 +218,8 @@ pub struct CdcNcmClass<'d, D: Driver<'d>> { } impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { - pub fn new( - builder: &mut Builder<'d, D>, + pub fn new( + builder: &mut Builder<'d, D, I>, state: &'d mut State<'d>, mac_address: [u8; 6], max_packet_size: u16, diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index b967aba0e1..2f95e6c87c 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs @@ -84,8 +84,8 @@ pub struct HidReaderWriter<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N writer: HidWriter<'d, D, WRITE_N>, } -fn build<'d, D: Driver<'d>>( - builder: &mut Builder<'d, D>, +fn build<'d, D: Driver<'d>, const I: usize>( + builder: &mut Builder<'d, D, I>, state: &'d mut State<'d>, config: Config<'d>, with_out_endpoint: bool, @@ -138,7 +138,7 @@ impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWrit /// This will allocate one IN and one OUT endpoints. If you only need writing (sending) /// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only. /// - pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State<'d>, config: Config<'d>) -> Self { + pub fn new(builder: &mut Builder<'d, D, I>, state: &'d mut State<'d>, config: Config<'d>) -> Self { let (ep_out, ep_in, offset) = build(builder, state, config, true); Self { @@ -217,7 +217,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { /// HID reports. A lower value means better throughput & latency, at the expense /// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for /// high performance uses, and a value of 255 is good for best-effort usecases. - pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State<'d>, config: Config<'d>) -> Self { + pub fn new(builder: &mut Builder<'d, D, I>, state: &'d mut State<'d>, config: Config<'d>) -> Self { let (ep_out, ep_in, _offset) = build(builder, state, config, false); assert!(ep_out.is_none()); diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index 497f03196a..e330c85acd 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -313,7 +313,7 @@ impl<'a> BosWriter<'a> { let blen = data.len(); if (start + blen + 3) > self.writer.buf.len() || (blen + 3) > 255 { - panic!("Descriptor buffer full"); + panic!("BOS descriptor buffer full"); } self.writer.buf[start] = (blen + 3) as u8; diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 661b84119d..baa5445d76 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -65,8 +65,6 @@ pub const CONFIGURATION_NONE: u8 = 0; /// The bConfiguration value for the single configuration supported by this device. pub const CONFIGURATION_VALUE: u8 = 1; -pub const MAX_INTERFACE_COUNT: usize = 4; - const STRING_INDEX_MANUFACTURER: u8 = 1; const STRING_INDEX_PRODUCT: u8 = 2; const STRING_INDEX_SERIAL_NUMBER: u8 = 3; @@ -100,13 +98,13 @@ struct Interface<'d> { num_strings: u8, } -pub struct UsbDevice<'d, D: Driver<'d>> { +pub struct UsbDevice<'d, D: Driver<'d>, const I: usize> { control_buf: &'d mut [u8], control: D::ControlPipe, - inner: Inner<'d, D>, + inner: Inner<'d, D, I>, } -struct Inner<'d, D: Driver<'d>> { +struct Inner<'d, D: Driver<'d>, const I: usize> { bus: D::Bus, handler: Option<&'d dyn DeviceStateHandler>, @@ -128,10 +126,10 @@ struct Inner<'d, D: Driver<'d>> { /// If true, do a set_addr after finishing the current control req. set_address_pending: bool, - interfaces: Vec, MAX_INTERFACE_COUNT>, + interfaces: Vec, I>, } -impl<'d, D: Driver<'d>> UsbDevice<'d, D> { +impl<'d, D: Driver<'d>, const I: usize> UsbDevice<'d, D, I> { pub(crate) fn build( driver: D, config: Config<'d>, @@ -139,9 +137,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { device_descriptor: &'d [u8], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], - interfaces: Vec, MAX_INTERFACE_COUNT>, + interfaces: Vec, I>, control_buf: &'d mut [u8], - ) -> UsbDevice<'d, D> { + ) -> UsbDevice<'d, D, I> { // Start the USB bus. // This prevent further allocation by consuming the driver. let (bus, control) = driver.start(config.max_packet_size_0 as u16); @@ -334,7 +332,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { } } -impl<'d, D: Driver<'d>> Inner<'d, D> { +impl<'d, D: Driver<'d>, const I: usize> Inner<'d, D, I> { async fn handle_bus_event(&mut self, evt: Event) { match evt { Event::Reset => { diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs index de93a2b450..50a3a651f9 100644 --- a/examples/nrf/src/bin/usb_ethernet.rs +++ b/examples/nrf/src/bin/usb_ethernet.rs @@ -32,7 +32,7 @@ macro_rules! singleton { } #[embassy_executor::task] -async fn usb_task(mut device: UsbDevice<'static, MyDriver>) -> ! { +async fn usb_task(mut device: UsbDevice<'static, MyDriver, 2>) -> ! { device.run().await } diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs index 76e198719d..1b6fbb5cab 100644 --- a/examples/nrf/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf/src/bin/usb_hid_keyboard.rs @@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) { let mut state = State::new(); - let mut builder = Builder::new( + let mut builder = Builder::<'_, _, 2>::new( driver, config, &mut device_descriptor, diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs index 4916a38d4f..f1f58b739b 100644 --- a/examples/nrf/src/bin/usb_hid_mouse.rs +++ b/examples/nrf/src/bin/usb_hid_mouse.rs @@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) { let mut state = State::new(); - let mut builder = Builder::new( + let mut builder = Builder::<'_, _, 2>::new( driver, config, &mut device_descriptor, diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs index 7c9c4184b3..8f03fd9730 100644 --- a/examples/nrf/src/bin/usb_serial.rs +++ b/examples/nrf/src/bin/usb_serial.rs @@ -52,7 +52,7 @@ async fn main(_spawner: Spawner) { let mut state = State::new(); - let mut builder = Builder::new( + let mut builder = Builder::<'_, _, 2>::new( driver, config, &mut device_descriptor, diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs index 93efc2fe67..6c1412cf62 100644 --- a/examples/nrf/src/bin/usb_serial_multitask.rs +++ b/examples/nrf/src/bin/usb_serial_multitask.rs @@ -17,7 +17,7 @@ use {defmt_rtt as _, panic_probe as _}; type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>; #[embassy_executor::task] -async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { +async fn usb_task(mut device: UsbDevice<'static, MyDriver, 2>) { device.run().await; }