usb: improved descriptor building API

The same API call allocates interfaces/endpoints/etc and writes their descriptors.
This means less API calls, and less possibility to screw things up.

DescriptorWriter is now private.
This commit is contained in:
Dario Nieuwenhuis
2022-04-15 23:17:50 +02:00
parent 1bf7b4d6c3
commit 50d257cc7c
4 changed files with 230 additions and 241 deletions

View File

@ -175,26 +175,15 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
assert!(builder.control_buf_len() >= 7);
let comm_if = builder.alloc_interface_with_handler(control);
let comm_ep = builder.alloc_interrupt_endpoint_in(8, 255);
let data_if = builder.alloc_interface();
let read_ep = builder.alloc_bulk_endpoint_out(max_packet_size);
let write_ep = builder.alloc_bulk_endpoint_in(max_packet_size);
let mut func = builder.function(USB_CLASS_CDC, CDC_SUBCLASS_ACM, CDC_PROTOCOL_NONE);
builder.config_descriptor.iad(
comm_if,
2,
USB_CLASS_CDC,
CDC_SUBCLASS_ACM,
CDC_PROTOCOL_NONE,
);
builder.config_descriptor.interface(
comm_if,
USB_CLASS_CDC,
CDC_SUBCLASS_ACM,
CDC_PROTOCOL_NONE,
);
builder.config_descriptor.write(
// Control interface
let mut iface = func.interface(Some(control));
let comm_if = iface.interface_number();
let data_if = u8::from(comm_if) + 1;
let mut alt = iface.alt_setting(USB_CLASS_CDC, CDC_SUBCLASS_ACM, CDC_PROTOCOL_NONE);
alt.descriptor(
CS_INTERFACE,
&[
CDC_TYPE_HEADER, // bDescriptorSubtype
@ -202,14 +191,14 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
0x01, // bcdCDC (1.10)
],
);
builder.config_descriptor.write(
alt.descriptor(
CS_INTERFACE,
&[
CDC_TYPE_ACM, // bDescriptorSubtype
0x00, // bmCapabilities
],
);
builder.config_descriptor.write(
alt.descriptor(
CS_INTERFACE,
&[
CDC_TYPE_UNION, // bDescriptorSubtype
@ -217,7 +206,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
data_if.into(), // bSubordinateInterface
],
);
builder.config_descriptor.write(
alt.descriptor(
CS_INTERFACE,
&[
CDC_TYPE_CALL_MANAGEMENT, // bDescriptorSubtype
@ -225,13 +214,15 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
data_if.into(), // bDataInterface
],
);
builder.config_descriptor.endpoint(comm_ep.info());
builder
.config_descriptor
.interface(data_if, USB_CLASS_CDC_DATA, 0x00, 0x00);
builder.config_descriptor.endpoint(write_ep.info());
builder.config_descriptor.endpoint(read_ep.info());
let comm_ep = alt.endpoint_interrupt_in(8, 255);
// Data interface
let mut iface = func.interface(None);
let data_if = iface.interface_number();
let mut alt = iface.alt_setting(USB_CLASS_CDC_DATA, 0x00, CDC_PROTOCOL_NONE);
let read_ep = alt.endpoint_bulk_out(max_packet_size);
let write_ep = alt.endpoint_bulk_in(max_packet_size);
CdcAcmClass {
_comm_ep: comm_ep,