Apply Pedantic Clippy Lints
This commit is contained in:
		@@ -70,9 +70,11 @@ fn main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    // envvars take priority.
 | 
					                    // envvars take priority.
 | 
				
			||||||
                    if !cfg.seen_env {
 | 
					                    if !cfg.seen_env {
 | 
				
			||||||
                        if cfg.seen_feature {
 | 
					                        assert!(
 | 
				
			||||||
                            panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value);
 | 
					                            !cfg.seen_feature,
 | 
				
			||||||
                        }
 | 
					                            "multiple values set for feature {}: {} and {}",
 | 
				
			||||||
 | 
					                            name, cfg.value, value
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        cfg.value = value;
 | 
					                        cfg.value = value;
 | 
				
			||||||
                        cfg.seen_feature = true;
 | 
					                        cfg.seen_feature = true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,17 @@
 | 
				
			|||||||
use heapless::Vec;
 | 
					use heapless::Vec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::config::*;
 | 
					use crate::config::MAX_HANDLER_COUNT;
 | 
				
			||||||
use crate::descriptor::{BosWriter, DescriptorWriter};
 | 
					use crate::descriptor::{BosWriter, DescriptorWriter};
 | 
				
			||||||
use crate::driver::{Driver, Endpoint, EndpointType};
 | 
					use crate::driver::{Driver, Endpoint, EndpointType};
 | 
				
			||||||
#[cfg(feature = "msos-descriptor")]
 | 
					#[cfg(feature = "msos-descriptor")]
 | 
				
			||||||
use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter};
 | 
					use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter};
 | 
				
			||||||
use crate::types::*;
 | 
					use crate::types::{InterfaceNumber, StringIndex};
 | 
				
			||||||
use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
 | 
					use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
/// Configuration used when creating [UsbDevice].
 | 
					/// Configuration used when creating [`UsbDevice`].
 | 
				
			||||||
pub struct Config<'a> {
 | 
					pub struct Config<'a> {
 | 
				
			||||||
    pub(crate) vendor_id: u16,
 | 
					    pub(crate) vendor_id: u16,
 | 
				
			||||||
    pub(crate) product_id: u16,
 | 
					    pub(crate) product_id: u16,
 | 
				
			||||||
