Fork of the official USBDevice library

Fork of USBDevice by mbed official

Committer:
screamer
Date:
Fri Apr 28 17:01:10 2017 +0000
Branch:
device-files
Revision:
76:f0fd8d911b24
Parent:
73:8d28a0cb7b43
Changed the layout of USBDevice implementation for various targets to match mbed-os/targets. This also reduces the amount of files being compiled as USBDevice code for other targets is not compiled.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 73:8d28a0cb7b43 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
screamer 73:8d28a0cb7b43 2 *
screamer 73:8d28a0cb7b43 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
screamer 73:8d28a0cb7b43 4 * and associated documentation files (the "Software"), to deal in the Software without
screamer 73:8d28a0cb7b43 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
screamer 73:8d28a0cb7b43 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
screamer 73:8d28a0cb7b43 7 * Software is furnished to do so, subject to the following conditions:
screamer 73:8d28a0cb7b43 8 *
screamer 73:8d28a0cb7b43 9 * The above copyright notice and this permission notice shall be included in all copies or
screamer 73:8d28a0cb7b43 10 * substantial portions of the Software.
screamer 73:8d28a0cb7b43 11 *
screamer 73:8d28a0cb7b43 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
screamer 73:8d28a0cb7b43 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
screamer 73:8d28a0cb7b43 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
screamer 73:8d28a0cb7b43 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
screamer 73:8d28a0cb7b43 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
screamer 73:8d28a0cb7b43 17 */
screamer 73:8d28a0cb7b43 18
screamer 73:8d28a0cb7b43 19 #include "stdint.h"
screamer 73:8d28a0cb7b43 20 #include "USBCDC.h"
screamer 73:8d28a0cb7b43 21
screamer 73:8d28a0cb7b43 22 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
screamer 73:8d28a0cb7b43 23
screamer 73:8d28a0cb7b43 24 #define DEFAULT_CONFIGURATION (1)
screamer 73:8d28a0cb7b43 25
screamer 73:8d28a0cb7b43 26 #define CDC_SET_LINE_CODING 0x20
screamer 73:8d28a0cb7b43 27 #define CDC_GET_LINE_CODING 0x21
screamer 73:8d28a0cb7b43 28 #define CDC_SET_CONTROL_LINE_STATE 0x22
screamer 73:8d28a0cb7b43 29
screamer 73:8d28a0cb7b43 30 // Control Line State bits
screamer 73:8d28a0cb7b43 31 #define CLS_DTR (1 << 0)
screamer 73:8d28a0cb7b43 32 #define CLS_RTS (1 << 1)
screamer 73:8d28a0cb7b43 33
screamer 73:8d28a0cb7b43 34 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
screamer 73:8d28a0cb7b43 35
screamer 73:8d28a0cb7b43 36 USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
screamer 73:8d28a0cb7b43 37 terminal_connected = false;
screamer 73:8d28a0cb7b43 38 USBDevice::connect(connect_blocking);
screamer 73:8d28a0cb7b43 39 }
screamer 73:8d28a0cb7b43 40
screamer 73:8d28a0cb7b43 41 bool USBCDC::USBCallback_request(void) {
screamer 73:8d28a0cb7b43 42 /* Called in ISR context */
screamer 73:8d28a0cb7b43 43
screamer 73:8d28a0cb7b43 44 bool success = false;
screamer 73:8d28a0cb7b43 45 CONTROL_TRANSFER * transfer = getTransferPtr();
screamer 73:8d28a0cb7b43 46
screamer 73:8d28a0cb7b43 47 /* Process class-specific requests */
screamer 73:8d28a0cb7b43 48
screamer 73:8d28a0cb7b43 49 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
screamer 73:8d28a0cb7b43 50 switch (transfer->setup.bRequest) {
screamer 73:8d28a0cb7b43 51 case CDC_GET_LINE_CODING:
screamer 73:8d28a0cb7b43 52 transfer->remaining = 7;
screamer 73:8d28a0cb7b43 53 transfer->ptr = cdc_line_coding;
screamer 73:8d28a0cb7b43 54 transfer->direction = DEVICE_TO_HOST;
screamer 73:8d28a0cb7b43 55 success = true;
screamer 73:8d28a0cb7b43 56 break;
screamer 73:8d28a0cb7b43 57 case CDC_SET_LINE_CODING:
screamer 73:8d28a0cb7b43 58 transfer->remaining = 7;
screamer 73:8d28a0cb7b43 59 transfer->notify = true;
screamer 73:8d28a0cb7b43 60 success = true;
screamer 73:8d28a0cb7b43 61 break;
screamer 73:8d28a0cb7b43 62 case CDC_SET_CONTROL_LINE_STATE:
screamer 73:8d28a0cb7b43 63 if (transfer->setup.wValue & CLS_DTR) {
screamer 73:8d28a0cb7b43 64 terminal_connected = true;
screamer 73:8d28a0cb7b43 65 } else {
screamer 73:8d28a0cb7b43 66 terminal_connected = false;
screamer 73:8d28a0cb7b43 67 }
screamer 73:8d28a0cb7b43 68 success = true;
screamer 73:8d28a0cb7b43 69 break;
screamer 73:8d28a0cb7b43 70 default:
screamer 73:8d28a0cb7b43 71 break;
screamer 73:8d28a0cb7b43 72 }
screamer 73:8d28a0cb7b43 73 }
screamer 73:8d28a0cb7b43 74
screamer 73:8d28a0cb7b43 75 return success;
screamer 73:8d28a0cb7b43 76 }
screamer 73:8d28a0cb7b43 77
screamer 73:8d28a0cb7b43 78 void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
screamer 73:8d28a0cb7b43 79 // Request of setting line coding has 7 bytes
screamer 73:8d28a0cb7b43 80 if (length != 7) {
screamer 73:8d28a0cb7b43 81 return;
screamer 73:8d28a0cb7b43 82 }
screamer 73:8d28a0cb7b43 83
screamer 73:8d28a0cb7b43 84 CONTROL_TRANSFER * transfer = getTransferPtr();
screamer 73:8d28a0cb7b43 85
screamer 73:8d28a0cb7b43 86 /* Process class-specific requests */
screamer 73:8d28a0cb7b43 87 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
screamer 73:8d28a0cb7b43 88 if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
screamer 73:8d28a0cb7b43 89 if (memcmp(cdc_line_coding, buf, 7)) {
screamer 73:8d28a0cb7b43 90 memcpy(cdc_line_coding, buf, 7);
screamer 73:8d28a0cb7b43 91
screamer 73:8d28a0cb7b43 92 int baud = buf[0] + (buf[1] << 8)
screamer 73:8d28a0cb7b43 93 + (buf[2] << 16) + (buf[3] << 24);
screamer 73:8d28a0cb7b43 94 int stop = buf[4];
screamer 73:8d28a0cb7b43 95 int bits = buf[6];
screamer 73:8d28a0cb7b43 96 int parity = buf[5];
screamer 73:8d28a0cb7b43 97
screamer 73:8d28a0cb7b43 98 lineCodingChanged(baud, bits, parity, stop);
screamer 73:8d28a0cb7b43 99 }
screamer 73:8d28a0cb7b43 100 }
screamer 73:8d28a0cb7b43 101 }
screamer 73:8d28a0cb7b43 102 }
screamer 73:8d28a0cb7b43 103
screamer 73:8d28a0cb7b43 104 // Called in ISR context
screamer 73:8d28a0cb7b43 105 // Set configuration. Return false if the
screamer 73:8d28a0cb7b43 106 // configuration is not supported.
screamer 73:8d28a0cb7b43 107 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
screamer 73:8d28a0cb7b43 108 if (configuration != DEFAULT_CONFIGURATION) {
screamer 73:8d28a0cb7b43 109 return false;
screamer 73:8d28a0cb7b43 110 }
screamer 73:8d28a0cb7b43 111
screamer 73:8d28a0cb7b43 112 // Configure endpoints > 0
screamer 73:8d28a0cb7b43 113 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
screamer 73:8d28a0cb7b43 114 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 115 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 116
screamer 73:8d28a0cb7b43 117 // We activate the endpoint to be able to recceive data
screamer 73:8d28a0cb7b43 118 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 119 return true;
screamer 73:8d28a0cb7b43 120 }
screamer 73:8d28a0cb7b43 121
screamer 73:8d28a0cb7b43 122 bool USBCDC::send(uint8_t * buffer, uint32_t size) {
screamer 73:8d28a0cb7b43 123 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
screamer 73:8d28a0cb7b43 124 }
screamer 73:8d28a0cb7b43 125
screamer 73:8d28a0cb7b43 126 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
screamer 73:8d28a0cb7b43 127 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
screamer 73:8d28a0cb7b43 128 return false;
screamer 73:8d28a0cb7b43 129 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
screamer 73:8d28a0cb7b43 130 return false;
screamer 73:8d28a0cb7b43 131 return true;
screamer 73:8d28a0cb7b43 132 }
screamer 73:8d28a0cb7b43 133
screamer 73:8d28a0cb7b43 134 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
screamer 73:8d28a0cb7b43 135 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
screamer 73:8d28a0cb7b43 136 return false;
screamer 73:8d28a0cb7b43 137 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
screamer 73:8d28a0cb7b43 138 return false;
screamer 73:8d28a0cb7b43 139 return true;
screamer 73:8d28a0cb7b43 140 }
screamer 73:8d28a0cb7b43 141
screamer 73:8d28a0cb7b43 142
screamer 73:8d28a0cb7b43 143 uint8_t * USBCDC::deviceDesc() {
screamer 73:8d28a0cb7b43 144 static uint8_t deviceDescriptor[] = {
screamer 73:8d28a0cb7b43 145 18, // bLength
screamer 73:8d28a0cb7b43 146 1, // bDescriptorType
screamer 73:8d28a0cb7b43 147 0x10, 0x01, // bcdUSB
screamer 73:8d28a0cb7b43 148 2, // bDeviceClass
screamer 73:8d28a0cb7b43 149 0, // bDeviceSubClass
screamer 73:8d28a0cb7b43 150 0, // bDeviceProtocol
screamer 73:8d28a0cb7b43 151 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
screamer 73:8d28a0cb7b43 152 (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor
screamer 73:8d28a0cb7b43 153 (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
screamer 73:8d28a0cb7b43 154 0x00, 0x01, // bcdDevice
screamer 73:8d28a0cb7b43 155 1, // iManufacturer
screamer 73:8d28a0cb7b43 156 2, // iProduct
screamer 73:8d28a0cb7b43 157 3, // iSerialNumber
screamer 73:8d28a0cb7b43 158 1 // bNumConfigurations
screamer 73:8d28a0cb7b43 159 };
screamer 73:8d28a0cb7b43 160 return deviceDescriptor;
screamer 73:8d28a0cb7b43 161 }
screamer 73:8d28a0cb7b43 162
screamer 73:8d28a0cb7b43 163 uint8_t * USBCDC::stringIinterfaceDesc() {
screamer 73:8d28a0cb7b43 164 static uint8_t stringIinterfaceDescriptor[] = {
screamer 73:8d28a0cb7b43 165 0x08,
screamer 73:8d28a0cb7b43 166 STRING_DESCRIPTOR,
screamer 73:8d28a0cb7b43 167 'C',0,'D',0,'C',0,
screamer 73:8d28a0cb7b43 168 };
screamer 73:8d28a0cb7b43 169 return stringIinterfaceDescriptor;
screamer 73:8d28a0cb7b43 170 }
screamer 73:8d28a0cb7b43 171
screamer 73:8d28a0cb7b43 172 uint8_t * USBCDC::stringIproductDesc() {
screamer 73:8d28a0cb7b43 173 static uint8_t stringIproductDescriptor[] = {
screamer 73:8d28a0cb7b43 174 0x16,
screamer 73:8d28a0cb7b43 175 STRING_DESCRIPTOR,
screamer 73:8d28a0cb7b43 176 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
screamer 73:8d28a0cb7b43 177 };
screamer 73:8d28a0cb7b43 178 return stringIproductDescriptor;
screamer 73:8d28a0cb7b43 179 }
screamer 73:8d28a0cb7b43 180
screamer 73:8d28a0cb7b43 181
screamer 73:8d28a0cb7b43 182 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
screamer 73:8d28a0cb7b43 183
screamer 73:8d28a0cb7b43 184 uint8_t * USBCDC::configurationDesc() {
screamer 73:8d28a0cb7b43 185 static uint8_t configDescriptor[] = {
screamer 73:8d28a0cb7b43 186 // configuration descriptor
screamer 73:8d28a0cb7b43 187 9, // bLength
screamer 73:8d28a0cb7b43 188 2, // bDescriptorType
screamer 73:8d28a0cb7b43 189 LSB(CONFIG1_DESC_SIZE), // wTotalLength
screamer 73:8d28a0cb7b43 190 MSB(CONFIG1_DESC_SIZE),
screamer 73:8d28a0cb7b43 191 2, // bNumInterfaces
screamer 73:8d28a0cb7b43 192 1, // bConfigurationValue
screamer 73:8d28a0cb7b43 193 0, // iConfiguration
screamer 73:8d28a0cb7b43 194 0x80, // bmAttributes
screamer 73:8d28a0cb7b43 195 50, // bMaxPower
screamer 73:8d28a0cb7b43 196
screamer 73:8d28a0cb7b43 197 // IAD to associate the two CDC interfaces
screamer 73:8d28a0cb7b43 198 0x08, // bLength
screamer 73:8d28a0cb7b43 199 0x0b, // bDescriptorType
screamer 73:8d28a0cb7b43 200 0x00, // bFirstInterface
screamer 73:8d28a0cb7b43 201 0x02, // bInterfaceCount
screamer 73:8d28a0cb7b43 202 0x02, // bFunctionClass
screamer 73:8d28a0cb7b43 203 0x02, // bFunctionSubClass
screamer 73:8d28a0cb7b43 204 0, // bFunctionProtocol
screamer 73:8d28a0cb7b43 205 0, // iFunction
screamer 73:8d28a0cb7b43 206
screamer 73:8d28a0cb7b43 207 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
screamer 73:8d28a0cb7b43 208 9, // bLength
screamer 73:8d28a0cb7b43 209 4, // bDescriptorType
screamer 73:8d28a0cb7b43 210 0, // bInterfaceNumber
screamer 73:8d28a0cb7b43 211 0, // bAlternateSetting
screamer 73:8d28a0cb7b43 212 1, // bNumEndpoints
screamer 73:8d28a0cb7b43 213 0x02, // bInterfaceClass
screamer 73:8d28a0cb7b43 214 0x02, // bInterfaceSubClass
screamer 73:8d28a0cb7b43 215 0x01, // bInterfaceProtocol
screamer 73:8d28a0cb7b43 216 0, // iInterface
screamer 73:8d28a0cb7b43 217
screamer 73:8d28a0cb7b43 218 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
screamer 73:8d28a0cb7b43 219 5, // bFunctionLength
screamer 73:8d28a0cb7b43 220 0x24, // bDescriptorType
screamer 73:8d28a0cb7b43 221 0x00, // bDescriptorSubtype
screamer 73:8d28a0cb7b43 222 0x10, 0x01, // bcdCDC
screamer 73:8d28a0cb7b43 223
screamer 73:8d28a0cb7b43 224 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
screamer 73:8d28a0cb7b43 225 5, // bFunctionLength
screamer 73:8d28a0cb7b43 226 0x24, // bDescriptorType
screamer 73:8d28a0cb7b43 227 0x01, // bDescriptorSubtype
screamer 73:8d28a0cb7b43 228 0x03, // bmCapabilities
screamer 73:8d28a0cb7b43 229 1, // bDataInterface
screamer 73:8d28a0cb7b43 230
screamer 73:8d28a0cb7b43 231 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
screamer 73:8d28a0cb7b43 232 4, // bFunctionLength
screamer 73:8d28a0cb7b43 233 0x24, // bDescriptorType
screamer 73:8d28a0cb7b43 234 0x02, // bDescriptorSubtype
screamer 73:8d28a0cb7b43 235 0x06, // bmCapabilities
screamer 73:8d28a0cb7b43 236
screamer 73:8d28a0cb7b43 237 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
screamer 73:8d28a0cb7b43 238 5, // bFunctionLength
screamer 73:8d28a0cb7b43 239 0x24, // bDescriptorType
screamer 73:8d28a0cb7b43 240 0x06, // bDescriptorSubtype
screamer 73:8d28a0cb7b43 241 0, // bMasterInterface
screamer 73:8d28a0cb7b43 242 1, // bSlaveInterface0
screamer 73:8d28a0cb7b43 243
screamer 73:8d28a0cb7b43 244 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
screamer 73:8d28a0cb7b43 245 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 246 ENDPOINT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 247 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
screamer 73:8d28a0cb7b43 248 E_INTERRUPT, // bmAttributes (0x03=intr)
screamer 73:8d28a0cb7b43 249 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
screamer 73:8d28a0cb7b43 250 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
screamer 73:8d28a0cb7b43 251 16, // bInterval
screamer 73:8d28a0cb7b43 252
screamer 73:8d28a0cb7b43 253
screamer 73:8d28a0cb7b43 254
screamer 73:8d28a0cb7b43 255
screamer 73:8d28a0cb7b43 256 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
screamer 73:8d28a0cb7b43 257 9, // bLength
screamer 73:8d28a0cb7b43 258 4, // bDescriptorType
screamer 73:8d28a0cb7b43 259 1, // bInterfaceNumber
screamer 73:8d28a0cb7b43 260 0, // bAlternateSetting
screamer 73:8d28a0cb7b43 261 2, // bNumEndpoints
screamer 73:8d28a0cb7b43 262 0x0A, // bInterfaceClass
screamer 73:8d28a0cb7b43 263 0x00, // bInterfaceSubClass
screamer 73:8d28a0cb7b43 264 0x00, // bInterfaceProtocol
screamer 73:8d28a0cb7b43 265 0, // iInterface
screamer 73:8d28a0cb7b43 266
screamer 73:8d28a0cb7b43 267 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
screamer 73:8d28a0cb7b43 268 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 269 ENDPOINT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 270 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
screamer 73:8d28a0cb7b43 271 E_BULK, // bmAttributes (0x02=bulk)
screamer 73:8d28a0cb7b43 272 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
screamer 73:8d28a0cb7b43 273 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
screamer 73:8d28a0cb7b43 274 0, // bInterval
screamer 73:8d28a0cb7b43 275
screamer 73:8d28a0cb7b43 276 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
screamer 73:8d28a0cb7b43 277 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 278 ENDPOINT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 279 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
screamer 73:8d28a0cb7b43 280 E_BULK, // bmAttributes (0x02=bulk)
screamer 73:8d28a0cb7b43 281 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
screamer 73:8d28a0cb7b43 282 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
screamer 73:8d28a0cb7b43 283 0 // bInterval
screamer 73:8d28a0cb7b43 284 };
screamer 73:8d28a0cb7b43 285 return configDescriptor;
screamer 73:8d28a0cb7b43 286 }