usb2/
configuration.rs

1//! Configuration descriptors
2
3use core::num::NonZeroU8;
4
5use crate::desc;
6
7/// Configuration Descriptor
8///
9/// See section 9.6.3 of (USB2)
10#[allow(non_snake_case)]
11#[derive(Clone, Copy)]
12pub struct Descriptor {
13    // pub blength: u8,
14    // pub bDescriptorType: u8,
15    /// The total length of this configuration descriptor plus the descriptors (interface, endpoint,
16    /// etc.) below it
17    pub wTotalLength: u16,
18    /// Number of interfaces associated to this configuration
19    pub bNumInterfaces: NonZeroU8,
20    /// Configuration value
21    pub bConfigurationValue: NonZeroU8,
22    /// Configuration string index
23    pub iConfiguration: Option<NonZeroU8>,
24    /// Attributes
25    pub bmAttributes: bmAttributes,
26    /// Maximum power (1 ULP = 2 mA)
27    pub bMaxPower: u8,
28}
29
30impl Descriptor {
31    /// The size of this descriptor on the wire
32    pub const SIZE: u8 = 9;
33
34    /// Returns the wire representation of this descriptor
35    pub fn bytes(&self) -> [u8; Self::SIZE as usize] {
36        [
37            Self::SIZE,
38            desc::Type::Configuration as u8,
39            self.wTotalLength as u8,
40            (self.wTotalLength >> 8) as u8,
41            self.bNumInterfaces.get(),
42            self.bConfigurationValue.get(),
43            self.iConfiguration.map(|nz| nz.get()).unwrap_or(0),
44            (1 << 7)
45                | if self.bmAttributes.self_powered {
46                    1 << 6
47                } else {
48                    0
49                }
50                | if self.bmAttributes.remote_wakeup {
51                    1 << 5
52                } else {
53                    0
54                },
55            self.bMaxPower,
56        ]
57    }
58}
59
60/// Attributes
61#[allow(non_camel_case_types)]
62#[derive(Clone, Copy)]
63pub struct bmAttributes {
64    /// Self-powered?
65    pub self_powered: bool,
66    /// Remote wakeup
67    pub remote_wakeup: bool,
68}