|
|
@ -349,134 +349,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, |
|
|
|
.bNumInterfaces = 1, |
|
|
|
# endif |
|
|
|
1, /* index of this configuration */ |
|
|
|
0, /* configuration name string index */ |
|
|
|
.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; |
|
|
|
|
|
|
@ -489,42 +529,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 |
|
|
|
} |
|
|
|