@@ -159,9 +159,10 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
 | 
				
			|||||||
            panic!("if composite_with_iads is set, you must set device_class = 0xEF, device_sub_class = 0x02, device_protocol = 0x01");
 | 
					            panic!("if composite_with_iads is set, you must set device_class = 0xEF, device_sub_class = 0x02, device_protocol = 0x01");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if config.max_power > 500 {
 | 
					        assert!(
 | 
				
			||||||
            panic!("The maximum allowed value for `max_power` is 500mA");
 | 
					            config.max_power <= 500,
 | 
				
			||||||
        }
 | 
					            "The maximum allowed value for `max_power` is 500mA"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match config.max_packet_size_0 {
 | 
					        match config.max_packet_size_0 {
 | 
				
			||||||
            8 | 16 | 32 | 64 => {}
 | 
					            8 | 16 | 32 | 64 => {}
 | 
				
			||||||
@@ -260,12 +261,11 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
 | 
				
			|||||||
    /// The Handler is called on some USB bus events, and to handle all control requests not already
 | 
					    /// The Handler is called on some USB bus events, and to handle all control requests not already
 | 
				
			||||||
    /// handled by the USB stack.
 | 
					    /// handled by the USB stack.
 | 
				
			||||||
    pub fn handler(&mut self, handler: &'d mut dyn Handler) {
 | 
					    pub fn handler(&mut self, handler: &'d mut dyn Handler) {
 | 
				
			||||||
        if self.handlers.push(handler).is_err() {
 | 
					        assert!(
 | 
				
			||||||
            panic!(
 | 
					            self.handlers.push(handler).is_ok(),
 | 
				
			||||||
                "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}",
 | 
					            "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}",
 | 
				
			||||||
                MAX_HANDLER_COUNT
 | 
					            MAX_HANDLER_COUNT
 | 
				
			||||||
            )
 | 
					        );
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Allocates a new string index.
 | 
					    /// Allocates a new string index.
 | 
				
			||||||
@@ -332,12 +332,10 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> {
 | 
				
			|||||||
            num_alt_settings: 0,
 | 
					            num_alt_settings: 0,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.builder.interfaces.push(iface).is_err() {
 | 
					        assert!(self.builder.interfaces.push(iface).is_ok(),
 | 
				
			||||||
            panic!(
 | 
					            "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}",
 | 
				
			||||||
                "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}",
 | 
					            MAX_INTERFACE_COUNT
 | 
				
			||||||
                MAX_INTERFACE_COUNT
 | 
					        );
 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        InterfaceBuilder {
 | 
					        InterfaceBuilder {
 | 
				
			||||||
            builder: self.builder,
 | 
					            builder: self.builder,
 | 
				
			||||||
@@ -371,7 +369,7 @@ pub struct InterfaceBuilder<'a, 'd, D: Driver<'d>> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> {
 | 
					impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> {
 | 
				
			||||||
    /// Get the interface number.
 | 
					    /// Get the interface number.
 | 
				
			||||||
    pub fn interface_number(&self) -> InterfaceNumber {
 | 
					    pub const fn interface_number(&self) -> InterfaceNumber {
 | 
				
			||||||
        self.interface_number
 | 
					        self.interface_number
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -422,12 +420,12 @@ pub struct InterfaceAltBuilder<'a, 'd, D: Driver<'d>> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
 | 
					impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
 | 
				
			||||||
    /// Get the interface number.
 | 
					    /// Get the interface number.
 | 
				
			||||||
    pub fn interface_number(&self) -> InterfaceNumber {
 | 
					    pub const fn interface_number(&self) -> InterfaceNumber {
 | 
				
			||||||
        self.interface_number
 | 
					        self.interface_number
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get the alternate setting number.
 | 
					    /// Get the alternate setting number.
 | 
				
			||||||
    pub fn alt_setting_number(&self) -> u8 {
 | 
					    pub const fn alt_setting_number(&self) -> u8 {
 | 
				
			||||||
        self.alt_setting_number
 | 
					        self.alt_setting_number
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -436,7 +434,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
 | 
				
			|||||||
    /// Descriptors are written in the order builder functions are called. Note that some
 | 
					    /// Descriptors are written in the order builder functions are called. Note that some
 | 
				
			||||||
    /// classes care about the order.
 | 
					    /// classes care about the order.
 | 
				
			||||||
    pub fn descriptor(&mut self, descriptor_type: u8, descriptor: &[u8]) {
 | 
					    pub fn descriptor(&mut self, descriptor_type: u8, descriptor: &[u8]) {
 | 
				
			||||||
        self.builder.config_descriptor.write(descriptor_type, descriptor)
 | 
					        self.builder.config_descriptor.write(descriptor_type, descriptor);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn {
 | 
					    fn endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ use embassy_sync::waitqueue::WakerRegistration;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType};
 | 
					use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType};
 | 
				
			||||||
use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
 | 
					use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
 | 
				
			||||||
use crate::types::*;
 | 
					use crate::types::InterfaceNumber;
 | 
				
			||||||
use crate::{Builder, Handler};
 | 
					use crate::{Builder, Handler};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// This should be used as `device_class` when building the `UsbDevice`.
 | 
					/// This should be used as `device_class` when building the `UsbDevice`.
 | 
				
			||||||
@@ -50,7 +50,7 @@ impl<'a> State<'a> {
 | 
				
			|||||||
    pub fn new() -> Self {
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            control: MaybeUninit::uninit(),
 | 
					            control: MaybeUninit::uninit(),
 | 
				
			||||||
            shared: Default::default(),
 | 
					            shared: ControlShared::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -61,9 +61,9 @@ impl<'a> State<'a> {
 | 
				
			|||||||
/// writing USB packets with no intermediate buffers, but it will not act like a stream-like serial
 | 
					/// writing USB packets with no intermediate buffers, but it will not act like a stream-like serial
 | 
				
			||||||
/// port. The following constraints must be followed if you use this class directly:
 | 
					/// port. The following constraints must be followed if you use this class directly:
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// - `read_packet` must be called with a buffer large enough to hold max_packet_size bytes.
 | 
					/// - `read_packet` must be called with a buffer large enough to hold `max_packet_size` bytes.
 | 
				
			||||||
/// - `write_packet` must not be called with a buffer larger than max_packet_size bytes.
 | 
					/// - `write_packet` must not be called with a buffer larger than `max_packet_size` bytes.
 | 
				
			||||||
/// - If you write a packet that is exactly max_packet_size bytes long, it won't be processed by the
 | 
					/// - If you write a packet that is exactly `max_packet_size` bytes long, it won't be processed by the
 | 
				
			||||||
///   host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP)
 | 
					///   host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP)
 | 
				
			||||||
///   can be sent if there is no other data to send. This is because USB bulk transactions must be
 | 
					///   can be sent if there is no other data to send. This is because USB bulk transactions must be
 | 
				
			||||||
///   terminated with a short packet, even if the bulk endpoint is used for stream-like data.
 | 
					///   terminated with a short packet, even if the bulk endpoint is used for stream-like data.
 | 
				
			||||||
@@ -109,17 +109,16 @@ impl Default for ControlShared {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl ControlShared {
 | 
					impl ControlShared {
 | 
				
			||||||
    async fn changed(&self) {
 | 
					    async fn changed(&self) {
 | 
				
			||||||
        poll_fn(|cx| match self.changed.load(Ordering::Relaxed) {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            true => {
 | 
					            if self.changed.load(Ordering::Relaxed) {
 | 
				
			||||||
                self.changed.store(false, Ordering::Relaxed);
 | 
					                self.changed.store(false, Ordering::Relaxed);
 | 
				
			||||||
                Poll::Ready(())
 | 
					                Poll::Ready(())
 | 
				
			||||||
            }
 | 
					            } else {
 | 
				
			||||||
            false => {
 | 
					 | 
				
			||||||
                self.waker.borrow_mut().register(cx.waker());
 | 
					                self.waker.borrow_mut().register(cx.waker());
 | 
				
			||||||
                Poll::Pending
 | 
					                Poll::Pending
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .await
 | 
					        .await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,7 +197,7 @@ impl<'d> Handler for Control<'d> {
 | 
				
			|||||||
            // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below.
 | 
					            // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below.
 | 
				
			||||||
            REQ_GET_LINE_CODING if req.length == 7 => {
 | 
					            REQ_GET_LINE_CODING if req.length == 7 => {
 | 
				
			||||||
                debug!("Sending line coding");
 | 
					                debug!("Sending line coding");
 | 
				
			||||||
                let coding = self.shared().line_coding.lock(|x| x.get());
 | 
					                let coding = self.shared().line_coding.lock(Cell::get);
 | 
				
			||||||
                assert!(buf.len() >= 7);
 | 
					                assert!(buf.len() >= 7);
 | 
				
			||||||
                buf[0..4].copy_from_slice(&coding.data_rate.to_le_bytes());
 | 
					                buf[0..4].copy_from_slice(&coding.data_rate.to_le_bytes());
 | 
				
			||||||
                buf[4] = coding.stop_bits as u8;
 | 
					                buf[4] = coding.stop_bits as u8;
 | 
				
			||||||
@@ -212,8 +211,8 @@ impl<'d> Handler for Control<'d> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
 | 
					impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
 | 
				
			||||||
    /// Creates a new CdcAcmClass with the provided UsbBus and max_packet_size in bytes. For
 | 
					    /// 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.
 | 
					    /// 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>, state: &'d mut State<'d>, max_packet_size: u16) -> Self {
 | 
				
			||||||
        assert!(builder.control_buf_len() >= 7);
 | 
					        assert!(builder.control_buf_len() >= 7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -289,7 +288,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
 | 
				
			|||||||
    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
					    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
				
			||||||
    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
					    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
				
			||||||
    pub fn line_coding(&self) -> LineCoding {
 | 
					    pub fn line_coding(&self) -> LineCoding {
 | 
				
			||||||
        self.control.line_coding.lock(|x| x.get())
 | 
					        self.control.line_coding.lock(Cell::get)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the DTR (data terminal ready) state
 | 
					    /// Gets the DTR (data terminal ready) state
 | 
				
			||||||
@@ -314,7 +313,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.read_ep.wait_enabled().await
 | 
					        self.read_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Split the class into a sender and receiver.
 | 
					    /// Split the class into a sender and receiver.
 | 
				
			||||||
@@ -362,7 +361,7 @@ pub struct ControlChanged<'d> {
 | 
				
			|||||||
impl<'d> ControlChanged<'d> {
 | 
					impl<'d> ControlChanged<'d> {
 | 
				
			||||||
    /// Return a future for when the control settings change
 | 
					    /// Return a future for when the control settings change
 | 
				
			||||||
    pub async fn control_changed(&self) {
 | 
					    pub async fn control_changed(&self) {
 | 
				
			||||||
        self.control.changed().await
 | 
					        self.control.changed().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -384,7 +383,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> {
 | 
				
			|||||||
    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
					    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
				
			||||||
    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
					    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
				
			||||||
    pub fn line_coding(&self) -> LineCoding {
 | 
					    pub fn line_coding(&self) -> LineCoding {
 | 
				
			||||||
        self.control.line_coding.lock(|x| x.get())
 | 
					        self.control.line_coding.lock(Cell::get)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the DTR (data terminal ready) state
 | 
					    /// Gets the DTR (data terminal ready) state
 | 
				
			||||||
@@ -404,7 +403,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.write_ep.wait_enabled().await
 | 
					        self.write_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -426,7 +425,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
					    /// Gets the current line coding. The line coding contains information that's mainly relevant
 | 
				
			||||||
    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
					    /// for USB to UART serial port emulators, and can be ignored if not relevant.
 | 
				
			||||||
    pub fn line_coding(&self) -> LineCoding {
 | 
					    pub fn line_coding(&self) -> LineCoding {
 | 
				
			||||||
        self.control.line_coding.lock(|x| x.get())
 | 
					        self.control.line_coding.lock(Cell::get)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the DTR (data terminal ready) state
 | 
					    /// Gets the DTR (data terminal ready) state
 | 
				
			||||||
@@ -446,7 +445,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.read_ep.wait_enabled().await
 | 
					        self.read_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -520,17 +519,17 @@ impl LineCoding {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the number of data bits for UART communication.
 | 
					    /// Gets the number of data bits for UART communication.
 | 
				
			||||||
    pub fn data_bits(&self) -> u8 {
 | 
					    pub const fn data_bits(&self) -> u8 {
 | 
				
			||||||
        self.data_bits
 | 
					        self.data_bits
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the parity type for UART communication.
 | 
					    /// Gets the parity type for UART communication.
 | 
				
			||||||
    pub fn parity_type(&self) -> ParityType {
 | 
					    pub const fn parity_type(&self) -> ParityType {
 | 
				
			||||||
        self.parity_type
 | 
					        self.parity_type
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the data rate in bits per second for UART communication.
 | 
					    /// Gets the data rate in bits per second for UART communication.
 | 
				
			||||||
    pub fn data_rate(&self) -> u32 {
 | 
					    pub const fn data_rate(&self) -> u32 {
 | 
				
			||||||
        self.data_rate
 | 
					        self.data_rate
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,10 +16,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use core::intrinsics::copy_nonoverlapping;
 | 
					use core::intrinsics::copy_nonoverlapping;
 | 
				
			||||||
use core::mem::{size_of, MaybeUninit};
 | 
					use core::mem::{size_of, MaybeUninit};
 | 
				
			||||||
 | 
					use core::ptr::addr_of;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType};
 | 
					use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType};
 | 
				
			||||||
use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
 | 
					use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
 | 
				
			||||||
use crate::types::*;
 | 
					use crate::types::{InterfaceNumber, StringIndex};
 | 
				
			||||||
use crate::{Builder, Handler};
 | 
					use crate::{Builder, Handler};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod embassy_net;
 | 
					pub mod embassy_net;
 | 
				
			||||||
@@ -62,9 +63,9 @@ const REQ_SET_NTB_INPUT_SIZE: u8 = 0x86;
 | 
				
			|||||||
//const NOTIF_POLL_INTERVAL: u8 = 20;
 | 
					//const NOTIF_POLL_INTERVAL: u8 = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NTB_MAX_SIZE: usize = 2048;
 | 
					const NTB_MAX_SIZE: usize = 2048;
 | 
				
			||||||
const SIG_NTH: u32 = 0x484d434e;
 | 
					const SIG_NTH: u32 = 0x484d_434e;
 | 
				
			||||||
const SIG_NDP_NO_FCS: u32 = 0x304d434e;
 | 
					const SIG_NDP_NO_FCS: u32 = 0x304d_434e;
 | 
				
			||||||
const SIG_NDP_WITH_FCS: u32 = 0x314d434e;
 | 
					const SIG_NDP_WITH_FCS: u32 = 0x314d_434e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ALTERNATE_SETTING_DISABLED: u8 = 0x00;
 | 
					const ALTERNATE_SETTING_DISABLED: u8 = 0x00;
 | 
				
			||||||
const ALTERNATE_SETTING_ENABLED: u8 = 0x01;
 | 
					const ALTERNATE_SETTING_ENABLED: u8 = 0x01;
 | 
				
			||||||
@@ -111,7 +112,7 @@ struct NtbParametersDir {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
fn byteify<T>(buf: &mut [u8], data: T) -> &[u8] {
 | 
					fn byteify<T>(buf: &mut [u8], data: T) -> &[u8] {
 | 
				
			||||||
    let len = size_of::<T>();
 | 
					    let len = size_of::<T>();
 | 
				
			||||||
    unsafe { copy_nonoverlapping(&data as *const _ as *const u8, buf.as_mut_ptr(), len) }
 | 
					    unsafe { copy_nonoverlapping(addr_of!(data).cast(), buf.as_mut_ptr(), len) }
 | 
				
			||||||
    &buf[..len]
 | 
					    &buf[..len]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -132,12 +133,12 @@ impl<'a> State<'a> {
 | 
				
			|||||||
    pub fn new() -> Self {
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            control: MaybeUninit::uninit(),
 | 
					            control: MaybeUninit::uninit(),
 | 
				
			||||||
            shared: Default::default(),
 | 
					            shared: ControlShared::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Shared data between Control and CdcAcmClass
 | 
					/// Shared data between Control and `CdcAcmClass`
 | 
				
			||||||
#[derive(Default)]
 | 
					#[derive(Default)]
 | 
				
			||||||
struct ControlShared {
 | 
					struct ControlShared {
 | 
				
			||||||
    mac_addr: [u8; 6],
 | 
					    mac_addr: [u8; 6],
 | 
				
			||||||
@@ -378,12 +379,12 @@ impl<'d, D: Driver<'d>> Sender<'d, D> {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This waits until the packet is successfully stored in the CDC-NCM endpoint buffers.
 | 
					    /// This waits until the packet is successfully stored in the CDC-NCM endpoint buffers.
 | 
				
			||||||
    pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> {
 | 
					    pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> {
 | 
				
			||||||
        let seq = self.seq;
 | 
					 | 
				
			||||||
        self.seq = self.seq.wrapping_add(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const OUT_HEADER_LEN: usize = 28;
 | 
					        const OUT_HEADER_LEN: usize = 28;
 | 
				
			||||||
        const ABS_MAX_PACKET_SIZE: usize = 512;
 | 
					        const ABS_MAX_PACKET_SIZE: usize = 512;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let seq = self.seq;
 | 
				
			||||||
 | 
					        self.seq = self.seq.wrapping_add(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let header = NtbOutHeader {
 | 
					        let header = NtbOutHeader {
 | 
				
			||||||
            nth_sig: SIG_NTH,
 | 
					            nth_sig: SIG_NTH,
 | 
				
			||||||
            nth_len: 0x0c,
 | 
					            nth_len: 0x0c,
 | 
				
			||||||
@@ -460,12 +461,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
            let ntb = &ntb[..pos];
 | 
					            let ntb = &ntb[..pos];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Process NTB header (NTH)
 | 
					            // Process NTB header (NTH)
 | 
				
			||||||
            let nth = match ntb.get(..12) {
 | 
					            let Some(nth) = ntb.get(..12) else {
 | 
				
			||||||
                Some(x) => x,
 | 
					                warn!("Received too short NTB");
 | 
				
			||||||
                None => {
 | 
					                continue;
 | 
				
			||||||
                    warn!("Received too short NTB");
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            let sig = u32::from_le_bytes(nth[0..4].try_into().unwrap());
 | 
					            let sig = u32::from_le_bytes(nth[0..4].try_into().unwrap());
 | 
				
			||||||
            if sig != SIG_NTH {
 | 
					            if sig != SIG_NTH {
 | 
				
			||||||
@@ -475,12 +473,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
            let ndp_idx = u16::from_le_bytes(nth[10..12].try_into().unwrap()) as usize;
 | 
					            let ndp_idx = u16::from_le_bytes(nth[10..12].try_into().unwrap()) as usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Process NTB Datagram Pointer (NDP)
 | 
					            // Process NTB Datagram Pointer (NDP)
 | 
				
			||||||
            let ndp = match ntb.get(ndp_idx..ndp_idx + 12) {
 | 
					            let Some(ndp) = ntb.get(ndp_idx..ndp_idx + 12) else {
 | 
				
			||||||
                Some(x) => x,
 | 
					                warn!("NTH has an NDP pointer out of range.");
 | 
				
			||||||
                None => {
 | 
					                continue;
 | 
				
			||||||
                    warn!("NTH has an NDP pointer out of range.");
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            let sig = u32::from_le_bytes(ndp[0..4].try_into().unwrap());
 | 
					            let sig = u32::from_le_bytes(ndp[0..4].try_into().unwrap());
 | 
				
			||||||
            if sig != SIG_NDP_NO_FCS && sig != SIG_NDP_WITH_FCS {
 | 
					            if sig != SIG_NDP_NO_FCS && sig != SIG_NDP_WITH_FCS {
 | 
				
			||||||
@@ -496,12 +491,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Process actual datagram, finally.
 | 
					            // Process actual datagram, finally.
 | 
				
			||||||
            let datagram = match ntb.get(datagram_index..datagram_index + datagram_len) {
 | 
					            let Some(datagram) = ntb.get(datagram_index..datagram_index + datagram_len) else {
 | 
				
			||||||
                Some(x) => x,
 | 
					                warn!("NDP has a datagram pointer out of range.");
 | 
				
			||||||
                None => {
 | 
					                continue;
 | 
				
			||||||
                    warn!("NDP has a datagram pointer out of range.");
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            buf[..datagram_len].copy_from_slice(datagram);
 | 
					            buf[..datagram_len].copy_from_slice(datagram);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,7 @@ pub enum ReportId {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ReportId {
 | 
					impl ReportId {
 | 
				
			||||||
    fn try_from(value: u16) -> Result<Self, ()> {
 | 
					    const fn try_from(value: u16) -> Result<Self, ()> {
 | 
				
			||||||
        match value >> 8 {
 | 
					        match value >> 8 {
 | 
				
			||||||
            1 => Ok(ReportId::In(value as u8)),
 | 
					            1 => Ok(ReportId::In(value as u8)),
 | 
				
			||||||
            2 => Ok(ReportId::Out(value as u8)),
 | 
					            2 => Ok(ReportId::Out(value as u8)),
 | 
				
			||||||
@@ -87,7 +87,7 @@ impl<'d> Default for State<'d> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d> State<'d> {
 | 
					impl<'d> State<'d> {
 | 
				
			||||||
    /// Create a new `State`.
 | 
					    /// Create a new `State`.
 | 
				
			||||||
    pub fn new() -> Self {
 | 
					    pub const fn new() -> Self {
 | 
				
			||||||
        State {
 | 
					        State {
 | 
				
			||||||
            control: MaybeUninit::uninit(),
 | 
					            control: MaybeUninit::uninit(),
 | 
				
			||||||
            out_report_offset: AtomicUsize::new(0),
 | 
					            out_report_offset: AtomicUsize::new(0),
 | 
				
			||||||
@@ -154,7 +154,7 @@ fn build<'d, D: Driver<'d>>(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWriter<'d, D, READ_N, WRITE_N> {
 | 
					impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWriter<'d, D, READ_N, WRITE_N> {
 | 
				
			||||||
    /// Creates a new HidReaderWriter.
 | 
					    /// Creates a new `HidReaderWriter`.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This will allocate one IN and one OUT endpoints. If you only need writing (sending)
 | 
					    /// 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.
 | 
					    /// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only.
 | 
				
			||||||
@@ -230,7 +230,7 @@ pub enum ReadError {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl From<EndpointError> for ReadError {
 | 
					impl From<EndpointError> for ReadError {
 | 
				
			||||||
    fn from(val: EndpointError) -> Self {
 | 
					    fn from(val: EndpointError) -> Self {
 | 
				
			||||||
        use EndpointError::*;
 | 
					        use EndpointError::{BufferOverflow, Disabled};
 | 
				
			||||||
        match val {
 | 
					        match val {
 | 
				
			||||||
            BufferOverflow => ReadError::BufferOverflow,
 | 
					            BufferOverflow => ReadError::BufferOverflow,
 | 
				
			||||||
            Disabled => ReadError::Disabled,
 | 
					            Disabled => ReadError::Disabled,
 | 
				
			||||||
@@ -258,16 +258,15 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the interrupt in endpoint to be enabled.
 | 
					    /// Waits for the interrupt in endpoint to be enabled.
 | 
				
			||||||
    pub async fn ready(&mut self) {
 | 
					    pub async fn ready(&mut self) {
 | 
				
			||||||
        self.ep_in.wait_enabled().await
 | 
					        self.ep_in.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Writes an input report by serializing the given report structure.
 | 
					    /// Writes an input report by serializing the given report structure.
 | 
				
			||||||
    #[cfg(feature = "usbd-hid")]
 | 
					    #[cfg(feature = "usbd-hid")]
 | 
				
			||||||
    pub async fn write_serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), EndpointError> {
 | 
					    pub async fn write_serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), EndpointError> {
 | 
				
			||||||
        let mut buf: [u8; N] = [0; N];
 | 
					        let mut buf: [u8; N] = [0; N];
 | 
				
			||||||
        let size = match serialize(&mut buf, r) {
 | 
					        let Ok(size) = serialize(&mut buf, r) else {
 | 
				
			||||||
            Ok(size) => size,
 | 
					            return Err(EndpointError::BufferOverflow);
 | 
				
			||||||
            Err(_) => return Err(EndpointError::BufferOverflow),
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.write(&buf[0..size]).await
 | 
					        self.write(&buf[0..size]).await
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -293,7 +292,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> {
 | 
				
			|||||||
impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> {
 | 
					impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> {
 | 
				
			||||||
    /// Waits for the interrupt out endpoint to be enabled.
 | 
					    /// Waits for the interrupt out endpoint to be enabled.
 | 
				
			||||||
    pub async fn ready(&mut self) {
 | 
					    pub async fn ready(&mut self) {
 | 
				
			||||||
        self.ep_out.wait_enabled().await
 | 
					        self.ep_out.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Delivers output reports from the Interrupt Out pipe to `handler`.
 | 
					    /// Delivers output reports from the Interrupt Out pipe to `handler`.
 | 
				
			||||||
@@ -350,9 +349,8 @@ impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> {
 | 
				
			|||||||
                        if size < max_packet_size || total == N {
 | 
					                        if size < max_packet_size || total == N {
 | 
				
			||||||
                            self.offset.store(0, Ordering::Release);
 | 
					                            self.offset.store(0, Ordering::Release);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            self.offset.store(total, Ordering::Release);
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        self.offset.store(total, Ordering::Release);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Err(err) => {
 | 
					                    Err(err) => {
 | 
				
			||||||
                        self.offset.store(0, Ordering::Release);
 | 
					                        self.offset.store(0, Ordering::Release);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,9 +27,9 @@ const MIDI_OUT_SIZE: u8 = 0x09;
 | 
				
			|||||||
/// writing USB packets with no intermediate buffers, but it will not act like a stream-like port.
 | 
					/// writing USB packets with no intermediate buffers, but it will not act like a stream-like port.
 | 
				
			||||||
/// The following constraints must be followed if you use this class directly:
 | 
					/// The following constraints must be followed if you use this class directly:
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// - `read_packet` must be called with a buffer large enough to hold max_packet_size bytes.
 | 
					/// - `read_packet` must be called with a buffer large enough to hold `max_packet_size` bytes.
 | 
				
			||||||
/// - `write_packet` must not be called with a buffer larger than max_packet_size bytes.
 | 
					/// - `write_packet` must not be called with a buffer larger than `max_packet_size` bytes.
 | 
				
			||||||
/// - If you write a packet that is exactly max_packet_size bytes long, it won't be processed by the
 | 
					/// - If you write a packet that is exactly `max_packet_size` bytes long, it won't be processed by the
 | 
				
			||||||
///   host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP)
 | 
					///   host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP)
 | 
				
			||||||
///   can be sent if there is no other data to send. This is because USB bulk transactions must be
 | 
					///   can be sent if there is no other data to send. This is because USB bulk transactions must be
 | 
				
			||||||
///   terminated with a short packet, even if the bulk endpoint is used for stream-like data.
 | 
					///   terminated with a short packet, even if the bulk endpoint is used for stream-like data.
 | 
				
			||||||
@@ -39,8 +39,8 @@ pub struct MidiClass<'d, D: Driver<'d>> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, D: Driver<'d>> MidiClass<'d, D> {
 | 
					impl<'d, D: Driver<'d>> MidiClass<'d, D> {
 | 
				
			||||||
    /// Creates a new MidiClass with the provided UsbBus, number of input and output jacks and max_packet_size in bytes.
 | 
					    /// Creates a new `MidiClass` with the provided UsbBus, number of input and output jacks and `max_packet_size` in bytes.
 | 
				
			||||||
    /// For full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64.
 | 
					    /// 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>, n_in_jacks: u8, n_out_jacks: u8, max_packet_size: u16) -> Self {
 | 
					    pub fn new(builder: &mut Builder<'d, D>, n_in_jacks: u8, n_out_jacks: u8, max_packet_size: u16) -> Self {
 | 
				
			||||||
        let mut func = builder.function(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE);
 | 
					        let mut func = builder.function(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -160,7 +160,7 @@ impl<'d, D: Driver<'d>> MidiClass<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.read_ep.wait_enabled().await
 | 
					        self.read_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Split the class into a sender and receiver.
 | 
					    /// Split the class into a sender and receiver.
 | 
				
			||||||
@@ -197,7 +197,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.write_ep.wait_enabled().await
 | 
					        self.write_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -222,6 +222,6 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Waits for the USB host to enable this interface
 | 
					    /// Waits for the USB host to enable this interface
 | 
				
			||||||
    pub async fn wait_connection(&mut self) {
 | 
					    pub async fn wait_connection(&mut self) {
 | 
				
			||||||
        self.read_ep.wait_enabled().await
 | 
					        self.read_ep.wait_enabled().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,7 +120,7 @@ impl Request {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the descriptor type and index from the value field of a GET_DESCRIPTOR request.
 | 
					    /// Gets the descriptor type and index from the value field of a GET_DESCRIPTOR request.
 | 
				
			||||||
    pub fn descriptor_type_index(&self) -> (u8, u8) {
 | 
					    pub const fn descriptor_type_index(&self) -> (u8, u8) {
 | 
				
			||||||
        ((self.value >> 8) as u8, self.value as u8)
 | 
					        ((self.value >> 8) as u8, self.value as u8)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use crate::builder::Config;
 | 
					use crate::builder::Config;
 | 
				
			||||||
use crate::driver::EndpointInfo;
 | 
					use crate::driver::EndpointInfo;
 | 
				
			||||||
use crate::types::*;
 | 
					use crate::types::{InterfaceNumber, StringIndex};
 | 
				
			||||||
use crate::CONFIGURATION_VALUE;
 | 
					use crate::CONFIGURATION_VALUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Standard descriptor types
 | 
					/// Standard descriptor types
 | 
				
			||||||
@@ -59,7 +59,7 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the current position in the buffer, i.e. the number of bytes written so far.
 | 
					    /// Gets the current position in the buffer, i.e. the number of bytes written so far.
 | 
				
			||||||
    pub fn position(&self) -> usize {
 | 
					    pub const fn position(&self) -> usize {
 | 
				
			||||||
        self.position
 | 
					        self.position
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,9 +67,10 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
    pub fn write(&mut self, descriptor_type: u8, descriptor: &[u8]) {
 | 
					    pub fn write(&mut self, descriptor_type: u8, descriptor: &[u8]) {
 | 
				
			||||||
        let length = descriptor.len();
 | 
					        let length = descriptor.len();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (self.position + 2 + length) > self.buf.len() || (length + 2) > 255 {
 | 
					        assert!(
 | 
				
			||||||
            panic!("Descriptor buffer full");
 | 
					            (self.position + 2 + length) <= self.buf.len() && (length + 2) <= 255,
 | 
				
			||||||
        }
 | 
					            "Descriptor buffer full"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.buf[self.position] = (length + 2) as u8;
 | 
					        self.buf[self.position] = (length + 2) as u8;
 | 
				
			||||||
        self.buf[self.position + 1] = descriptor_type;
 | 
					        self.buf[self.position + 1] = descriptor_type;
 | 
				
			||||||
@@ -102,7 +103,7 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
                config.serial_number.map_or(0, |_| 3), // iSerialNumber
 | 
					                config.serial_number.map_or(0, |_| 3), // iSerialNumber
 | 
				
			||||||
                1,                                     // bNumConfigurations
 | 
					                1,                                     // bNumConfigurations
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        )
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) fn configuration(&mut self, config: &Config) {
 | 
					    pub(crate) fn configuration(&mut self, config: &Config) {
 | 
				
			||||||
@@ -120,7 +121,7 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
                    | if config.supports_remote_wakeup { 0x20 } else { 0x00 }, // bmAttributes
 | 
					                    | if config.supports_remote_wakeup { 0x20 } else { 0x00 }, // bmAttributes
 | 
				
			||||||
                (config.max_power / 2) as u8, // bMaxPower
 | 
					                (config.max_power / 2) as u8, // bMaxPower
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        )
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[allow(unused)]
 | 
					    #[allow(unused)]
 | 
				
			||||||
@@ -248,9 +249,7 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
    pub(crate) fn string(&mut self, string: &str) {
 | 
					    pub(crate) fn string(&mut self, string: &str) {
 | 
				
			||||||
        let mut pos = self.position;
 | 
					        let mut pos = self.position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if pos + 2 > self.buf.len() {
 | 
					        assert!(pos + 2 <= self.buf.len(), "Descriptor buffer full");
 | 
				
			||||||
            panic!("Descriptor buffer full");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.buf[pos] = 0; // length placeholder
 | 
					        self.buf[pos] = 0; // length placeholder
 | 
				
			||||||
        self.buf[pos + 1] = descriptor_type::STRING;
 | 
					        self.buf[pos + 1] = descriptor_type::STRING;
 | 
				
			||||||
@@ -258,9 +257,7 @@ impl<'a> DescriptorWriter<'a> {
 | 
				
			|||||||
        pos += 2;
 | 
					        pos += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for c in string.encode_utf16() {
 | 
					        for c in string.encode_utf16() {
 | 
				
			||||||
            if pos >= self.buf.len() {
 | 
					            assert!(pos < self.buf.len(), "Descriptor buffer full");
 | 
				
			||||||
                panic!("Descriptor buffer full");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
 | 
					            self.buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
 | 
				
			||||||
            pos += 2;
 | 
					            pos += 2;
 | 
				
			||||||
@@ -279,7 +276,7 @@ pub struct BosWriter<'a> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> BosWriter<'a> {
 | 
					impl<'a> BosWriter<'a> {
 | 
				
			||||||
    pub(crate) fn new(writer: DescriptorWriter<'a>) -> Self {
 | 
					    pub(crate) const fn new(writer: DescriptorWriter<'a>) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            writer,
 | 
					            writer,
 | 
				
			||||||
            num_caps_mark: None,
 | 
					            num_caps_mark: None,
 | 
				
			||||||
@@ -314,9 +311,10 @@ impl<'a> BosWriter<'a> {
 | 
				
			|||||||
        let mut start = self.writer.position;
 | 
					        let mut start = self.writer.position;
 | 
				
			||||||
        let blen = data.len();
 | 
					        let blen = data.len();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (start + blen + 3) > self.writer.buf.len() || (blen + 3) > 255 {
 | 
					        assert!(
 | 
				
			||||||
            panic!("Descriptor buffer full");
 | 
					            (start + blen + 3) <= self.writer.buf.len() && (blen + 3) <= 255,
 | 
				
			||||||
        }
 | 
					            "Descriptor buffer full"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.writer.buf[start] = (blen + 3) as u8;
 | 
					        self.writer.buf[start] = (blen + 3) as u8;
 | 
				
			||||||
        self.writer.buf[start + 1] = descriptor_type::CAPABILITY;
 | 
					        self.writer.buf[start + 1] = descriptor_type::CAPABILITY;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,11 +11,11 @@ pub struct Reader<'a> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> Reader<'a> {
 | 
					impl<'a> Reader<'a> {
 | 
				
			||||||
    pub fn new(data: &'a [u8]) -> Self {
 | 
					    pub const fn new(data: &'a [u8]) -> Self {
 | 
				
			||||||
        Self { data }
 | 
					        Self { data }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn eof(&self) -> bool {
 | 
					    pub const fn eof(&self) -> bool {
 | 
				
			||||||
        self.data.is_empty()
 | 
					        self.data.is_empty()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -102,7 +102,7 @@ pub fn foreach_endpoint(data: &[u8], mut f: impl FnMut(EndpointInfo)) -> Result<
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            descriptor_type::ENDPOINT => {
 | 
					            descriptor_type::ENDPOINT => {
 | 
				
			||||||
                ep.ep_address = EndpointAddress::from(r.read_u8()?);
 | 
					                ep.ep_address = EndpointAddress::from(r.read_u8()?);
 | 
				
			||||||
                f(ep)
 | 
					                f(ep);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {}
 | 
					            _ => {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,12 +24,12 @@ use embassy_futures::select::{select, Either};
 | 
				
			|||||||
use heapless::Vec;
 | 
					use heapless::Vec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder};
 | 
					pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder};
 | 
				
			||||||
use crate::config::*;
 | 
					use crate::config::{MAX_HANDLER_COUNT, MAX_INTERFACE_COUNT};
 | 
				
			||||||
use crate::control::*;
 | 
					use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType};
 | 
				
			||||||
use crate::descriptor::*;
 | 
					use crate::descriptor::{descriptor_type, lang_id};
 | 
				
			||||||
use crate::descriptor_reader::foreach_endpoint;
 | 
					use crate::descriptor_reader::foreach_endpoint;
 | 
				
			||||||
use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event};
 | 
					use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event};
 | 
				
			||||||
use crate::types::*;
 | 
					use crate::types::{InterfaceNumber, StringIndex};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The global state of the USB device.
 | 
					/// The global state of the USB device.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@@ -364,6 +364,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn handle_control_in(&mut self, req: Request) {
 | 
					    async fn handle_control_in(&mut self, req: Request) {
 | 
				
			||||||
 | 
					        const DEVICE_DESCRIPTOR_LEN: usize = 18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut resp_length = req.length as usize;
 | 
					        let mut resp_length = req.length as usize;
 | 
				
			||||||
        let max_packet_size = self.control.max_packet_size();
 | 
					        let max_packet_size = self.control.max_packet_size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -371,7 +373,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
 | 
				
			|||||||
        // The host doesn't know our EP0 max packet size yet, and might assume
 | 
					        // The host doesn't know our EP0 max packet size yet, and might assume
 | 
				
			||||||
        // a full-length packet is a short packet, thinking we're done sending data.
 | 
					        // a full-length packet is a short packet, thinking we're done sending data.
 | 
				
			||||||
        // See https://github.com/hathach/tinyusb/issues/184
 | 
					        // See https://github.com/hathach/tinyusb/issues/184
 | 
				
			||||||
        const DEVICE_DESCRIPTOR_LEN: usize = 18;
 | 
					 | 
				
			||||||
        if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length {
 | 
					        if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length {
 | 
				
			||||||
            trace!("received control req while not addressed: capping response to 1 packet.");
 | 
					            trace!("received control req while not addressed: capping response to 1 packet.");
 | 
				
			||||||
            resp_length = max_packet_size;
 | 
					            resp_length = max_packet_size;
 | 
				
			||||||
@@ -432,7 +433,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
 | 
				
			|||||||
                    self.control.accept_set_address(self.inner.address).await;
 | 
					                    self.control.accept_set_address(self.inner.address).await;
 | 
				
			||||||
                    self.inner.set_address_pending = false;
 | 
					                    self.inner.set_address_pending = false;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    self.control.accept().await
 | 
					                    self.control.accept().await;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            OutResponse::Rejected => self.control.reject().await,
 | 
					            OutResponse::Rejected => self.control.reject().await,
 | 
				
			||||||
@@ -545,9 +546,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    OutResponse::Accepted
 | 
					                    OutResponse::Accepted
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state {
 | 
					                (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => {
 | 
				
			||||||
                    UsbDeviceState::Default => OutResponse::Accepted,
 | 
					                    if self.device_state != UsbDeviceState::Default {
 | 
				
			||||||
                    _ => {
 | 
					 | 
				
			||||||
                        debug!("SET_CONFIGURATION: unconfigured");
 | 
					                        debug!("SET_CONFIGURATION: unconfigured");
 | 
				
			||||||
                        self.device_state = UsbDeviceState::Addressed;
 | 
					                        self.device_state = UsbDeviceState::Addressed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -561,17 +561,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
 | 
				
			|||||||
                        for h in &mut self.handlers {
 | 
					                        for h in &mut self.handlers {
 | 
				
			||||||
                            h.configured(false);
 | 
					                            h.configured(false);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                        OutResponse::Accepted
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                },
 | 
					                    OutResponse::Accepted
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                _ => OutResponse::Rejected,
 | 
					                _ => OutResponse::Rejected,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            (RequestType::Standard, Recipient::Interface) => {
 | 
					            (RequestType::Standard, Recipient::Interface) => {
 | 
				
			||||||
                let iface_num = InterfaceNumber::new(req.index as _);
 | 
					                let iface_num = InterfaceNumber::new(req.index as _);
 | 
				
			||||||
                let iface = match self.interfaces.get_mut(iface_num.0 as usize) {
 | 
					                let Some(iface) = self.interfaces.get_mut(iface_num.0 as usize) else {
 | 
				
			||||||
                    Some(iface) => iface,
 | 
					                    return OutResponse::Rejected;
 | 
				
			||||||
                    None => return OutResponse::Rejected,
 | 
					 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                match req.request {
 | 
					                match req.request {
 | 
				
			||||||
@@ -647,9 +645,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
 | 
				
			|||||||
                _ => InResponse::Rejected,
 | 
					                _ => InResponse::Rejected,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            (RequestType::Standard, Recipient::Interface) => {
 | 
					            (RequestType::Standard, Recipient::Interface) => {
 | 
				
			||||||
                let iface = match self.interfaces.get_mut(req.index as usize) {
 | 
					                let Some(iface) = self.interfaces.get_mut(req.index as usize) else {
 | 
				
			||||||
                    Some(iface) => iface,
 | 
					                    return InResponse::Rejected;
 | 
				
			||||||
                    None => return InResponse::Rejected,
 | 
					 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                match req.request {
 | 
					                match req.request {
 | 
				
			||||||
@@ -753,16 +750,12 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
 | 
				
			|||||||
                    };
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if let Some(s) = s {
 | 
					                    if let Some(s) = s {
 | 
				
			||||||
                        if buf.len() < 2 {
 | 
					                        assert!(buf.len() >= 2, "control buffer too small");
 | 
				
			||||||
                            panic!("control buffer too small");
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        buf[1] = descriptor_type::STRING;
 | 
					                        buf[1] = descriptor_type::STRING;
 | 
				
			||||||
                        let mut pos = 2;
 | 
					                        let mut pos = 2;
 | 
				
			||||||
                        for c in s.encode_utf16() {
 | 
					                        for c in s.encode_utf16() {
 | 
				
			||||||
                            if pos + 2 >= buf.len() {
 | 
					                            assert!(pos + 2 < buf.len(), "control buffer too small");
 | 
				
			||||||
                                panic!("control buffer too small");
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
 | 
					                            buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
 | 
				
			||||||
                            pos += 2;
 | 
					                            pos += 2;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use core::mem::size_of;
 | 
					use core::mem::size_of;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{capability_type, BosWriter};
 | 
					use crate::descriptor::{capability_type, BosWriter};
 | 
				
			||||||
use crate::types::InterfaceNumber;
 | 
					use crate::types::InterfaceNumber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A serialized Microsoft OS 2.0 Descriptor set.
 | 
					/// A serialized Microsoft OS 2.0 Descriptor set.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
pub struct InterfaceNumber(pub u8);
 | 
					pub struct InterfaceNumber(pub u8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl InterfaceNumber {
 | 
					impl InterfaceNumber {
 | 
				
			||||||
    pub(crate) fn new(index: u8) -> InterfaceNumber {
 | 
					    pub(crate) const fn new(index: u8) -> InterfaceNumber {
 | 
				
			||||||
        InterfaceNumber(index)
 | 
					        InterfaceNumber(index)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -25,7 +25,7 @@ impl From<InterfaceNumber> for u8 {
 | 
				
			|||||||
pub struct StringIndex(pub u8);
 | 
					pub struct StringIndex(pub u8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl StringIndex {
 | 
					impl StringIndex {
 | 
				
			||||||
    pub(crate) fn new(index: u8) -> StringIndex {
 | 
					    pub(crate) const fn new(index: u8) -> StringIndex {
 | 
				
			||||||
        StringIndex(index)
 | 
					        StringIndex(index)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user