|
|
#include "usb_std.h" |
|
|
#include "usbd_core.h" |
|
|
#include "hid_transfer.h" |
|
|
|
|
|
|
|
|
ALIGNED_HEAD uint8_t g_hid_report[] ALIGNED_TAIL = |
|
|
{ |
|
|
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 |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_device_descriptor[USB_DEVICE_DESC_LEN] ALIGNED_TAIL = |
|
|
{ |
|
|
USB_DEVICE_DESC_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_DEVICE, // bDescriptorType |
|
|
#ifdef DAP_FW_V1 |
|
|
0x00, 0x02, // bcdUSB |
|
|
#else |
|
|
0x01, 0x02, // bcdUSB |
|
|
#endif |
|
|
0x00, // bDeviceClass |
|
|
0x00, // bDeviceSubClass |
|
|
0x00, // bDeviceProtocol |
|
|
USB_MAX_EP0_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 |
|
|
0x01 // bNumConfigurations |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD uint8_t g_config_descriptor[] ALIGNED_TAIL = |
|
|
{ |
|
|
USB_DEVICE_CFG_DESC_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_CONFIGURATION, // bDescriptorType |
|
|
#ifdef DAP_FW_V1 |
|
|
#define TOTAL_LEN_ (USB_DEVICE_CFG_DESC_LEN + (USB_DEVICE_IF_DESC_LEN + 0x09 + USB_DEVICE_EPT_LEN + USB_DEVICE_EPT_LEN)) |
|
|
#else |
|
|
#define TOTAL_LEN_ (USB_DEVICE_CFG_DESC_LEN + (USB_DEVICE_IF_DESC_LEN + USB_DEVICE_EPT_LEN + USB_DEVICE_EPT_LEN)) |
|
|
#endif |
|
|
#define TOTAL_LEN (TOTAL_LEN_ + (8 + USB_DEVICE_IF_DESC_LEN + 5 + 5 + 4 + 5 + USB_DEVICE_EPT_LEN + USB_DEVICE_IF_DESC_LEN + USB_DEVICE_EPT_LEN + USB_DEVICE_EPT_LEN)) |
|
|
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 |
|
|
USB_DEVICE_IF_DESC_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_INTERFACE, // bDescriptorType |
|
|
0x00, // bInterfaceNumber |
|
|
0x00, // bAlternateSetting |
|
|
0x02, // bNumEndpoints |
|
|
#ifdef DAP_FW_V1 |
|
|
0x03, // bInterfaceClass |
|
|
#else |
|
|
0xFF, // bInterfaceClass |
|
|
#endif |
|
|
0x00, // bInterfaceSubClass |
|
|
0x00, // bInterfaceProtocol |
|
|
0x05, // iInterface |
|
|
|
|
|
#ifdef DAP_FW_V1 |
|
|
// HID Descriptor |
|
|
0x09, // bLength |
|
|
HID_CLASS_DESC_HID, // bDescriptorType |
|
|
0x10, 0x01, // HID Class Spec |
|
|
0x00, // H/W target country. |
|
|
0x01, // Number of HID class descriptors to follow. |
|
|
HID_CLASS_DESC_REPORT, // Descriptor type. |
|
|
sizeof(g_hid_report) & 0xFF, 0x00, // 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. |
|
|
USB_DEVICE_EPT_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_ENDPOINT, // bDescriptorType |
|
|
HID_INT_OUT_EP, // bEndpointAddress |
|
|
#ifdef DAP_FW_V1 |
|
|
USB_EPT_DESC_INTERRUPT, // bmAttributes |
|
|
#else |
|
|
USB_EPT_DESC_BULK, // bmAttributes |
|
|
#endif |
|
|
HID_INT_OUT_SZ, 0x00, // wMaxPacketSize |
|
|
1, // bInterval |
|
|
|
|
|
// EP Descriptor: interrupt in. |
|
|
USB_DEVICE_EPT_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_ENDPOINT, // bDescriptorType |
|
|
HID_INT_IN_EP, // bEndpointAddress |
|
|
#ifdef DAP_FW_V1 |
|
|
USB_EPT_DESC_INTERRUPT, // bmAttributes |
|
|
#else |
|
|
USB_EPT_DESC_BULK, // bmAttributes |
|
|
#endif |
|
|
HID_INT_IN_SZ, 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 |
|
|
|
|
|
// I/F descriptor: CDC Control |
|
|
USB_DEVICE_IF_DESC_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_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 |
|
|
USB_DEVICE_EPT_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_ENDPOINT, // bDescriptorType |
|
|
CDC_INT_IN_EP, // bEndpointAddress |
|
|
USB_EPT_DESC_INTERRUPT, // bmAttributes |
|
|
CDC_INT_IN_SZ, 0x00, // wMaxPacketSize |
|
|
10, // bInterval |
|
|
|
|
|
// I/F descriptor: CDC Data |
|
|
USB_DEVICE_IF_DESC_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_INTERFACE, // bDescriptorType |
|
|
0x02, // bInterfaceNumber |
|
|
0x00, // bAlternateSetting |
|
|
0x02, // bNumEndpoints |
|
|
0x0A, // bInterfaceClass |
|
|
0x00, // bInterfaceSubClass |
|
|
0x00, // bInterfaceProtocol |
|
|
0x00, // iInterface |
|
|
|
|
|
// ENDPOINT descriptor |
|
|
USB_DEVICE_EPT_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_ENDPOINT, // bDescriptorType |
|
|
CDC_BULK_IN_EP, // bEndpointAddress |
|
|
USB_EPT_DESC_BULK, // bmAttributes |
|
|
CDC_BULK_IN_SZ, 0x00, // wMaxPacketSize |
|
|
0x00, // bInterval |
|
|
|
|
|
// ENDPOINT descriptor |
|
|
USB_DEVICE_EPT_LEN, // bLength |
|
|
USB_DESCIPTOR_TYPE_ENDPOINT, // bDescriptorType |
|
|
CDC_BULK_OUT_EP, // bEndpointAddress |
|
|
USB_EPT_DESC_BULK, // bmAttributes |
|
|
CDC_BULK_OUT_SZ, 0x00, // wMaxPacketSize |
|
|
0x00, // bInterval |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_langid_string[] ALIGNED_TAIL = |
|
|
{ |
|
|
4, |
|
|
USB_DESCIPTOR_TYPE_STRING, |
|
|
0x09, |
|
|
0x04, |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_vendor_string[] ALIGNED_TAIL = |
|
|
{ |
|
|
18, |
|
|
USB_DESCIPTOR_TYPE_STRING, |
|
|
'X', 0, 'I', 0, 'V', 0, 'N', 0, '1', 0, '9', 0, '8', 0, '7', 0 |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_product_string[] ALIGNED_TAIL = |
|
|
{ |
|
|
36, |
|
|
USB_DESCIPTOR_TYPE_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 |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_serial_string[] ALIGNED_TAIL = |
|
|
{ |
|
|
26, |
|
|
USB_DESCIPTOR_TYPE_STRING, |
|
|
'0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, 'A', 0, 'B', 0 |
|
|
}; |
|
|
|
|
|
|
|
|
ALIGNED_HEAD static uint8_t g_interface_string[] ALIGNED_TAIL = |
|
|
{ |
|
|
36, |
|
|
USB_DESCIPTOR_TYPE_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 |
|
|
}; |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_device_descriptor(void) |
|
|
{ |
|
|
static usbd_desc_t device_descriptor = |
|
|
{ |
|
|
sizeof(g_device_descriptor), |
|
|
g_device_descriptor |
|
|
}; |
|
|
|
|
|
return &device_descriptor; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t * get_device_qualifier(void) |
|
|
{ |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_config_descriptor(void) |
|
|
{ |
|
|
static usbd_desc_t config_descriptor = |
|
|
{ |
|
|
sizeof(g_config_descriptor), |
|
|
g_config_descriptor |
|
|
}; |
|
|
|
|
|
return &config_descriptor; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_langid_string(void) |
|
|
{ |
|
|
static usbd_desc_t langid_string = |
|
|
{ |
|
|
sizeof(g_langid_string), |
|
|
g_langid_string |
|
|
}; |
|
|
|
|
|
return &langid_string; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_vendor_string(void) |
|
|
{ |
|
|
static usbd_desc_t vendor_string = |
|
|
{ |
|
|
sizeof(g_vendor_string), |
|
|
g_vendor_string |
|
|
}; |
|
|
|
|
|
return &vendor_string; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_product_string(void) |
|
|
{ |
|
|
static usbd_desc_t product_string = |
|
|
{ |
|
|
sizeof(g_product_string), |
|
|
g_product_string |
|
|
}; |
|
|
|
|
|
return &product_string; |
|
|
} |
|
|
|
|
|
|
|
|
static void int_to_unicode(uint32_t value , uint8_t *pbuf , uint8_t len); |
|
|
static usbd_desc_t *get_serial_string(void) |
|
|
{ |
|
|
static usbd_desc_t serial_string = |
|
|
{ |
|
|
sizeof(g_serial_string), |
|
|
g_serial_string |
|
|
}; |
|
|
|
|
|
uint32_t serial0, serial1, serial2; |
|
|
serial0 = *(uint32_t*)0x1FFFF7E8; |
|
|
serial1 = *(uint32_t*)0x1FFFF7EC; |
|
|
serial2 = *(uint32_t*)0x1FFFF7F0; |
|
|
|
|
|
serial0 += serial2; |
|
|
|
|
|
if(serial0 != 0) |
|
|
{ |
|
|
int_to_unicode(serial0, &g_serial_string[2], 8); |
|
|
int_to_unicode(serial1, &g_serial_string[18], 4); |
|
|
} |
|
|
|
|
|
return &serial_string; |
|
|
} |
|
|
|
|
|
|
|
|
static usbd_desc_t *get_interface_string(void) |
|
|
{ |
|
|
static usbd_desc_t interface_string = |
|
|
{ |
|
|
sizeof(g_interface_string), |
|
|
g_interface_string |
|
|
}; |
|
|
|
|
|
return &interface_string; |
|
|
} |
|
|
|
|
|
|
|
|
usbd_desc_handler hid_desc_handler = |
|
|
{ |
|
|
get_device_descriptor, |
|
|
get_device_qualifier, |
|
|
get_config_descriptor, |
|
|
NULL, // get_device_other_speed |
|
|
get_langid_string, |
|
|
get_vendor_string, |
|
|
get_product_string, |
|
|
get_serial_string, |
|
|
get_interface_string, |
|
|
NULL, // get_device_config_string |
|
|
}; |
|
|
|
|
|
|
|
|
static void int_to_unicode(uint32_t value , uint8_t *pbuf , uint8_t len) |
|
|
{ |
|
|
for(int i = 0 ; i < len ; i++) |
|
|
{ |
|
|
if((value >> 28) < 0xA) |
|
|
{ |
|
|
pbuf[2 * i] = (value >> 28) + '0'; |
|
|
} |
|
|
else |
|
|
{ |
|
|
pbuf[2 * i] = (value >> 28) + 'A' - 10; |
|
|
} |
|
|
|
|
|
pbuf[2 * i + 1] = 0; |
|
|
|
|
|
value = value << 4; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t BOS_Descriptor[] = |
|
|
{ |
|
|
5, |
|
|
0x0F, |
|
|
5+20+8, 0, // wTotalLength |
|
|
1, // bNumDeviceCaps |
|
|
|
|
|
/*** MS OS 2.0 descriptor platform capability descriptor ***/ |
|
|
28, |
|
|
0x10, |
|
|
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 |
|
|
}; |
|
|
|
|
|
|
|
|
#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}" |
|
|
};
|
|
|
|