diff options
author | Ryan <fauxpark@gmail.com> | 2020-03-28 13:02:25 +1100 |
---|---|---|
committer | Florian Didron <fdidron@users.noreply.github.com> | 2020-06-12 17:00:27 +0900 |
commit | 0def4a9c08cb17107fc7b04a6989e2b8ad9d69ca (patch) | |
tree | e39edbafc2a5249cf07a5c38828b1d11e3148003 | |
parent | 18a7247336279798b5b4e06cbf256be5506cf566 (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.h | 47 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 248 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/vusb.h | 76 |
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 |