summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2020-03-28 13:02:25 +1100
committerFlorian Didron <fdidron@users.noreply.github.com>2020-06-12 17:00:27 +0900
commit0def4a9c08cb17107fc7b04a6989e2b8ad9d69ca (patch)
treee39edbafc2a5249cf07a5c38828b1d11e3148003
parent18a7247336279798b5b4e06cbf256be5506cf566 (diff)
V-USB: Use structs for USB descriptors (#8572)
* V-USB: Use structs for USB descriptors * Update usbconfigs * cformat pass
-rw-r--r--quantum/template/ps2avrgb/usbconfig.h47
-rw-r--r--tmk_core/protocol/vusb/vusb.c248
-rw-r--r--tmk_core/protocol/vusb/vusb.h76
3 files changed, 227 insertions, 144 deletions
diff --git a/quantum/template/ps2avrgb/usbconfig.h b/quantum/template/ps2avrgb/usbconfig.h
index 83ad06544d..6e910a7038 100644
--- a/quantum/template/ps2avrgb/usbconfig.h
+++ b/quantum/template/ps2avrgb/usbconfig.h
@@ -197,7 +197,7 @@ section at the end of this file).
/* -------------------------- Device Description --------------------------- */
-#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
+#define USB_CFG_VENDOR_ID
/* USB vendor ID for the device, low byte first. If you have registered your
* own Vendor ID, define it here. Otherwise you may use one of obdev's free
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
@@ -206,7 +206,7 @@ section at the end of this file).
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
* the implications!
*/
-#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
+#define USB_CFG_DEVICE_ID
/* This is the ID of the product, low byte first. It is interpreted in the
* scope of the vendor ID. If you have registered your own VID with usb.org
* or if you have licensed a PID from somebody else, define it here. Otherwise
@@ -217,34 +217,6 @@ section at the end of this file).
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
* the implications!
*/
-#define USB_CFG_DEVICE_VERSION (DEVICE_VER & 0xFF), ((DEVICE_VER >> 8) & 0xFF)
-/* Version number of the device: Minor number first, then major number.
- */
-#define USB_CFG_VENDOR_NAME 'w', 'i', 'n', 'k', 'e', 'y', 'l', 'e', 's', 's', '.', 'k', 'r'
-#define USB_CFG_VENDOR_NAME_LEN 13
-/* These two values define the vendor name returned by the USB device. The name
- * must be given as a list of characters under single quotes. The characters
- * are interpreted as Unicode (UTF-16) entities.
- * If you don't want a vendor name string, undefine these macros.
- * ALWAYS define a vendor name containing your Internet domain name if you use
- * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
- * details.
- */
-#define USB_CFG_DEVICE_NAME 'p', 's', '2', 'a', 'v', 'r', 'G', 'B'
-#define USB_CFG_DEVICE_NAME_LEN 8
-/* Same as above for the device name. If you don't want a device name, undefine
- * the macros. See the file USB-IDs-for-free.txt before you assign a name if
- * you use a shared VID/PID.
- */
-/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
-/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
-/* Same as above for the serial number. If you don't want a serial number,
- * undefine the macros.
- * It may be useful to provide the serial number through other means than at
- * compile time. See the section about descriptor properties below for how
- * to fine tune control over USB descriptors such as the string descriptor
- * for the serial number.
- */
#define USB_CFG_DEVICE_CLASS 0
#define USB_CFG_DEVICE_SUBCLASS 0
/* See USB specification if you want to conform to an existing device class.
@@ -323,18 +295,15 @@ section at the end of this file).
* };
*/
-#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_DEVICE USB_PROP_IS_DYNAMIC
#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
-//#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
-#define USB_CFG_DESCR_PROPS_STRINGS 0
-#define USB_CFG_DESCR_PROPS_STRING_0 0
-#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
-#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
-#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#define USB_CFG_DESCR_PROPS_STRINGS USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_0 USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER USB_PROP_IS_DYNAMIC
#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
-//#define USB_CFG_DESCR_PROPS_HID 0
#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
-//#define USB_CFG_DESCR_PROPS_HID_REPORT 0
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
#define usbMsgPtr_t unsigned short
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 69f2c12e3f..c89aa849d2 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -360,134 +360,174 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
#endif
// clang-format off
-const PROGMEM usbStringDescriptor_t usbDescriptorStringZero = {
+const PROGMEM usbStringDescriptor_t usbStringDescriptorZero = {
.header = {
- .bLength = USB_STRING_LEN(1),
+ .bLength = USB_STRING_LEN(1),
.bDescriptorType = USBDESCR_STRING
},
- .bString = {0x0409} // US English
+ .bString = {0x0409} // US English
};
-const PROGMEM usbStringDescriptor_t usbDescriptorStringManufacturer = {
+const PROGMEM usbStringDescriptor_t usbStringDescriptorManufacturer = {
.header = {
- .bLength = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1),
+ .bLength = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1),
.bDescriptorType = USBDESCR_STRING
},
- .bString = LSTR(MANUFACTURER)
+ .bString = LSTR(MANUFACTURER)
};
-const PROGMEM usbStringDescriptor_t usbDescriptorStringProduct = {
+const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
.header = {
- .bLength = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1),
+ .bLength = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1),
.bDescriptorType = USBDESCR_STRING
},
- .bString = LSTR(PRODUCT)
+ .bString = LSTR(PRODUCT)
};
-const PROGMEM usbStringDescriptor_t usbDescriptorStringSerial = {
+const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = {
.header = {
- .bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1),
+ .bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1),
.bDescriptorType = USBDESCR_STRING
},
- .bString = LSTR(SERIAL_NUMBER)
+ .bString = LSTR(SERIAL_NUMBER)
};
-// clang-format on
+#if USB_CFG_DESCR_PROPS_DEVICE
/*
- * Descriptor for compite device: Keyboard + Mouse
- *
- * contains: device, interface, HID and endpoint descriptors
+ * Device descriptor
*/
+const PROGMEM usbDeviceDescriptor_t usbDeviceDescriptor = {
+ .header = {
+ .bLength = sizeof(usbDeviceDescriptor_t),
+ .bDescriptorType = USBDESCR_DEVICE
+ },
+ .bcdUSB = 0x0110,
+ .bDeviceClass = USB_CFG_DEVICE_CLASS,
+ .bDeviceSubClass = USB_CFG_DEVICE_SUBCLASS,
+ .bDeviceProtocol = 0x00,
+ .bMaxPacketSize0 = 8,
+ .idVendor = VENDOR_ID,
+ .idProduct = PRODUCT_ID,
+ .bcdDevice = DEVICE_VER,
+ .iManufacturer = 0x01,
+ .iProduct = 0x02,
+ .iSerialNumber = 0x03,
+ .bNumConfigurations = 1
+};
+#endif
+
#if USB_CFG_DESCR_PROPS_CONFIGURATION
-const PROGMEM char usbDescriptorConfiguration[] = {
- /* USB configuration descriptor */
- 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
- USBDESCR_CONFIG, /* descriptor type */
-# if defined (MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
- 59, // 9 + (9 + 9 + 7) + (9 + 9 + 7)
-#else
- 34, // 9 + (9 + 9 + 7)
-# endif
- 0,
- // 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
- /* total length of data returned (including inlined descriptors) */
+/*
+ * Configuration descriptors
+ */
+const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
+ .header = {
+ .header = {
+ .bLength = sizeof(usbConfigurationDescriptorHeader_t),
+ .bDescriptorType = USBDESCR_CONFIG
+ },
+ .wTotalLength = sizeof(usbConfigurationDescriptor_t),
# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
- 2, /* number of interfaces in this configuration */
+ .bNumInterfaces = 2,
# else
- 1,
-#endif
- 1, /* index of this configuration */
- 0, /* configuration name string index */
+ .bNumInterfaces = 1,
+# endif
+ .bConfigurationValue = 0x01,
+ .iConfiguration = 0x00,
# if USB_CFG_IS_SELF_POWERED
- (1 << 7) | USBATTR_SELFPOWER, /* attributes */
+ .bmAttributes = (1 << 7) | USBATTR_SELFPOWER,
# else
- (1 << 7), /* attributes */
+ .bmAttributes = (1 << 7),
# endif
- USB_MAX_POWER_CONSUMPTION / 2, /* max USB current in 2mA units */
+ .bMaxPower = USB_MAX_POWER_CONSUMPTION / 2
+ },
/*
- * Keyboard interface
+ * Keyboard
*/
- /* Interface descriptor */
- 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
- USBDESCR_INTERFACE, /* descriptor type */
- 0, /* index of this interface */
- 0, /* alternate setting for this interface */
- USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */
- USB_CFG_INTERFACE_CLASS, USB_CFG_INTERFACE_SUBCLASS, USB_CFG_INTERFACE_PROTOCOL, 0, /* string index for interface */
- /* HID descriptor */
- 9, /* sizeof(usbDescrHID): length of descriptor in bytes */
- USBDESCR_HID, /* descriptor type: HID */
- 0x01, 0x01, /* BCD representation of HID version */
- 0x00, /* target country code */
- 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */
- 0x22, /* descriptor type: report */
- sizeof(keyboard_hid_report), 0, /* total length of report descriptor */
-/* Endpoint descriptor */
-# if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */
- 7, /* sizeof(usbDescrEndpoint) */
- USBDESCR_ENDPOINT, /* descriptor type = endpoint */
- (char)0x81, /* IN endpoint number 1 */
- 0x03, /* attrib: Interrupt endpoint */
- 8, 0, /* maximum packet size */
- USB_POLLING_INTERVAL_MS, /* in ms */
+ .keyboardInterface = {
+ .header = {
+ .bLength = sizeof(usbInterfaceDescriptor_t),
+ .bDescriptorType = USBDESCR_INTERFACE
+ },
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = USB_CFG_HAVE_INTRIN_ENDPOINT,
+ .bInterfaceClass = USB_CFG_INTERFACE_CLASS,
+ .bInterfaceSubClass = USB_CFG_INTERFACE_SUBCLASS,
+ .bInterfaceProtocol = USB_CFG_INTERFACE_PROTOCOL,
+ .iInterface = 0x00
+ },
+ .keyboardHID = {
+ .header = {
+ .bLength = sizeof(usbHIDDescriptor_t),
+ .bDescriptorType = USBDESCR_HID
+ },
+ .bcdHID = 0x0101,
+ .bCountryCode = 0x00,
+ .bNumDescriptors = 1,
+ .bDescriptorType = USBDESCR_HID_REPORT,
+ .wDescriptorLength = sizeof(keyboard_hid_report)
+ },
+# ifdef USB_CFG_HAVE_INTRIN_ENDPOINT
+ .keyboardINEndpoint = {
+ .header = {
+ .bLength = sizeof(usbEndpointDescriptor_t),
+ .bDescriptorType = USBDESCR_ENDPOINT
+ },
+ .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | 1),
+ .bmAttributes = 0x03,
+ .wMaxPacketSize = 8,
+ .bInterval = USB_POLLING_INTERVAL_MS
+ },
# endif
# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
/*
- * Mouse/extrakeys interface
+ * Mouse/Extrakeys
*/
- /* Interface descriptor */
- 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
- USBDESCR_INTERFACE, /* descriptor type */
- 1, /* index of this interface */
- 0, /* alternate setting for this interface */
- USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */
- 0x03, /* CLASS: HID */
- 0, /* SUBCLASS: none */
- 0, /* PROTOCOL: none */
- 0, /* string index for interface */
- /* HID descriptor */
- 9, /* sizeof(usbDescrHID): length of descriptor in bytes */
- USBDESCR_HID, /* descriptor type: HID */
- 0x01, 0x01, /* BCD representation of HID version */
- 0x00, /* target country code */
- 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */
- 0x22, /* descriptor type: report */
- sizeof(mouse_extra_hid_report), 0, /* total length of report descriptor */
-# if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
- /* Endpoint descriptor */
- 7, /* sizeof(usbDescrEndpoint) */
- USBDESCR_ENDPOINT, /* descriptor type = endpoint */
- (char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
- 0x03, /* attrib: Interrupt endpoint */
- 8, 0, /* maximum packet size */
- USB_POLLING_INTERVAL_MS, /* in ms */
+ .mouseExtraInterface = {
+ .header = {
+ .bLength = sizeof(usbInterfaceDescriptor_t),
+ .bDescriptorType = USBDESCR_INTERFACE
+ },
+ .bInterfaceNumber = 1,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = USB_CFG_HAVE_INTRIN_ENDPOINT3,
+ .bInterfaceClass = 0x03,
+ .bInterfaceSubClass = 0x00,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = 0x00
+ },
+ .mouseExtraHID = {
+ .header = {
+ .bLength = sizeof(usbHIDDescriptor_t),
+ .bDescriptorType = USBDESCR_HID
+ },
+ .bcdHID = 0x0101,
+ .bCountryCode = 0x00,
+ .bNumDescriptors = 1,
+ .bDescriptorType = USBDESCR_HID_REPORT,
+ .wDescriptorLength = sizeof(mouse_extra_hid_report)
+ },
+# if USB_CFG_HAVE_INTRIN_ENDPOINT3
+ .mouseExtraINEndpoint = {
+ .header = {
+ .bLength = sizeof(usbEndpointDescriptor_t),
+ .bDescriptorType = USBDESCR_ENDPOINT
+ },
+ .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
+ .bmAttributes = 0x03,
+ .wMaxPacketSize = 8,
+ .bInterval = USB_POLLING_INTERVAL_MS
+ }
# endif
# endif
};
#endif
+// clang-format on
+
USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
usbMsgLen_t len = 0;
@@ -500,42 +540,48 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
debug_hex16(rq->wLength.word); debug("\n");
*/
switch (rq->wValue.bytes[1]) {
+#if USB_CFG_DESCR_PROPS_DEVICE
+ case USBDESCR_DEVICE:
+ usbMsgPtr = (unsigned char *)&usbDeviceDescriptor;
+ len = sizeof(usbDeviceDescriptor_t);
+ break;
+#endif
#if USB_CFG_DESCR_PROPS_CONFIGURATION
case USBDESCR_CONFIG:
- usbMsgPtr = (unsigned char *)usbDescriptorConfiguration;
- len = sizeof(usbDescriptorConfiguration);
+ usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor;
+ len = sizeof(usbConfigurationDescriptor_t);
break;
#endif
case USBDESCR_STRING:
switch (rq->wValue.bytes[0]) {
case 0:
- usbMsgPtr = (unsigned char *)&usbDescriptorStringZero;
- len = usbDescriptorStringZero.header.bLength;
+ usbMsgPtr = (unsigned char *)&usbStringDescriptorZero;
+ len = usbStringDescriptorZero.header.bLength;
break;
case 1: // iManufacturer
- usbMsgPtr = (unsigned char *)&usbDescriptorStringManufacturer;
- len = usbDescriptorStringManufacturer.header.bLength;
+ usbMsgPtr = (unsigned char *)&usbStringDescriptorManufacturer;
+ len = usbStringDescriptorManufacturer.header.bLength;
break;
case 2: // iProduct
- usbMsgPtr = (unsigned char *)&usbDescriptorStringProduct;
- len = usbDescriptorStringProduct.header.bLength;
+ usbMsgPtr = (unsigned char *)&usbStringDescriptorProduct;
+ len = usbStringDescriptorProduct.header.bLength;
break;
case 3: // iSerialNumber
- usbMsgPtr = (unsigned char *)&usbDescriptorStringSerial;
- len = usbDescriptorStringSerial.header.bLength;
+ usbMsgPtr = (unsigned char *)&usbStringDescriptorSerial;
+ len = usbStringDescriptorSerial.header.bLength;
break;
}
break;
case USBDESCR_HID:
switch (rq->wValue.bytes[0]) {
case 0:
- usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9);
- len = 9;
+ usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.keyboardHID;
+ len = sizeof(usbHIDDescriptor_t);
break;
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
case 1:
- usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9);
- len = 9;
+ usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID;
+ len = sizeof(usbHIDDescriptor_t);
break;
#endif
}
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h
index cee07207a3..debac67d24 100644
--- a/tmk_core/protocol/vusb/vusb.h
+++ b/tmk_core/protocol/vusb/vusb.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef VUSB_H
-#define VUSB_H
+#pragma once
#include "host_driver.h"
@@ -25,14 +24,83 @@ typedef struct usbDescriptorHeader {
uchar bDescriptorType;
} __attribute__((packed)) usbDescriptorHeader_t;
+typedef struct usbDeviceDescriptor {
+ usbDescriptorHeader_t header;
+ unsigned bcdUSB;
+ uchar bDeviceClass;
+ uchar bDeviceSubClass;
+ uchar bDeviceProtocol;
+ uchar bMaxPacketSize0;
+ unsigned idVendor;
+ unsigned idProduct;
+ unsigned bcdDevice;
+ uchar iManufacturer;
+ uchar iProduct;
+ uchar iSerialNumber;
+ uchar bNumConfigurations;
+} __attribute__((packed)) usbDeviceDescriptor_t;
+
+typedef struct usbConfigurationDescriptorHeader {
+ usbDescriptorHeader_t header;
+ unsigned wTotalLength;
+ uchar bNumInterfaces;
+ uchar bConfigurationValue;
+ uchar iConfiguration;
+ uchar bmAttributes;
+ uchar bMaxPower;
+} __attribute__((packed)) usbConfigurationDescriptorHeader_t;
+
typedef struct usbStringDescriptor {
usbDescriptorHeader_t header;
int bString[];
} __attribute__((packed)) usbStringDescriptor_t;
+typedef struct usbInterfaceDescriptor {
+ usbDescriptorHeader_t header;
+ uchar bInterfaceNumber;
+ uchar bAlternateSetting;
+ uchar bNumEndpoints;
+ uchar bInterfaceClass;
+ uchar bInterfaceSubClass;
+ uchar bInterfaceProtocol;
+ uchar iInterface;
+} __attribute__((packed)) usbInterfaceDescriptor_t;
+
+typedef struct usbEndpointDescriptor {
+ usbDescriptorHeader_t header;
+ uchar bEndpointAddress;
+ uchar bmAttributes;
+ unsigned wMaxPacketSize;
+ uchar bInterval;
+} __attribute__((packed)) usbEndpointDescriptor_t;
+
+typedef struct usbHIDDescriptor {
+ usbDescriptorHeader_t header;
+ unsigned bcdHID;
+ uchar bCountryCode;
+ uchar bNumDescriptors;
+ uchar bDescriptorType;
+ unsigned wDescriptorLength;
+} __attribute__((packed)) usbHIDDescriptor_t;
+
+typedef struct usbConfigurationDescriptor {
+ usbConfigurationDescriptorHeader_t header;
+ usbInterfaceDescriptor_t keyboardInterface;
+ usbHIDDescriptor_t keyboardHID;
+#ifdef USB_CFG_HAVE_INTRIN_ENDPOINT
+ usbEndpointDescriptor_t keyboardINEndpoint;
+#endif
+
+#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
+ usbInterfaceDescriptor_t mouseExtraInterface;
+ usbHIDDescriptor_t mouseExtraHID;
+# ifdef USB_CFG_HAVE_INTRIN_ENDPOINT3
+ usbEndpointDescriptor_t mouseExtraINEndpoint;
+# endif
+#endif
+} __attribute__((packed)) usbConfigurationDescriptor_t;
+
#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
host_driver_t *vusb_driver(void);
void vusb_transfer_keyboard(void);
-
-#endif