A Composite device with USBSerial and USBKeyboard

Dependents:   USBSerialKeyboard_Example

Committer:
p3p
Date:
Sat Mar 30 12:27:31 2013 +0000
Revision:
1:9367d07d0707
Parent:
0:93ff83b03fd8
Initial Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3p 0:93ff83b03fd8 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
p3p 0:93ff83b03fd8 2 *
p3p 0:93ff83b03fd8 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
p3p 0:93ff83b03fd8 4 * and associated documentation files (the "Software"), to deal in the Software without
p3p 0:93ff83b03fd8 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
p3p 0:93ff83b03fd8 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
p3p 0:93ff83b03fd8 7 * Software is furnished to do so, subject to the following conditions:
p3p 0:93ff83b03fd8 8 *
p3p 0:93ff83b03fd8 9 * The above copyright notice and this permission notice shall be included in all copies or
p3p 0:93ff83b03fd8 10 * substantial portions of the Software.
p3p 0:93ff83b03fd8 11 *
p3p 0:93ff83b03fd8 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
p3p 0:93ff83b03fd8 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
p3p 0:93ff83b03fd8 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
p3p 0:93ff83b03fd8 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
p3p 0:93ff83b03fd8 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
p3p 0:93ff83b03fd8 17 */
p3p 0:93ff83b03fd8 18
p3p 0:93ff83b03fd8 19 #include "stdint.h"
p3p 0:93ff83b03fd8 20 #include "USBCDCHID.h"
p3p 0:93ff83b03fd8 21
p3p 0:93ff83b03fd8 22
p3p 0:93ff83b03fd8 23 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
p3p 0:93ff83b03fd8 24
p3p 0:93ff83b03fd8 25 #define DEFAULT_CONFIGURATION (1)
p3p 0:93ff83b03fd8 26
p3p 0:93ff83b03fd8 27 #define CDC_SET_LINE_CODING 0x20
p3p 0:93ff83b03fd8 28 #define CDC_GET_LINE_CODING 0x21
p3p 0:93ff83b03fd8 29 #define CDC_SET_CONTROL_LINE_STATE 0x22
p3p 0:93ff83b03fd8 30
p3p 0:93ff83b03fd8 31 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
p3p 0:93ff83b03fd8 32
p3p 0:93ff83b03fd8 33 USBCDCHID::USBCDCHID(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
p3p 0:93ff83b03fd8 34 terminal_connected = false;
p3p 0:93ff83b03fd8 35 USBDevice::connect();
p3p 0:93ff83b03fd8 36 }
p3p 0:93ff83b03fd8 37
p3p 0:93ff83b03fd8 38 bool USBCDCHID::USBCallback_request(void) {
p3p 0:93ff83b03fd8 39 /* Called in ISR context */
p3p 0:93ff83b03fd8 40
p3p 0:93ff83b03fd8 41 bool success = false;
p3p 0:93ff83b03fd8 42 CONTROL_TRANSFER * transfer = getTransferPtr();
p3p 0:93ff83b03fd8 43
p3p 0:93ff83b03fd8 44 uint8_t *hidDescriptor;
p3p 0:93ff83b03fd8 45 // Process additional standard requests
p3p 0:93ff83b03fd8 46
p3p 0:93ff83b03fd8 47 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
p3p 0:93ff83b03fd8 48 {
p3p 0:93ff83b03fd8 49 switch (transfer->setup.bRequest)
p3p 0:93ff83b03fd8 50 {
p3p 0:93ff83b03fd8 51 case GET_DESCRIPTOR:
p3p 0:93ff83b03fd8 52 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
p3p 0:93ff83b03fd8 53 {
p3p 0:93ff83b03fd8 54 case REPORT_DESCRIPTOR:
p3p 0:93ff83b03fd8 55 if ((reportDesc() != NULL) && (reportDescLength() != 0))
p3p 0:93ff83b03fd8 56 {
p3p 0:93ff83b03fd8 57 transfer->remaining = reportDescLength();
p3p 0:93ff83b03fd8 58 transfer->ptr = reportDesc();
p3p 0:93ff83b03fd8 59 transfer->direction = DEVICE_TO_HOST;
p3p 0:93ff83b03fd8 60 success = true;
p3p 0:93ff83b03fd8 61
p3p 0:93ff83b03fd8 62 }
p3p 0:93ff83b03fd8 63 break;
p3p 0:93ff83b03fd8 64 case HID_DESCRIPTOR:
p3p 0:93ff83b03fd8 65 // Find the HID descriptor, after the configuration descriptor
p3p 0:93ff83b03fd8 66 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
p3p 0:93ff83b03fd8 67 if (hidDescriptor != NULL)
p3p 0:93ff83b03fd8 68 {
p3p 0:93ff83b03fd8 69 transfer->remaining = HID_DESCRIPTOR_LENGTH;
p3p 0:93ff83b03fd8 70 transfer->ptr = hidDescriptor;
p3p 0:93ff83b03fd8 71 transfer->direction = DEVICE_TO_HOST;
p3p 0:93ff83b03fd8 72 success = true;
p3p 0:93ff83b03fd8 73
p3p 0:93ff83b03fd8 74 }
p3p 0:93ff83b03fd8 75 break;
p3p 0:93ff83b03fd8 76
p3p 0:93ff83b03fd8 77 default:
p3p 0:93ff83b03fd8 78 break;
p3p 0:93ff83b03fd8 79 }
p3p 0:93ff83b03fd8 80 break;
p3p 0:93ff83b03fd8 81 default:
p3p 0:93ff83b03fd8 82 break;
p3p 0:93ff83b03fd8 83 }
p3p 0:93ff83b03fd8 84 }
p3p 0:93ff83b03fd8 85
p3p 0:93ff83b03fd8 86 /* Process class-specific requests */
p3p 0:93ff83b03fd8 87 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
p3p 0:93ff83b03fd8 88 switch (transfer->setup.bRequest) {
p3p 0:93ff83b03fd8 89 case CDC_GET_LINE_CODING:
p3p 0:93ff83b03fd8 90 transfer->remaining = 7;
p3p 0:93ff83b03fd8 91 transfer->ptr = cdc_line_coding;
p3p 0:93ff83b03fd8 92 transfer->direction = DEVICE_TO_HOST;
p3p 0:93ff83b03fd8 93 success = true;
p3p 0:93ff83b03fd8 94 break;
p3p 0:93ff83b03fd8 95 case CDC_SET_LINE_CODING:
p3p 0:93ff83b03fd8 96 transfer->remaining = 7;
p3p 0:93ff83b03fd8 97 success = true;
p3p 0:93ff83b03fd8 98 terminal_connected = true;
p3p 0:93ff83b03fd8 99 break;
p3p 0:93ff83b03fd8 100 case CDC_SET_CONTROL_LINE_STATE:
p3p 0:93ff83b03fd8 101 if (terminal_connected)
p3p 0:93ff83b03fd8 102 terminal_connected = false;
p3p 0:93ff83b03fd8 103 success = true;
p3p 0:93ff83b03fd8 104 break;
p3p 0:93ff83b03fd8 105 case SET_REPORT:
p3p 0:93ff83b03fd8 106 // First byte will be used for report ID
p3p 0:93ff83b03fd8 107 outputReport.data[0] = transfer->setup.wValue & 0xff;
p3p 0:93ff83b03fd8 108 outputReport.length = transfer->setup.wLength + 1;
p3p 0:93ff83b03fd8 109
p3p 0:93ff83b03fd8 110 transfer->remaining = sizeof(outputReport.data) - 1;
p3p 0:93ff83b03fd8 111 transfer->ptr = &outputReport.data[1];
p3p 0:93ff83b03fd8 112 transfer->direction = HOST_TO_DEVICE;
p3p 0:93ff83b03fd8 113 transfer->notify = true;
p3p 0:93ff83b03fd8 114 success = true;
p3p 0:93ff83b03fd8 115 default:
p3p 0:93ff83b03fd8 116 break;
p3p 0:93ff83b03fd8 117 }
p3p 0:93ff83b03fd8 118 }
p3p 0:93ff83b03fd8 119
p3p 0:93ff83b03fd8 120 return success;
p3p 0:93ff83b03fd8 121 }
p3p 0:93ff83b03fd8 122
p3p 0:93ff83b03fd8 123
p3p 0:93ff83b03fd8 124 // Called in ISR context
p3p 0:93ff83b03fd8 125 // Set configuration. Return false if the
p3p 0:93ff83b03fd8 126 // configuration is not supported.
p3p 0:93ff83b03fd8 127 bool USBCDCHID::USBCallback_setConfiguration(uint8_t configuration) {
p3p 0:93ff83b03fd8 128 if (configuration != DEFAULT_CONFIGURATION) {
p3p 0:93ff83b03fd8 129 return false;
p3p 0:93ff83b03fd8 130 }
p3p 0:93ff83b03fd8 131
p3p 0:93ff83b03fd8 132 // Configure endpoints > 0
p3p 0:93ff83b03fd8 133 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
p3p 0:93ff83b03fd8 134 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
p3p 0:93ff83b03fd8 135 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
p3p 0:93ff83b03fd8 136 addEndpoint(EPINT_OUT, MAX_HID_REPORT_SIZE);
p3p 0:93ff83b03fd8 137
p3p 0:93ff83b03fd8 138 // We activate the endpoints to be able to recceive data
p3p 0:93ff83b03fd8 139 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
p3p 0:93ff83b03fd8 140 readStart(EPINT_OUT, MAX_HID_REPORT_SIZE);
p3p 0:93ff83b03fd8 141 return true;
p3p 0:93ff83b03fd8 142 }
p3p 0:93ff83b03fd8 143
p3p 0:93ff83b03fd8 144 bool USBCDCHID::send(uint8_t * buffer, uint32_t size) {
p3p 0:93ff83b03fd8 145 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
p3p 0:93ff83b03fd8 146 }
p3p 0:93ff83b03fd8 147
p3p 0:93ff83b03fd8 148 bool USBCDCHID::readEP(uint8_t * buffer, uint32_t * size) {
p3p 0:93ff83b03fd8 149 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
p3p 0:93ff83b03fd8 150 return false;
p3p 0:93ff83b03fd8 151 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
p3p 0:93ff83b03fd8 152 return false;
p3p 0:93ff83b03fd8 153 return true;
p3p 0:93ff83b03fd8 154 }
p3p 0:93ff83b03fd8 155
p3p 0:93ff83b03fd8 156 bool USBCDCHID::readEP_NB(uint8_t * buffer, uint32_t * size) {
p3p 0:93ff83b03fd8 157 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
p3p 0:93ff83b03fd8 158 return false;
p3p 0:93ff83b03fd8 159 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
p3p 0:93ff83b03fd8 160 return false;
p3p 0:93ff83b03fd8 161 return true;
p3p 0:93ff83b03fd8 162 }
p3p 0:93ff83b03fd8 163
p3p 0:93ff83b03fd8 164 uint8_t * USBCDCHID::reportDesc() {
p3p 0:93ff83b03fd8 165 static uint8_t reportDescriptor[] = {
p3p 0:93ff83b03fd8 166 USAGE_PAGE(1), 0x01, // Generic Desktop
p3p 0:93ff83b03fd8 167 USAGE(1), 0x06, // Keyboard
p3p 0:93ff83b03fd8 168 COLLECTION(1), 0x01, // Application
p3p 0:93ff83b03fd8 169 REPORT_ID(1), REPORT_ID_KEYBOARD,
p3p 0:93ff83b03fd8 170
p3p 0:93ff83b03fd8 171 USAGE_PAGE(1), 0x07, // Key Codes
p3p 0:93ff83b03fd8 172 USAGE_MINIMUM(1), 0xE0,
p3p 0:93ff83b03fd8 173 USAGE_MAXIMUM(1), 0xE7,
p3p 0:93ff83b03fd8 174 LOGICAL_MINIMUM(1), 0x00,
p3p 0:93ff83b03fd8 175 LOGICAL_MAXIMUM(1), 0x01,
p3p 0:93ff83b03fd8 176 REPORT_SIZE(1), 0x01,
p3p 0:93ff83b03fd8 177 REPORT_COUNT(1), 0x08,
p3p 0:93ff83b03fd8 178 INPUT(1), 0x02, // Data, Variable, Absolute
p3p 0:93ff83b03fd8 179 REPORT_COUNT(1), 0x01,
p3p 0:93ff83b03fd8 180 REPORT_SIZE(1), 0x08,
p3p 0:93ff83b03fd8 181 INPUT(1), 0x01, // Constant
p3p 0:93ff83b03fd8 182
p3p 0:93ff83b03fd8 183
p3p 0:93ff83b03fd8 184 REPORT_COUNT(1), 0x05,
p3p 0:93ff83b03fd8 185 REPORT_SIZE(1), 0x01,
p3p 0:93ff83b03fd8 186 USAGE_PAGE(1), 0x08, // LEDs
p3p 0:93ff83b03fd8 187 USAGE_MINIMUM(1), 0x01,
p3p 0:93ff83b03fd8 188 USAGE_MAXIMUM(1), 0x05,
p3p 0:93ff83b03fd8 189 OUTPUT(1), 0x02, // Data, Variable, Absolute
p3p 0:93ff83b03fd8 190 REPORT_COUNT(1), 0x01,
p3p 0:93ff83b03fd8 191 REPORT_SIZE(1), 0x03,
p3p 0:93ff83b03fd8 192 OUTPUT(1), 0x01, // Constant
p3p 0:93ff83b03fd8 193
p3p 0:93ff83b03fd8 194
p3p 0:93ff83b03fd8 195 REPORT_COUNT(1), 0x06,
p3p 0:93ff83b03fd8 196 REPORT_SIZE(1), 0x08,
p3p 0:93ff83b03fd8 197 LOGICAL_MINIMUM(1), 0x00,
p3p 0:93ff83b03fd8 198 LOGICAL_MAXIMUM(1), 0x65,
p3p 0:93ff83b03fd8 199 USAGE_PAGE(1), 0x07, // Key Codes
p3p 0:93ff83b03fd8 200 USAGE_MINIMUM(1), 0x00,
p3p 0:93ff83b03fd8 201 USAGE_MAXIMUM(1), 0x65,
p3p 0:93ff83b03fd8 202 INPUT(1), 0x00, // Data, Array
p3p 0:93ff83b03fd8 203 END_COLLECTION(0),
p3p 0:93ff83b03fd8 204
p3p 0:93ff83b03fd8 205 // Media Control
p3p 0:93ff83b03fd8 206 USAGE_PAGE(1), 0x0C,
p3p 0:93ff83b03fd8 207 USAGE(1), 0x01,
p3p 0:93ff83b03fd8 208 COLLECTION(1), 0x01,
p3p 0:93ff83b03fd8 209 REPORT_ID(1), REPORT_ID_VOLUME,
p3p 0:93ff83b03fd8 210 USAGE_PAGE(1), 0x0C,
p3p 0:93ff83b03fd8 211 LOGICAL_MINIMUM(1), 0x00,
p3p 0:93ff83b03fd8 212 LOGICAL_MAXIMUM(1), 0x01,
p3p 0:93ff83b03fd8 213 REPORT_SIZE(1), 0x01,
p3p 0:93ff83b03fd8 214 REPORT_COUNT(1), 0x07,
p3p 0:93ff83b03fd8 215 USAGE(1), 0xB5, // Next Track
p3p 0:93ff83b03fd8 216 USAGE(1), 0xB6, // Previous Track
p3p 0:93ff83b03fd8 217 USAGE(1), 0xB7, // Stop
p3p 0:93ff83b03fd8 218 USAGE(1), 0xCD, // Play / Pause
p3p 0:93ff83b03fd8 219 USAGE(1), 0xE2, // Mute
p3p 0:93ff83b03fd8 220 USAGE(1), 0xE9, // Volume Up
p3p 0:93ff83b03fd8 221 USAGE(1), 0xEA, // Volume Down
p3p 0:93ff83b03fd8 222 INPUT(1), 0x02, // Input (Data, Variable, Absolute)
p3p 0:93ff83b03fd8 223 REPORT_COUNT(1), 0x01,
p3p 0:93ff83b03fd8 224 INPUT(1), 0x01,
p3p 0:93ff83b03fd8 225 END_COLLECTION(0),
p3p 0:93ff83b03fd8 226 };
p3p 0:93ff83b03fd8 227 reportLength = sizeof(reportDescriptor);
p3p 0:93ff83b03fd8 228 return reportDescriptor;
p3p 0:93ff83b03fd8 229 }
p3p 0:93ff83b03fd8 230
p3p 0:93ff83b03fd8 231 uint8_t * USBCDCHID::deviceDesc() {
p3p 0:93ff83b03fd8 232 static uint8_t deviceDescriptor[] = {
p3p 0:93ff83b03fd8 233 18, // bLength
p3p 0:93ff83b03fd8 234 1, // bDescriptorType
p3p 0:93ff83b03fd8 235 0x10, 0x01, // bcdUSB
p3p 0:93ff83b03fd8 236 0xEF, // bDeviceClass
p3p 0:93ff83b03fd8 237 0x02, // bDeviceSubClass
p3p 0:93ff83b03fd8 238 0x01, // bDeviceProtocol
p3p 0:93ff83b03fd8 239 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
p3p 0:93ff83b03fd8 240 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
p3p 0:93ff83b03fd8 241 LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
p3p 0:93ff83b03fd8 242 0x00, 0x01, // bcdDevice
p3p 0:93ff83b03fd8 243 1, // iManufacturer
p3p 0:93ff83b03fd8 244 2, // iProduct
p3p 0:93ff83b03fd8 245 3, // iSerialNumber
p3p 0:93ff83b03fd8 246 1 // bNumConfigurations
p3p 0:93ff83b03fd8 247 };
p3p 0:93ff83b03fd8 248 return deviceDescriptor;
p3p 0:93ff83b03fd8 249 }
p3p 0:93ff83b03fd8 250
p3p 0:93ff83b03fd8 251 uint8_t * USBCDCHID::stringIinterfaceDesc() {
p3p 0:93ff83b03fd8 252 static uint8_t stringIinterfaceDescriptor[] = {
p3p 0:93ff83b03fd8 253 0x08,
p3p 0:93ff83b03fd8 254 STRING_DESCRIPTOR,
p3p 0:93ff83b03fd8 255 'C',0,'D',0,'C',0,
p3p 0:93ff83b03fd8 256 };
p3p 0:93ff83b03fd8 257 return stringIinterfaceDescriptor;
p3p 0:93ff83b03fd8 258 }
p3p 0:93ff83b03fd8 259
p3p 0:93ff83b03fd8 260 uint8_t * USBCDCHID::stringIproductDesc() {
p3p 0:93ff83b03fd8 261 static uint8_t stringIproductDescriptor[] = {
p3p 0:93ff83b03fd8 262 0x16,
p3p 0:93ff83b03fd8 263 STRING_DESCRIPTOR,
p3p 0:93ff83b03fd8 264 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
p3p 0:93ff83b03fd8 265 };
p3p 0:93ff83b03fd8 266 return stringIproductDescriptor;
p3p 0:93ff83b03fd8 267 }
p3p 0:93ff83b03fd8 268
p3p 0:93ff83b03fd8 269
p3p 0:93ff83b03fd8 270 #define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7+8+ INTERFACE_DESCRIPTOR_LENGTH + HID_DESCRIPTOR_LENGTH + ENDPOINT_DESCRIPTOR_LENGTH + ENDPOINT_DESCRIPTOR_LENGTH)
p3p 0:93ff83b03fd8 271
p3p 0:93ff83b03fd8 272 uint8_t * USBCDCHID::configurationDesc() {
p3p 0:93ff83b03fd8 273 static uint8_t configDescriptor[] = {
p3p 0:93ff83b03fd8 274 9, // bLength;
p3p 0:93ff83b03fd8 275 2, // bDescriptorType;
p3p 0:93ff83b03fd8 276 LSB(CONFIG1_DESC_SIZE), // wTotalLength
p3p 0:93ff83b03fd8 277 MSB(CONFIG1_DESC_SIZE),
p3p 0:93ff83b03fd8 278 3, // bNumInterfaces
p3p 0:93ff83b03fd8 279 1, // bConfigurationValue
p3p 0:93ff83b03fd8 280 0, // iConfiguration
p3p 0:93ff83b03fd8 281 0x80, // bmAttributes
p3p 0:93ff83b03fd8 282 50, // bMaxPower
p3p 0:93ff83b03fd8 283
p3p 0:93ff83b03fd8 284 //IAD
p3p 0:93ff83b03fd8 285 0x08, // bLength
p3p 0:93ff83b03fd8 286 0x0B, // bDescriptorType
p3p 0:93ff83b03fd8 287 0x00, // bFirstInterface
p3p 0:93ff83b03fd8 288 0x02, // bInterfaceCount
p3p 0:93ff83b03fd8 289 0x02, // bFunctionClass
p3p 0:93ff83b03fd8 290 0x02, // bFunctionSubClass
p3p 0:93ff83b03fd8 291 0x01, // bFunctionProtocol
p3p 0:93ff83b03fd8 292 0x00, // iFunction
p3p 0:93ff83b03fd8 293
p3p 0:93ff83b03fd8 294 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
p3p 0:93ff83b03fd8 295 9, // bLength
p3p 0:93ff83b03fd8 296 4, // bDescriptorType
p3p 0:93ff83b03fd8 297 0, // bInterfaceNumber
p3p 0:93ff83b03fd8 298 0, // bAlternateSetting
p3p 0:93ff83b03fd8 299 1, // bNumEndpoints
p3p 0:93ff83b03fd8 300 0x02, // bInterfaceClass
p3p 0:93ff83b03fd8 301 0x02, // bInterfaceSubClass
p3p 0:93ff83b03fd8 302 0x01, // bInterfaceProtocol
p3p 0:93ff83b03fd8 303 0, // iInterface
p3p 0:93ff83b03fd8 304
p3p 0:93ff83b03fd8 305 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
p3p 0:93ff83b03fd8 306 5, // bFunctionLength
p3p 0:93ff83b03fd8 307 0x24, // bDescriptorType
p3p 0:93ff83b03fd8 308 0x00, // bDescriptorSubtype
p3p 0:93ff83b03fd8 309 0x10, 0x01, // bcdCDC
p3p 0:93ff83b03fd8 310
p3p 0:93ff83b03fd8 311 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
p3p 0:93ff83b03fd8 312 5, // bFunctionLength
p3p 0:93ff83b03fd8 313 0x24, // bDescriptorType
p3p 0:93ff83b03fd8 314 0x01, // bDescriptorSubtype
p3p 0:93ff83b03fd8 315 0x03, // bmCapabilities
p3p 0:93ff83b03fd8 316 1, // bDataInterface
p3p 0:93ff83b03fd8 317
p3p 0:93ff83b03fd8 318 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
p3p 0:93ff83b03fd8 319 4, // bFunctionLength
p3p 0:93ff83b03fd8 320 0x24, // bDescriptorType
p3p 0:93ff83b03fd8 321 0x02, // bDescriptorSubtype
p3p 0:93ff83b03fd8 322 0x06, // bmCapabilities
p3p 0:93ff83b03fd8 323
p3p 0:93ff83b03fd8 324 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
p3p 0:93ff83b03fd8 325 5, // bFunctionLength
p3p 0:93ff83b03fd8 326 0x24, // bDescriptorType
p3p 0:93ff83b03fd8 327 0x06, // bDescriptorSubtype
p3p 0:93ff83b03fd8 328 0, // bMasterInterface
p3p 0:93ff83b03fd8 329 1, // bSlaveInterface0
p3p 0:93ff83b03fd8 330
p3p 0:93ff83b03fd8 331 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
p3p 0:93ff83b03fd8 332 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
p3p 0:93ff83b03fd8 333 ENDPOINT_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 334 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
p3p 0:93ff83b03fd8 335 E_INTERRUPT, // bmAttributes (0x03=intr)
p3p 0:93ff83b03fd8 336 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
p3p 0:93ff83b03fd8 337 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
p3p 0:93ff83b03fd8 338 16, // bInterval
p3p 0:93ff83b03fd8 339
p3p 0:93ff83b03fd8 340
p3p 0:93ff83b03fd8 341
p3p 0:93ff83b03fd8 342
p3p 0:93ff83b03fd8 343
p3p 0:93ff83b03fd8 344 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
p3p 0:93ff83b03fd8 345 9, // bLength
p3p 0:93ff83b03fd8 346 4, // bDescriptorType
p3p 0:93ff83b03fd8 347 1, // bInterfaceNumber
p3p 0:93ff83b03fd8 348 0, // bAlternateSetting
p3p 0:93ff83b03fd8 349 2, // bNumEndpoints
p3p 0:93ff83b03fd8 350 0x0A, // bInterfaceClass
p3p 0:93ff83b03fd8 351 0x00, // bInterfaceSubClass
p3p 0:93ff83b03fd8 352 0x00, // bInterfaceProtocol
p3p 0:93ff83b03fd8 353 0, // iInterface
p3p 0:93ff83b03fd8 354
p3p 0:93ff83b03fd8 355 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
p3p 0:93ff83b03fd8 356 7, // bLength
p3p 0:93ff83b03fd8 357 5, // bDescriptorType
p3p 0:93ff83b03fd8 358 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
p3p 0:93ff83b03fd8 359 0x02, // bmAttributes (0x02=bulk)
p3p 0:93ff83b03fd8 360 LSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (LSB)
p3p 0:93ff83b03fd8 361 MSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (MSB)
p3p 0:93ff83b03fd8 362 0, // bInterval
p3p 0:93ff83b03fd8 363
p3p 0:93ff83b03fd8 364 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
p3p 0:93ff83b03fd8 365 7, // bLength
p3p 0:93ff83b03fd8 366 5, // bDescriptorType
p3p 0:93ff83b03fd8 367 PHY_TO_DESC(EPBULK_OUT),// bEndpointAddress
p3p 0:93ff83b03fd8 368 0x02, // bmAttributes (0x02=bulk)
p3p 0:93ff83b03fd8 369 LSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (LSB)
p3p 0:93ff83b03fd8 370 MSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (MSB)
p3p 0:93ff83b03fd8 371 0, // bInterval
p3p 0:93ff83b03fd8 372
p3p 0:93ff83b03fd8 373
p3p 0:93ff83b03fd8 374 // ***************
p3p 0:93ff83b03fd8 375 // keyboard hacked in
p3p 0:93ff83b03fd8 376 // ***************
p3p 0:93ff83b03fd8 377
p3p 0:93ff83b03fd8 378
p3p 0:93ff83b03fd8 379 INTERFACE_DESCRIPTOR_LENGTH, // bLength
p3p 0:93ff83b03fd8 380 INTERFACE_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 381 0x02, // bInterfaceNumber
p3p 0:93ff83b03fd8 382 0x00, // bAlternateSetting
p3p 0:93ff83b03fd8 383 0x02, // bNumEndpoints
p3p 0:93ff83b03fd8 384 HID_CLASS, // bInterfaceClass
p3p 0:93ff83b03fd8 385 1, // bInterfaceSubClass
p3p 0:93ff83b03fd8 386 1, // bInterfaceProtocol (keyboard)
p3p 0:93ff83b03fd8 387 0x00, // iInterface
p3p 0:93ff83b03fd8 388
p3p 0:93ff83b03fd8 389 HID_DESCRIPTOR_LENGTH, // bLength
p3p 0:93ff83b03fd8 390 HID_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 391 LSB(HID_VERSION_1_11), // bcdHID (LSB)
p3p 0:93ff83b03fd8 392 MSB(HID_VERSION_1_11), // bcdHID (MSB)
p3p 0:93ff83b03fd8 393 0x00, // bCountryCode
p3p 0:93ff83b03fd8 394 0x01, // bNumDescriptors
p3p 0:93ff83b03fd8 395 REPORT_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 396 LSB(reportDescLength()), // wDescriptorLength (LSB)
p3p 0:93ff83b03fd8 397 MSB(reportDescLength()), // wDescriptorLength (MSB)
p3p 0:93ff83b03fd8 398
p3p 0:93ff83b03fd8 399 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
p3p 0:93ff83b03fd8 400 ENDPOINT_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 401 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
p3p 0:93ff83b03fd8 402 E_INTERRUPT, // bmAttributes
p3p 0:93ff83b03fd8 403 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
p3p 0:93ff83b03fd8 404 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
p3p 0:93ff83b03fd8 405 1, // bInterval (milliseconds)
p3p 0:93ff83b03fd8 406
p3p 0:93ff83b03fd8 407 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
p3p 0:93ff83b03fd8 408 ENDPOINT_DESCRIPTOR, // bDescriptorType
p3p 0:93ff83b03fd8 409 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
p3p 0:93ff83b03fd8 410 E_INTERRUPT, // bmAttributes
p3p 0:93ff83b03fd8 411 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
p3p 0:93ff83b03fd8 412 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
p3p 0:93ff83b03fd8 413 1, // bInterval (milliseconds)
p3p 0:93ff83b03fd8 414 };
p3p 0:93ff83b03fd8 415 return configDescriptor;
p3p 0:93ff83b03fd8 416 }