Hopefully without breaking the others. Summary of the changes: - Device descriptor reports the device is bus powered and requires 100mA max. - HID descriptor version bumped to 1.11 (was 1.10) - Added string index for Interface and HID descriptors (which seems to make OS X happy)
156 lines
7.2 KiB
Diff
156 lines
7.2 KiB
Diff
diff --git a/capsules/Cargo.toml b/capsules/Cargo.toml
|
|
index 65301bcf1..dc70e98b1 100644
|
|
--- a/capsules/Cargo.toml
|
|
+++ b/capsules/Cargo.toml
|
|
@@ -8,3 +8,6 @@ edition = "2021"
|
|
kernel = { path = "../kernel" }
|
|
enum_primitive = { path = "../libraries/enum_primitive" }
|
|
tickv = { path = "../libraries/tickv" }
|
|
+
|
|
+[features]
|
|
+vendor_hid = []
|
|
diff --git a/capsules/src/usb/descriptors.rs b/capsules/src/usb/descriptors.rs
|
|
index 9c5bc9cd1..c3ed71c44 100644
|
|
--- a/capsules/src/usb/descriptors.rs
|
|
+++ b/capsules/src/usb/descriptors.rs
|
|
@@ -415,13 +415,14 @@ impl DescriptorBuffer {
|
|
/// example, if the interface descriptor list contains `[ID1, ID2, ID3]`,
|
|
/// and the endpoint descriptors list is `[[ED1, ED2], [ED3, ED4, ED5],
|
|
/// [ED6]]`, then the third interface descriptor (`ID3`) has one
|
|
-/// corresponding endpoint descriptor (`ED6`).
|
|
+/// corresponding endpoint descriptor (`ED6`). If supplied, each HID descriptor
|
|
+/// corresponds to the matching index in the interface descriptor list.
|
|
pub fn create_descriptor_buffers(
|
|
device_descriptor: DeviceDescriptor,
|
|
mut configuration_descriptor: ConfigurationDescriptor,
|
|
interface_descriptor: &mut [InterfaceDescriptor],
|
|
endpoint_descriptors: &[&[EndpointDescriptor]],
|
|
- hid_descriptor: Option<&HIDDescriptor>,
|
|
+ hid_descriptor: Option<&[&HIDDescriptor<'static>]>,
|
|
cdc_descriptor: Option<&[CdcInterfaceDescriptor]>,
|
|
) -> (DeviceBuffer, DescriptorBuffer) {
|
|
// Create device descriptor buffer and fill.
|
|
@@ -505,7 +506,7 @@ pub fn create_descriptor_buffers(
|
|
.iter()
|
|
.map(|descs| descs.iter().map(|d| d.size()).sum::<usize>())
|
|
.sum::<usize>()
|
|
- + hid_descriptor.map_or(0, |d| d.size())
|
|
+ + hid_descriptor.map_or(0, |ds| ds.iter().map(|d| d.size()).sum::<usize>())
|
|
+ cdc_descriptor.map_or(0, |ds| ds.iter().map(|d| d.size()).sum::<usize>());
|
|
|
|
// Set the number of endpoints for each interface descriptor.
|
|
@@ -522,12 +523,10 @@ pub fn create_descriptor_buffers(
|
|
// Add the interface descriptor.
|
|
len += d.write_to(&other_buf.buf[len..]);
|
|
|
|
- // If there is a HID descriptor, we include
|
|
- // it with the first interface descriptor.
|
|
- if i == 0 {
|
|
- // HID descriptor, if any.
|
|
- if let Some(dh) = hid_descriptor {
|
|
- len += dh.write_to(&other_buf.buf[len..]);
|
|
+ // HID descriptor, if present, for this interface.
|
|
+ if let Some(dh) = hid_descriptor {
|
|
+ if let Some(d) = dh.get(i) {
|
|
+ len += d.write_to(&other_buf.buf[len..]);
|
|
}
|
|
}
|
|
|
|
diff --git a/capsules/src/usb/usbc_client_ctrl.rs b/capsules/src/usb/usbc_client_ctrl.rs
|
|
index c8e55a8a8..54c7c3bbb 100644
|
|
--- a/capsules/src/usb/usbc_client_ctrl.rs
|
|
+++ b/capsules/src/usb/usbc_client_ctrl.rs
|
|
@@ -40,6 +40,12 @@ const DESCRIPTOR_BUFLEN: usize = 128;
|
|
|
|
const N_ENDPOINTS: usize = 3;
|
|
|
|
+#[cfg(feature = "vendor_hid")]
|
|
+const N_HID_INTERFACES: usize = 2;
|
|
+
|
|
+#[cfg(not(feature = "vendor_hid"))]
|
|
+const N_HID_INTERFACES: usize = 1;
|
|
+
|
|
/// Handler for USB control endpoint requests.
|
|
pub struct ClientCtrl<'a, 'b, U: 'a> {
|
|
/// The USB hardware controller.
|
|
@@ -66,12 +72,12 @@ pub struct ClientCtrl<'a, 'b, U: 'a> {
|
|
|
|
/// An optional HID descriptor for the configuration. This can be requested
|
|
/// separately. It must also be included in `other_descriptor_buffer` if it exists.
|
|
- hid_descriptor: Option<&'b HIDDescriptor<'b>>,
|
|
+ hid_descriptor: Option<[&'b HIDDescriptor<'b>; N_HID_INTERFACES]>,
|
|
|
|
/// An optional report descriptor for the configuration. This can be
|
|
/// requested separately. It must also be included in
|
|
/// `other_descriptor_buffer` if it exists.
|
|
- report_descriptor: Option<&'b ReportDescriptor<'b>>,
|
|
+ report_descriptor: Option<[&'b ReportDescriptor<'b>; N_HID_INTERFACES]>,
|
|
|
|
/// Supported language (only one for now).
|
|
language: &'b [u16; 1],
|
|
@@ -106,8 +112,8 @@ impl<'a, 'b, U: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, U> {
|
|
controller: &'a U,
|
|
device_descriptor_buffer: DeviceBuffer,
|
|
other_descriptor_buffer: DescriptorBuffer,
|
|
- hid_descriptor: Option<&'b HIDDescriptor<'b>>,
|
|
- report_descriptor: Option<&'b ReportDescriptor<'b>>,
|
|
+ hid_descriptor: Option<[&'b HIDDescriptor<'b>; N_HID_INTERFACES]>,
|
|
+ report_descriptor: Option<[&'b ReportDescriptor<'b>; N_HID_INTERFACES]>,
|
|
language: &'b [u16; 1],
|
|
strings: &'b [&'b str],
|
|
) -> Self {
|
|
@@ -333,28 +339,39 @@ impl<'a, 'b, U: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, U> {
|
|
descriptor_type,
|
|
// TODO: use the descriptor index
|
|
descriptor_index: _,
|
|
- // TODO: use the language ID?
|
|
- lang_id: _,
|
|
+ lang_id,
|
|
requested_length,
|
|
} => match descriptor_type {
|
|
DescriptorType::HID => {
|
|
- if let Some(desc) = self.hid_descriptor {
|
|
- let buf = self.descriptor_buf();
|
|
- let len = desc.write_to(buf);
|
|
- let end = min(len, requested_length as usize);
|
|
- self.state[endpoint].set(State::CtrlIn(0, end));
|
|
- hil::usb::CtrlSetupResult::Ok
|
|
+ if let Some(dh) = self.hid_descriptor {
|
|
+ let interface = lang_id as usize;
|
|
+ if interface < dh.len() {
|
|
+ let d = dh[interface];
|
|
+ let buf = self.descriptor_buf();
|
|
+ let len = d.write_to(buf);
|
|
+ let end = min(len, requested_length as usize);
|
|
+ self.state[endpoint].set(State::CtrlIn(0, end));
|
|
+ hil::usb::CtrlSetupResult::Ok
|
|
+ } else {
|
|
+ hil::usb::CtrlSetupResult::ErrGeneric
|
|
+ }
|
|
} else {
|
|
hil::usb::CtrlSetupResult::ErrGeneric
|
|
}
|
|
}
|
|
DescriptorType::Report => {
|
|
- if let Some(desc) = self.report_descriptor {
|
|
- let buf = self.descriptor_buf();
|
|
- let len = desc.write_to(buf);
|
|
- let end = min(len, requested_length as usize);
|
|
- self.state[endpoint].set(State::CtrlIn(0, end));
|
|
- hil::usb::CtrlSetupResult::Ok
|
|
+ if let Some(desc_array) = self.report_descriptor {
|
|
+ let interface = lang_id as usize;
|
|
+ if interface < desc_array.len() {
|
|
+ let desc = desc_array[interface];
|
|
+ let buf = self.descriptor_buf();
|
|
+ let len = desc.write_to(buf);
|
|
+ let end = min(len, requested_length as usize);
|
|
+ self.state[endpoint].set(State::CtrlIn(0, end));
|
|
+ hil::usb::CtrlSetupResult::Ok
|
|
+ } else {
|
|
+ hil::usb::CtrlSetupResult::ErrGeneric
|
|
+ }
|
|
} else {
|
|
hil::usb::CtrlSetupResult::ErrGeneric
|
|
}
|