add note about bLength and bDescriptorType

This commit is contained in:
Jorge Aparicio 2020-07-16 18:05:01 +02:00
parent 7ab4fb0863
commit 1bb84dfed1
2 changed files with 10 additions and 4 deletions

View file

@ -14,6 +14,8 @@ The `Ep0In` API has two methods: `start` and `end` (also see their API documenta
To implement responding to a GET_DESCRIPTOR Device request, extend `usb-3.rs` so that it uses `Ep0In` to respond to the `GET_DESCRIPTOR Device` request (and only to that request). The response must be a device descriptor with its fields set to these values:
- `bLength = 18`, the size of the descriptor (must always be this value)
- `bDescriptorType = 1`, device descriptor type (must always be this value)
- `bDeviceClass = bDeviceSubClass = bDeviceProtocol = 0`, these are unimportant for enumeration
- `bMaxPacketSize0 = 64`, this is the most performant option (minimizes exchanges between the device and the host) and it's assumed by the `Ep0In` abstraction
- `idVendor = consts::VID`, value expected by the `usb-list` tool (\*)
@ -26,6 +28,8 @@ To implement responding to a GET_DESCRIPTOR Device request, extend `usb-3.rs` so
Although you can create the device descriptor by hand as an array filled with magic values we *strongly* recommend you use the `usb2::device::Descriptor` abstraction. The crate is already in the dependency list of the project; you can open its API documentation with the following command: `cargo doc -p usb2 --open`.
> NOTE: the `usb2::device::Descriptor` struct does not have `bLength` and `bDescriptorType` fields. Those fields have fixed values according to the USB spec so you cannot modify or set them. When `bytes()` is called on the `Descriptor` value the returned array, the binary representation of the descriptor, will contain those fields set to their correct value.
Note that the device descriptor is 18 bytes long but the host may ask for fewer bytes (see `wlength` field in the SETUP data). In that case you must respond with the amount of bytes the host asked for. The opposite may also happen: `wlength` may be larger than the size of the device descriptor; in this case your answer must be 18 bytes long (do *not* pad the response with zeroes).
Don't forget to also handle the `EP0DATADONE` event!

View file

@ -13,8 +13,8 @@ The configuration descriptor and one interface descriptor will be concatenated i
The configuration descriptor in the response should contain these fields:
- `bLength = 9`, the size of this descriptor (see table 9-10 in the USB spec)
- `bDescriptorType = 2`, configuration descriptor (see table 9-5 in the USB spec)
- `bLength = 9`, the size of this descriptor (must always be this value)
- `bDescriptorType = 2`, configuration descriptor type (must always be this value)
- `wTotalLength = 18` = one configuration descriptor (9 bytes) and one interface descriptor (9 bytes)
- `bNumInterfaces = 1`, a single interface (the minimum value)
- `bConfigurationValue = 42`, any non-zero value will do
@ -24,8 +24,8 @@ The configuration descriptor in the response should contain these fields:
The interface descriptor in the response should contain these fields:
- `bLength = 9`, the size of this descriptor (see table 9-11 in the USB spec)
- `bDescriptorType = 4`, interface descriptor (see table 9-5 in the USB spec)
- `bLength = 9`, the size of this descriptor (must always be this value)
- `bDescriptorType = 4`, interface descriptor type (must always be this value)
- `bInterfaceNumber = 0`, this is the first, and only, interface
- `bAlternateSetting = 0`, alternate settings are not supported
- `bNumEndpoints = 0`, no endpoint associated to this interface (other than the control endpoint)
@ -34,4 +34,6 @@ The interface descriptor in the response should contain these fields:
Again, we strongly recommend that you use the `usb2::configuration::Descriptor` and `usb2::interface::Descriptor` abstractions here. Each descriptor instance can be transformed into its byte representation using the `bytes` method -- the method returns an array. To concatenate both arrays you can use an stack-allocated [`heapless::Vec`] buffer. If you haven't the `heapless` crate before you can find example usage in the the `src/bin/vec.rs` file.
> NOTE: the `usb2::configuration::Descriptor` and `usb2::interface::Descriptor` structs do not have `bLength` and `bDescriptorType` fields. Those fields have fixed values according to the USB spec so you cannot modify or set them. When `bytes()` is called on the `Descriptor` value the returned array, the binary representation of the descriptor, will contain those fields set to their correct value.
[`heapless::Vec`]: https://docs.rs/heapless/0.5.5/heapless/struct.Vec.html