From 68168393b9ea61328f4bb43bc3059ab32c4be2e9 Mon Sep 17 00:00:00 2001 From: Karel Bilek Date: Sun, 17 Dec 2017 03:54:48 +0100 Subject: [PATCH] Add USB 2.1 (WebUSB preparation) Most code taken from https://github.com/devanlai/dap42 and https://github.com/devanlai/dapboot --- usb21_standard.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ usb21_standard.h | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 usb21_standard.c create mode 100644 usb21_standard.h diff --git a/usb21_standard.c b/usb21_standard.c new file mode 100644 index 0000000..7ed1986 --- /dev/null +++ b/usb21_standard.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, Devan Lai + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include "util.h" +#include "usb21_standard.h" + +static uint16_t build_bos_descriptor(const struct usb_bos_descriptor *bos, + uint8_t *buf, uint16_t len) +{ + uint8_t *tmpbuf = buf; + uint16_t count, total = 0, totallen = 0; + uint16_t i; + + memcpy(buf, bos, count = MIN(len, bos->bLength)); + buf += count; + len -= count; + total += count; + totallen += bos->bLength; + + /* For each device capability */ + for (i = 0; i < bos->bNumDeviceCaps; i++) { + /* Copy device capability descriptor. */ + const struct usb_device_capability_descriptor *cap = + bos->capabilities[i]; + + memcpy(buf, cap, count = MIN(len, cap->bLength)); + buf += count; + len -= count; + total += count; + totallen += cap->bLength; + } + + /* Fill in wTotalLength. */ + *(uint16_t *)(tmpbuf + 2) = totallen; + + return total; +} + +static const struct usb_bos_descriptor* usb21_bos; + +static int usb21_standard_get_descriptor(usbd_device* usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len, + usbd_control_complete_callback* complete) { + (void)complete; + (void)usbd_dev; + + if (req->bRequest == USB_REQ_GET_DESCRIPTOR) { + int descr_type = req->wValue >> 8; + if (descr_type == USB_DT_BOS) { + if (!usb21_bos) { + return USBD_REQ_NOTSUPP; + } + *len = MIN(*len, build_bos_descriptor(usb21_bos, *buf, *len)); + return USBD_REQ_HANDLED; + } + } + + return USBD_REQ_NEXT_CALLBACK; +} + +static void usb21_set_config(usbd_device* usbd_dev, uint16_t wValue) { + (void)wValue; + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, + USB_REQ_TYPE_DIRECTION | USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + &usb21_standard_get_descriptor); +} + +void usb21_setup(usbd_device* usbd_dev, const struct usb_bos_descriptor* binary_object_store) { + usb21_bos = binary_object_store; + + /* Register the control request handler _before_ the config is set */ + usb21_set_config(usbd_dev, 0x0000); + usbd_register_set_config_callback(usbd_dev, usb21_set_config); +} diff --git a/usb21_standard.h b/usb21_standard.h new file mode 100644 index 0000000..e7578a5 --- /dev/null +++ b/usb21_standard.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, Devan Lai + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef USB21_STANDARD_H_INCLUDED +#define USB21_STANDARD_H_INCLUDED + +#include + +/* USB 3.1 Descriptor Types - Table 9-6 */ +#define USB_DT_BOS 15 +#define USB_DT_DEVICE_CAPABILITY 16 +#define USB_DT_SUPERSPEED_USB_ENDPOINT_COMPANION 48 +#define USB_DT_SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION 49 + +struct usb_device_capability_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; +} __attribute__((packed)); + +struct usb_bos_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; + /* Descriptor ends here. The following are used internally: */ + const struct usb_device_capability_descriptor **capabilities; +} __attribute__((packed)); + +#define USB_DT_BOS_SIZE 5 + +/* USB Device Capability Types - USB 3.1 Table 9-14 */ +#define USB_DC_WIRELESS_USB 1 +#define USB_DC_USB_2_0_EXTENSION 2 +#define USB_DC_SUPERSPEED_USB 3 +#define USB_DC_CONTAINER_ID 4 +#define USB_DC_PLATFORM 5 +#define USB_DC_POWER_DELIVERY_CAPABILITY 6 +#define USB_DC_BATTERY_INFO_CAPABILITY 7 +#define USB_DC_PD_CONSUMER_PORT_CAPABILITY 8 +#define USB_DC_PD_PROVIDER_PORT_CAPABILITY 9 +#define USB_DC_SUPERSPEED_PLUS 10 +#define USB_DC_PRECISION_TIME_MEASUREMENT 11 +#define USB_DC_WIRELESS_USB_EXT 12 + +extern void usb21_setup(usbd_device* usbd_dev, const struct usb_bos_descriptor* binary_object_store); + +#endif