////TODO: refactoring into structure /** * @file USBd_config.c * @brief Standard USB Descriptor Definitions fix bugs 2020-1-23 * @version 0.2 * @date 2020-1-23 * * */ #include #include #include "USBd_config.h" #include "usb_defs.h" #define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF) /** * @brief step 1. Build Standard Device Descriptor * */ // Standard Device Descriptor const uint8_t kUSBd0DeviceDescriptor[0x12] = { 0x12, // bLength USB_DT_DEVICE, // bDescriptorType (constant) USBShort(0x0200), // bcdUSB (2.00) // We need to use a device other than the USB-IF standard, set to 0x00 0x00, // bDeviceClass 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol USBD0_MAX_PACKET0, // Maximum packet size for default pipe. USBShort(USBD0_DEV_DESC_IDVENDOR), // Vendor ID (VID). USBShort(USBD0_DEV_DESC_IDPRODUCT), // Product ID (PID). USBShort(USBD0_DEV_DESC_BCDDEVICE), // Device Version BCD. 0x01, // Index of Manufacturer string identifier. 0x02, // Index of Product string identifier. 0x03 * USBD0_STR_DESC_SER_EN, // Index of Product serial number. 0x01 // Number of configurations. }; /** * @brief step 2. Buid Standard Configuration Descriptor * */ // Standard Interface Descriptor const uint8_t kUSBd0InterfaceDescriptor[0x1E]= { 0x09, // bLength USB_DT_INTERFACE, // bDescriptorType USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting 0x03, // bNumEndpoints(we will use three endpoints) // USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol 0x00, // iInterface // Index of string descriptor describing this interface ////TODO: fix this 0x04 ? // Standard Endpoint Descriptor // Endpoint 1: Bulk Out – used for commands received from host PC. // Endpoint 2: Bulk In – used for responses send to host PC. // Endpoint 3: Bulk In (optional) – used for streaming SWO trace // ATTENTION: // physical endpoint 1 indeed included two "endpoints": Bulk OUT and Bulk IN // physical endpoint 1 -> Endpoint 1 & Endpoint 2 // physical endpoint 2 -> Endpoint 3 // See also : // http://www.keil.com/pack/doc/CMSIS/DAP/html/group__DAP__ConfigUSB__gr.html /* Pysical endpoint 1 */ // "Endpoint 1: Bulk Out – used for commands received from host PC." PC -> Device 0x07, // bLength USB_DT_ENDPOINT, // bDescriptorType 0x01, // bEndpointAddress USB_ENDPOINT_ATTR_BULK, // bmAttributes USBShort(512), // wMaxPacketSize // We assume that it always runs in High Speed. 0x00, // bInterval /* Pysical endpoint 1 */ // "Endpoint 2: Bulk In – used for responses send to host PC." Device -> PC 0x07, // bLength USB_DT_ENDPOINT, // bDescriptorType 0x81, // bEndpointAddress USB_ENDPOINT_ATTR_BULK, // bmAttributes USBShort(512), // wMaxPacketSize 0x00, // bInterval /* Pysical endpoint 2 */ // "Endpoint 3: Bulk In (optional) – used for streaming SWO trace" Device -> PC 0x07, // bLength USB_DT_ENDPOINT, // bDescriptorType 0x82, // bEndpointAddress USB_ENDPOINT_ATTR_BULK, // bmAttributes USBShort(512), // wMaxPacketSize 0x00, // bInterval }; // Standard Configuration Descriptor #define LENGTHOFCONFIGDESCRIPTOR 9 const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] = { // Configuration descriptor header. 0x09, // bLength -> 0x09?? may be ok... 1-23 0x03, // bDescriptorType // constant, set to 0x03 USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)), // wTotalLength 0x01, // bNumInterfaces // There is only one interface in the CMSIS-DAP project 0x01, // bConfigurationValue: 0x01 is used to select this configuration */ 0x00, // iConfiguration: no string to describe this configuration */ USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes USBD0_CFG_DESC_BMAXPOWER, // bMaxPower }; /** * @brief step 3. Build String Descriptor * */ const uint8_t kLangDescriptor[0x04] = { 4, USB_DT_STRING, USBShort(USB_LANGID_ENGLISH_US) }; /** * @brief We will use these string descriptor: * 1. Manufacturer string -> "KEIL - Tools By ARM" * 2. Product string -> "LPC-Link-II" * 3. Serial number string -> "0001A0000000" * 4. Interface string -> "LPC-Link-II CMSIS-DAP" * * */ const uint8_t kManufacturerString[0x28] = { 0x28, // bLength 0x03, // bDescriptorType // "KEIL - Tools By ARM" 'K', 0, 'E', 0, 'I', 0, 'L', 0, ' ', 0, '-', 0, ' ', 0, 'T', 0, 'o', 0, 'o', 0, 'l', 0, 's', 0, ' ', 0, 'B', 0, 'y', 0, ' ', 0, 'A', 0, 'R', 0, 'M', 0 }; const uint8_t kProductString[0x18] = { 0x18, // bLength 0x03, // bDescriptorType // "LPC-Link-II" 'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0, 'I', 0 }; const uint8_t kSerialNumberString[0x1A] = { 0x1A, // bLength 0x03, // bDescriptorType // "0001A0000000" '0', 0, '0', 0, '0', 0, '1', 0, 'A', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0 }; const uint8_t kInterfaceString[0x2C] = { 0x2C, // bLength 0x03, // bDescriptorType // "LPC-Link-II CMSIS-DAP" 'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0, 'I', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0, 'P', 0 }; const uint8_t * const kUSBd0StringDescriptorsSet[0x05] = { kLangDescriptor, kManufacturerString, kProductString, kSerialNumberString, kInterfaceString };