A Composite device with USBSerial and USBKeyboard
Dependents: USBSerialKeyboard_Example
USBCDCHID.cpp@1:9367d07d0707, 2013-03-30 (annotated)
- 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?
User | Revision | Line number | New 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 | } |