|
|
#include "NuMicro.h" |
|
|
#include "hid_transfer.h" |
|
|
|
|
|
|
|
|
uint8_t HID_DeviceReportDescriptor[] = |
|
|
{ |
|
|
0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1) |
|
|
0x09, 0x01, // Usage (Vendor Usage 1) |
|
|
0xA1, 0x01, // Collection (Application) |
|
|
0x19, 0x01, // Usage Minimum |
|
|
0x29, 0x40, // Usage Maximum //64 input usages total (0x01 to 0x40) |
|
|
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00) |
|
|
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255) |
|
|
0x75, 0x08, // Report Size: 8-bit field size |
|
|
0x95, 0x40, // Report Count: Make sixty-four 8-bit fields (the next time the parser hits an "Input", "Output", or "Feature" item) |
|
|
0x81, 0x00, // Input (Data, Array, Abs): Instantiates input packet fields based on the above report size, count, logical min/max, and usage. |
|
|
0x19, 0x01, // Usage Minimum |
|
|
0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40) |
|
|
0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same report size and count as "Input" fields, since nothing new/different was specified to the parser since the "Input" item. |
|
|
0xC0 // End Collection |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t gu8DeviceDescriptor[] = |
|
|
{ |
|
|
LEN_DEVICE, // bLength |
|
|
DESC_DEVICE, // bDescriptorType |
|
|
#ifdef DAP_FW_V1 |
|
|
0x00, 0x02, // bcdUSB |
|
|
#else |
|
|
0x01, 0x02, // bcdUSB |
|
|
#endif |
|
|
0x00, // bDeviceClass |
|
|
0x00, // bDeviceSubClass |
|
|
0x00, // bDeviceProtocol |
|
|
EP0_MAX_PKT_SIZE, // bMaxPacketSize0 |
|
|
USBD_VID & 0xFF, USBD_VID >> 8, // idVendor |
|
|
USBD_PID & 0xFF, USBD_PID >> 8, // idProduct |
|
|
0x10, 0x01, // bcdDevice |
|
|
0x01, // iManufacture |
|
|
0x02, // iProduct |
|
|
0x03, // iSerialNumber - no serial |
|
|
0x01 // bNumConfigurations |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t gu8ConfigDescriptor[] = |
|
|
{ |
|
|
LEN_CONFIG, // bLength |
|
|
DESC_CONFIG, // bDescriptorType |
|
|
#ifdef DAP_FW_V1 |
|
|
#define TOTAL_LEN_0 (LEN_CONFIG + (LEN_INTERFACE + LEN_HID + LEN_ENDPOINT + LEN_ENDPOINT)) |
|
|
#else |
|
|
#define TOTAL_LEN_0 (LEN_CONFIG + (LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT)) |
|
|
#endif |
|
|
#define TOTAL_LEN (TOTAL_LEN_0 + (8 + LEN_INTERFACE + 5 + 5 + 4 + 5 + LEN_ENDPOINT + LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT)) |
|
|
TOTAL_LEN & 0xFF, TOTAL_LEN >> 8, // wTotalLength |
|
|
(1 + 2), // bNumInterfaces |
|
|
0x01, // bConfigurationValue |
|
|
0x00, // iConfiguration |
|
|
0x00, // bmAttributes, D6: self power D5: remote wake-up |
|
|
0x64, // MaxPower, 100 * 2mA = 200mA |
|
|
|
|
|
// I/F descriptor: HID |
|
|
LEN_INTERFACE, // bLength |
|
|
DESC_INTERFACE, // bDescriptorType |
|
|
0x00, // bInterfaceNumber |
|
|
0x00, // bAlternateSetting |
|
|
0x02, // bNumEndpoints |
|
|
#ifdef DAP_FW_V1 |
|
|
0x03, // bInterfaceClass |
|
|
#else |
|
|
0xFF, // bInterfaceClass |
|
|
#endif |
|
|
0x00, // bInterfaceSubClass |
|
|
0x00, // bInterfaceProtocol |
|
|
0x04, // iInterface |
|
|
|
|
|
#ifdef DAP_FW_V1 |
|
|
// HID Descriptor |
|
|
LEN_HID, // bLength |
|
|
DESC_HID, // bDescriptorType |
|
|
0x10, 0x01, // HID Class Spec |
|
|
0x00, // H/W target country. |
|
|
0x01, // Number of HID class descriptors to follow. |
|
|
DESC_HID_RPT, // Descriptor type. |
|
|
sizeof(HID_DeviceReportDescriptor) & 0xFF, sizeof(HID_DeviceReportDescriptor) >> 8, // Total length of report descriptor. |
|
|
#endif |
|
|
|
|
|
// CMSIS-DAP v2 WinUSB Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD> Bulk OUT<EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD> Bulk IN |
|
|
// EP Descriptor: interrupt out. |
|
|
LEN_ENDPOINT, // bLength |
|
|
DESC_ENDPOINT, // bDescriptorType |
|
|
(EP_OUTPUT | HID_INT_OUT_EP), // bEndpointAddress |
|
|
#ifdef DAP_FW_V1 |
|
|
EP_INT, // bmAttributes |
|
|
#else |
|
|
EP_BULK, // bmAttributes |
|
|
#endif |
|
|
EP3_MAX_PKT_SIZE, 0x00, // wMaxPacketSize |
|
|
1, // bInterval |
|
|
|
|
|
// EP Descriptor: interrupt in. |
|
|
LEN_ENDPOINT, // bLength |
|
|
DESC_ENDPOINT, // bDescriptorType |
|
|
(EP_INPUT | HID_INT_IN_EP), // bEndpointAddress |
|
|
#ifdef DAP_FW_V1 |
|
|
EP_INT, // bmAttributes |
|
|
#else |
|
|
EP_BULK, // bmAttributes |
|
|
#endif |
|
|
EP2_MAX_PKT_SIZE, 0x00, // wMaxPacketSize |
|
|
1, // bInterval |
|
|
|
|
|
// Interface Association Descriptor (IAD) |
|
|
0x08, // bLength |
|
|
0x0B, // bDescriptorType: IAD |
|
|
0x01, // bFirstInterface |
|
|
0x02, // bInterfaceCount |
|
|
0x02, // bFunctionClass: CDC |
|
|
0x02, // bFunctionSubClass |
|
|
0x01, // bFunctionProtocol |
|
|
0x00, // iFunction, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> |
|
|
|
|
|
// I/F descriptor: VCOM |
|
|
LEN_INTERFACE, // bLength |
|
|
DESC_INTERFACE, // bDescriptorType |
|
|
0x01, // bInterfaceNumber |
|
|
0x00, // bAlternateSetting |
|
|
0x01, // bNumEndpoints |
|
|
0x02, // bInterfaceClass |
|
|
0x02, // bInterfaceSubClass |
|
|
0x01, // bInterfaceProtocol |
|
|
0x00, // iInterface |
|
|
|
|
|
// Communication Class Specified INTERFACE descriptor |
|
|
0x05, // Size of the descriptor, in bytes |
|
|
0x24, // CS_INTERFACE descriptor type |
|
|
0x00, // Header functional descriptor subtype |
|
|
0x10, 0x01, // Communication device compliant to the communication spec. ver. 1.10 |
|
|
|
|
|
// Communication Class Specified INTERFACE descriptor |
|
|
0x05, // Size of the descriptor, in bytes |
|
|
0x24, // CS_INTERFACE descriptor type |
|
|
0x01, // Call management functional descriptor |
|
|
0x00, // BIT0: Whether device handle call management itself. |
|
|
// BIT1: Whether device can send/receive call management information over a Data Class Interface 0 |
|
|
0x02, // Interface number of data class interface optionally used for call management |
|
|
|
|
|
// Communication Class Specified INTERFACE descriptor |
|
|
0x04, // Size of the descriptor, in bytes |
|
|
0x24, // CS_INTERFACE descriptor type |
|
|
0x02, // Abstract control management functional descriptor subtype |
|
|
0x00, // bmCapabilities |
|
|
|
|
|
// Communication Class Specified INTERFACE descriptor |
|
|
0x05, // bLength |
|
|
0x24, // bDescriptorType: CS_INTERFACE descriptor type |
|
|
0x06, // bDescriptorSubType |
|
|
0x01, // bMasterInterface |
|
|
0x02, // bSlaveInterface0 |
|
|
|
|
|
// ENDPOINT descriptor |
|
|
LEN_ENDPOINT, // bLength |
|
|
DESC_ENDPOINT, // bDescriptorType |
|
|
(EP_INPUT | CDC_INT_IN_EP), // bEndpointAddress |
|
|
EP_INT, // bmAttributes |
|
|
EP4_MAX_PKT_SIZE, 0x00, // wMaxPacketSize |
|
|
10, // bInterval |
|
|
|
|
|
// I/F descriptor |
|
|
LEN_INTERFACE, // bLength |
|
|
DESC_INTERFACE, // bDescriptorType |
|
|
0x02, // bInterfaceNumber |
|
|
0x00, // bAlternateSetting |
|
|
0x02, // bNumEndpoints |
|
|
0x0A, // bInterfaceClass |
|
|
0x00, // bInterfaceSubClass |
|
|
0x00, // bInterfaceProtocol |
|
|
0x00, // iInterface |
|
|
|
|
|
// ENDPOINT descriptor |
|
|
LEN_ENDPOINT, // bLength |
|
|
DESC_ENDPOINT, // bDescriptorType |
|
|
(EP_INPUT | CDC_BULK_IN_EP), // bEndpointAddress |
|
|
EP_BULK, // bmAttributes |
|
|
EP5_MAX_PKT_SIZE, 0x00, // wMaxPacketSize |
|
|
0x00, // bInterval |
|
|
|
|
|
// ENDPOINT descriptor |
|
|
LEN_ENDPOINT, // bLength |
|
|
DESC_ENDPOINT, // bDescriptorType |
|
|
(EP_OUTPUT | CDC_BULK_OUT_EP), // bEndpointAddress |
|
|
EP_BULK, // bmAttributes |
|
|
EP6_MAX_PKT_SIZE, 0x00, // wMaxPacketSize |
|
|
0x00, // bInterval |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t gu8StringLang[] = |
|
|
{ |
|
|
4, |
|
|
DESC_STRING, |
|
|
0x09, 0x04 |
|
|
}; |
|
|
|
|
|
uint8_t gu8VendorStringDesc[] = |
|
|
{ |
|
|
18, |
|
|
DESC_STRING, |
|
|
'X', 0, 'I', 0, 'V', 0, 'N', 0, '1', 0, '9', 0, '8', 0, '7', 0 |
|
|
}; |
|
|
|
|
|
uint8_t gu8ProductStringDesc[] = |
|
|
{ |
|
|
36, |
|
|
DESC_STRING, |
|
|
'X', 0, 'V', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0, 'P', 0 |
|
|
}; |
|
|
|
|
|
uint8_t gu8SerialNumStringDesc[] = |
|
|
{ |
|
|
26, |
|
|
DESC_STRING, |
|
|
'0', 0, '0', 0, '2', 0, '2', 0, '0', 0, '1', 0, '1', 0, '1', 0, '0', 0, '0', 0, '0', 0, '0', 0 |
|
|
}; |
|
|
|
|
|
uint8_t gu8InterfaceStringDesc[] = |
|
|
{ |
|
|
36, |
|
|
DESC_STRING, |
|
|
'X', 0, 'V', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0, 'P', 0 |
|
|
}; |
|
|
|
|
|
uint8_t *gpu8UsbString[] = |
|
|
{ |
|
|
gu8StringLang, |
|
|
gu8VendorStringDesc, |
|
|
gu8ProductStringDesc, |
|
|
gu8SerialNumStringDesc, |
|
|
gu8InterfaceStringDesc, |
|
|
NULL, |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t *gu8UsbHidReport[] = |
|
|
{ |
|
|
HID_DeviceReportDescriptor, |
|
|
NULL, |
|
|
}; |
|
|
|
|
|
uint32_t gu32UsbHidReportLen[] = |
|
|
{ |
|
|
sizeof(HID_DeviceReportDescriptor), |
|
|
0, |
|
|
}; |
|
|
|
|
|
uint32_t gu32ConfigHidDescIdx[] = |
|
|
{ |
|
|
(LEN_CONFIG + LEN_INTERFACE), |
|
|
0, |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t gu8BOSDescriptor[] = |
|
|
{ |
|
|
5, |
|
|
DESC_BOS, |
|
|
5+20+8, 0, // wTotalLength |
|
|
1, // bNumDeviceCaps |
|
|
|
|
|
/*** MS OS 2.0 descriptor platform capability descriptor ***/ |
|
|
28, |
|
|
DESC_CAPABILITY, |
|
|
5, // bDevCapabilityType: PLATFORM (05H) |
|
|
0x00, |
|
|
0xDF, 0x60, 0xDD, 0xD8, // PlatformCapabilityUUID: MS_OS_20_Platform_Capability_ID (D8DD60DF-4589-4CC7-9CD2-659D9E648A9F) |
|
|
0x89, 0x45, 0xC7, 0x4C, |
|
|
0x9C, 0xD2, 0x65, 0x9D, |
|
|
0x9E, 0x64, 0x8A, 0x9F, |
|
|
|
|
|
0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: 0x06030000 for Windows 8.1 |
|
|
10+8+20+128, 0x00, // wTotalLength: size of MS OS 2.0 descriptor set |
|
|
WINUSB_VENDOR_CODE, // bMS_VendorCode |
|
|
0x00, // bAltEnumCmd |
|
|
}; |
|
|
|
|
|
|
|
|
const S_USBD_INFO_T gsInfo = |
|
|
{ |
|
|
(uint8_t *)gu8DeviceDescriptor, |
|
|
(uint8_t *)gu8ConfigDescriptor, |
|
|
(uint8_t **)gpu8UsbString, |
|
|
(uint8_t **)gu8UsbHidReport, |
|
|
(uint8_t *)gu8BOSDescriptor, |
|
|
(uint32_t *)gu32UsbHidReportLen, |
|
|
(uint32_t *)gu32ConfigHidDescIdx |
|
|
}; |
|
|
|
|
|
|
|
|
#define MS_OS_20_SET_HEADER_DESCRIPTOR 0x00 |
|
|
#define MS_OS_20_SUBSET_HEADER_CONFIGURATION 0x01 |
|
|
#define MS_OS_20_SUBSET_HEADER_FUNCTION 0x02 |
|
|
#define MS_OS_20_FEATURE_COMPATIBLE_ID 0x03 |
|
|
#define MS_OS_20_FEATURE_REG_PROPERTY 0x04 |
|
|
#define MS_OS_20_FEATURE_MIN_RESUME_TIME 0x05 |
|
|
#define MS_OS_20_FEATURE_MODEL_ID 0x06 |
|
|
#define MS_OS_20_FEATURE_CCGP_DEVICE 0x07 |
|
|
#define MS_OS_20_FEATURE_VENDOR_REVISION 0x08 |
|
|
|
|
|
uint8_t MS_OS_20_DescriptorSet[] = |
|
|
{ |
|
|
/*** Microsoft OS 2.0 Descriptor Set Header ***/ |
|
|
10, 0, |
|
|
MS_OS_20_SET_HEADER_DESCRIPTOR, 0, |
|
|
0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: 0x06030000 for Windows 8.1 |
|
|
10+8+20+128, 0, // wTotalLength |
|
|
|
|
|
/*** Microsoft OS 2.0 function subset header ***/ |
|
|
8, 0, |
|
|
MS_OS_20_SUBSET_HEADER_FUNCTION, 0, |
|
|
0, // bFirstInterface, first interface to which this subset applies |
|
|
0, |
|
|
8+20+128, 0, // wSubsetLength |
|
|
|
|
|
/*** Microsoft OS 2.0 compatible ID descriptor ***/ |
|
|
20, 0, |
|
|
MS_OS_20_FEATURE_COMPATIBLE_ID, 0, |
|
|
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // CompatibleID |
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SubCompatibleID |
|
|
|
|
|
/*** MS OS 2.0 registry property descriptor ***/ |
|
|
128, 0, |
|
|
MS_OS_20_FEATURE_REG_PROPERTY, 0, |
|
|
1, 0, // wPropertyDataType: 1 = Unicode REG_SZ |
|
|
40, 0x00, // wPropertyNameLength |
|
|
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, |
|
|
'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, 'G', 0, 'U', 0, 'I', 0, 'D', 0, 0, 0, // PropertyName: "DeviceInterfaceGUID" |
|
|
78, 0x00, // wPropertyDataLength |
|
|
'{', 0, 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, |
|
|
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, |
|
|
'A', 0, 'A', 0, '3', 0, '6', 0, '-', 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, |
|
|
'6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, '}', 0, 0, 0, // PropertyData: "{CDB3B5AD-293B-4663-AA36-1AAE46463776}" |
|
|
};
|
|
|
|