USBMSD SD card Hello World for Mbed platforms

Dependencies:   mbed USBMSD_SD USBDevice

Committer:
samux
Date:
Sun Dec 11 15:22:50 2011 +0000
Revision:
18:08b207d10056
Parent:
14:757226626acb
all is working: rename...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 14:757226626acb 1 /* USBDevice.c */
samux 14:757226626acb 2 /* Generic USB device */
samux 14:757226626acb 3 /* Copyright (c) 2011 ARM Limited. All rights reserved. */
samux 14:757226626acb 4
samux 14:757226626acb 5 /* Reference: */
samux 14:757226626acb 6 /* Universal Serial Bus Specification Revision 2.0, Chapter 9 "USB Device Framework" */
samux 14:757226626acb 7
samux 14:757226626acb 8 #include "stdint.h"
samux 14:757226626acb 9
samux 14:757226626acb 10 #include "USBEndpoints.h"
samux 14:757226626acb 11 #include "USBDevice.h"
samux 14:757226626acb 12 #include "USBDescriptor.h"
samux 14:757226626acb 13 #include "USBHID_Types.h"
samux 14:757226626acb 14
samux 14:757226626acb 15
samux 14:757226626acb 16 /* Device status */
samux 14:757226626acb 17 #define DEVICE_STATUS_SELF_POWERED (1U<<0)
samux 14:757226626acb 18 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
samux 14:757226626acb 19
samux 14:757226626acb 20 /* Endpoint status */
samux 14:757226626acb 21 #define ENDPOINT_STATUS_HALT (1U<<0)
samux 14:757226626acb 22
samux 14:757226626acb 23 /* Standard feature selectors */
samux 14:757226626acb 24 #define DEVICE_REMOTE_WAKEUP (1)
samux 14:757226626acb 25 #define ENDPOINT_HALT (0)
samux 14:757226626acb 26
samux 14:757226626acb 27 /* Macro to convert wIndex endpoint number to physical endpoint number */
samux 14:757226626acb 28 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
samux 14:757226626acb 29 ((endpoint & 0x80) ? 1 : 0))
samux 14:757226626acb 30
samux 14:757226626acb 31
samux 14:757226626acb 32 bool USBDevice::requestGetDescriptor(void)
samux 14:757226626acb 33 {
samux 14:757226626acb 34 bool success = false;
samux 14:757226626acb 35
samux 14:757226626acb 36 switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
samux 14:757226626acb 37 {
samux 14:757226626acb 38 case DEVICE_DESCRIPTOR:
samux 14:757226626acb 39 if (deviceDesc() != NULL)
samux 14:757226626acb 40 {
samux 14:757226626acb 41 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
samux 14:757226626acb 42 && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
samux 14:757226626acb 43 {
samux 14:757226626acb 44 transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
samux 14:757226626acb 45 transfer.ptr = deviceDesc();
samux 14:757226626acb 46 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 47 success = true;
samux 14:757226626acb 48 }
samux 14:757226626acb 49 }
samux 14:757226626acb 50 break;
samux 14:757226626acb 51 case CONFIGURATION_DESCRIPTOR:
samux 14:757226626acb 52 if (configurationDesc() != NULL)
samux 14:757226626acb 53 {
samux 14:757226626acb 54 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
samux 14:757226626acb 55 && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
samux 14:757226626acb 56 {
samux 14:757226626acb 57 /* Get wTotalLength */
samux 14:757226626acb 58 transfer.remaining = configurationDesc()[2] \
samux 14:757226626acb 59 | (configurationDesc()[3] << 8);
samux 14:757226626acb 60
samux 14:757226626acb 61 transfer.ptr = configurationDesc();
samux 14:757226626acb 62 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 63 success = true;
samux 14:757226626acb 64 }
samux 14:757226626acb 65 }
samux 14:757226626acb 66 break;
samux 14:757226626acb 67 case STRING_DESCRIPTOR:
samux 14:757226626acb 68 switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
samux 14:757226626acb 69 {
samux 14:757226626acb 70 case STRING_OFFSET_LANGID:
samux 14:757226626acb 71 transfer.remaining = stringLangidDesc()[0];
samux 14:757226626acb 72 transfer.ptr = stringLangidDesc();
samux 14:757226626acb 73 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 74 success = true;
samux 14:757226626acb 75 break;
samux 14:757226626acb 76 case STRING_OFFSET_IMANUFACTURER:
samux 14:757226626acb 77 transfer.remaining = stringImanufacturerDesc()[0];
samux 14:757226626acb 78 transfer.ptr = stringImanufacturerDesc();
samux 14:757226626acb 79 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 80 success = true;
samux 14:757226626acb 81 break;
samux 14:757226626acb 82 case STRING_OFFSET_IPRODUCT:
samux 14:757226626acb 83 transfer.remaining = stringIproductDesc()[0];
samux 14:757226626acb 84 transfer.ptr = stringIproductDesc();
samux 14:757226626acb 85 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 86 success = true;
samux 14:757226626acb 87 break;
samux 14:757226626acb 88 case STRING_OFFSET_ISERIAL:
samux 14:757226626acb 89 transfer.remaining = stringIserialDesc()[0];
samux 14:757226626acb 90 transfer.ptr = stringIserialDesc();
samux 14:757226626acb 91 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 92 success = true;
samux 14:757226626acb 93 break;
samux 14:757226626acb 94 case STRING_OFFSET_ICONFIGURATION:
samux 14:757226626acb 95 transfer.remaining = stringIConfigurationDesc()[0];
samux 14:757226626acb 96 transfer.ptr = stringIConfigurationDesc();
samux 14:757226626acb 97 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 98 success = true;
samux 14:757226626acb 99 break;
samux 14:757226626acb 100 case STRING_OFFSET_IINTERFACE:
samux 14:757226626acb 101 transfer.remaining = stringIinterfaceDesc()[0];
samux 14:757226626acb 102 transfer.ptr = stringIinterfaceDesc();
samux 14:757226626acb 103 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 104 success = true;
samux 14:757226626acb 105 break;
samux 14:757226626acb 106 }
samux 14:757226626acb 107 break;
samux 14:757226626acb 108 case INTERFACE_DESCRIPTOR:
samux 14:757226626acb 109 case ENDPOINT_DESCRIPTOR:
samux 14:757226626acb 110 /* TODO: Support is optional, not implemented here */
samux 14:757226626acb 111 break;
samux 14:757226626acb 112 default:
samux 14:757226626acb 113 break;
samux 14:757226626acb 114 }
samux 14:757226626acb 115
samux 14:757226626acb 116 return success;
samux 14:757226626acb 117 }
samux 14:757226626acb 118
samux 14:757226626acb 119 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
samux 14:757226626acb 120 {
samux 14:757226626acb 121 /* Fill in the elements of a SETUP_PACKET structure from raw data */
samux 14:757226626acb 122 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
samux 14:757226626acb 123 packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
samux 14:757226626acb 124 packet->bmRequestType.Recipient = data[0] & 0x1f;
samux 14:757226626acb 125 packet->bRequest = data[1];
samux 14:757226626acb 126 packet->wValue = (data[2] | (uint16_t)data[3] << 8);
samux 14:757226626acb 127 packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
samux 14:757226626acb 128 packet->wLength = (data[6] | (uint16_t)data[7] << 8);
samux 14:757226626acb 129 }
samux 14:757226626acb 130
samux 14:757226626acb 131
samux 14:757226626acb 132 bool USBDevice::controlOut(void)
samux 14:757226626acb 133 {
samux 14:757226626acb 134 /* Control transfer data OUT stage */
samux 14:757226626acb 135 uint8_t buffer[MAX_PACKET_SIZE_EP0];
samux 14:757226626acb 136 uint32_t packetSize;
samux 14:757226626acb 137
samux 14:757226626acb 138 /* Check we should be transferring data OUT */
samux 14:757226626acb 139 if (transfer.direction != HOST_TO_DEVICE)
samux 14:757226626acb 140 {
samux 14:757226626acb 141 return false;
samux 14:757226626acb 142 }
samux 14:757226626acb 143
samux 14:757226626acb 144 /* Read from endpoint */
samux 14:757226626acb 145 packetSize = EP0getReadResult(buffer);
samux 14:757226626acb 146
samux 14:757226626acb 147 /* Check if transfer size is valid */
samux 14:757226626acb 148 if (packetSize > transfer.remaining)
samux 14:757226626acb 149 {
samux 14:757226626acb 150 /* Too big */
samux 14:757226626acb 151 return false;
samux 14:757226626acb 152 }
samux 14:757226626acb 153
samux 14:757226626acb 154 /* Update transfer */
samux 14:757226626acb 155 transfer.ptr += packetSize;
samux 14:757226626acb 156 transfer.remaining -= packetSize;
samux 14:757226626acb 157
samux 14:757226626acb 158 /* Check if transfer has completed */
samux 14:757226626acb 159 if (transfer.remaining == 0)
samux 14:757226626acb 160 {
samux 14:757226626acb 161 /* Transfer completed */
samux 14:757226626acb 162 if (transfer.notify)
samux 14:757226626acb 163 {
samux 14:757226626acb 164 /* Notify class layer. */
samux 14:757226626acb 165 USBCallback_requestCompleted(buffer, packetSize);
samux 14:757226626acb 166 transfer.notify = false;
samux 14:757226626acb 167 }
samux 14:757226626acb 168 /* Status stage */
samux 14:757226626acb 169 EP0write(NULL, 0);
samux 14:757226626acb 170 }
samux 14:757226626acb 171 else
samux 14:757226626acb 172 {
samux 14:757226626acb 173 EP0read();
samux 14:757226626acb 174 }
samux 14:757226626acb 175
samux 14:757226626acb 176 return true;
samux 14:757226626acb 177 }
samux 14:757226626acb 178
samux 14:757226626acb 179 bool USBDevice::controlIn(void)
samux 14:757226626acb 180 {
samux 14:757226626acb 181 /* Control transfer data IN stage */
samux 14:757226626acb 182 uint32_t packetSize;
samux 14:757226626acb 183
samux 14:757226626acb 184 /* Check if transfer has completed (status stage transactions */
samux 14:757226626acb 185 /* also have transfer.remaining == 0) */
samux 14:757226626acb 186 if (transfer.remaining == 0)
samux 14:757226626acb 187 {
samux 14:757226626acb 188 if (transfer.zlp)
samux 14:757226626acb 189 {
samux 14:757226626acb 190 /* Send zero length packet */
samux 14:757226626acb 191 EP0write(NULL, 0);
samux 14:757226626acb 192 transfer.zlp = false;
samux 14:757226626acb 193 }
samux 14:757226626acb 194
samux 14:757226626acb 195 /* Transfer completed */
samux 14:757226626acb 196 if (transfer.notify)
samux 14:757226626acb 197 {
samux 14:757226626acb 198 /* Notify class layer. */
samux 14:757226626acb 199 USBCallback_requestCompleted(NULL, 0);
samux 14:757226626acb 200 transfer.notify = false;
samux 14:757226626acb 201 }
samux 14:757226626acb 202
samux 14:757226626acb 203 EP0read();
samux 14:757226626acb 204
samux 14:757226626acb 205 /* Completed */
samux 14:757226626acb 206 return true;
samux 14:757226626acb 207 }
samux 14:757226626acb 208
samux 14:757226626acb 209 /* Check we should be transferring data IN */
samux 14:757226626acb 210 if (transfer.direction != DEVICE_TO_HOST)
samux 14:757226626acb 211 {
samux 14:757226626acb 212 return false;
samux 14:757226626acb 213 }
samux 14:757226626acb 214
samux 14:757226626acb 215 packetSize = transfer.remaining;
samux 14:757226626acb 216
samux 14:757226626acb 217 if (packetSize > MAX_PACKET_SIZE_EP0)
samux 14:757226626acb 218 {
samux 14:757226626acb 219 packetSize = MAX_PACKET_SIZE_EP0;
samux 14:757226626acb 220 }
samux 14:757226626acb 221
samux 14:757226626acb 222 /* Write to endpoint */
samux 14:757226626acb 223 EP0write(transfer.ptr, packetSize);
samux 14:757226626acb 224
samux 14:757226626acb 225 /* Update transfer */
samux 14:757226626acb 226 transfer.ptr += packetSize;
samux 14:757226626acb 227 transfer.remaining -= packetSize;
samux 14:757226626acb 228
samux 14:757226626acb 229 return true;
samux 14:757226626acb 230 }
samux 14:757226626acb 231
samux 14:757226626acb 232 bool USBDevice::requestSetAddress(void)
samux 14:757226626acb 233 {
samux 14:757226626acb 234 /* Set the device address */
samux 14:757226626acb 235 setAddress(transfer.setup.wValue);
samux 14:757226626acb 236
samux 14:757226626acb 237 if (transfer.setup.wValue == 0)
samux 14:757226626acb 238 {
samux 14:757226626acb 239 device.state = DEFAULT;
samux 14:757226626acb 240 }
samux 14:757226626acb 241 else
samux 14:757226626acb 242 {
samux 14:757226626acb 243 device.state = ADDRESS;
samux 14:757226626acb 244 }
samux 14:757226626acb 245
samux 14:757226626acb 246 return true;
samux 14:757226626acb 247 }
samux 14:757226626acb 248
samux 14:757226626acb 249 bool USBDevice::requestSetConfiguration(void)
samux 14:757226626acb 250 {
samux 14:757226626acb 251
samux 14:757226626acb 252 device.configuration = transfer.setup.wValue;
samux 14:757226626acb 253 /* Set the device configuration */
samux 14:757226626acb 254 if (device.configuration == 0)
samux 14:757226626acb 255 {
samux 14:757226626acb 256 /* Not configured */
samux 14:757226626acb 257 unconfigureDevice();
samux 14:757226626acb 258 device.state = ADDRESS;
samux 14:757226626acb 259 }
samux 14:757226626acb 260 else
samux 14:757226626acb 261 {
samux 14:757226626acb 262 if (USBCallback_setConfiguration(device.configuration))
samux 14:757226626acb 263 {
samux 14:757226626acb 264 /* Valid configuration */
samux 14:757226626acb 265 configureDevice();
samux 14:757226626acb 266 device.state = CONFIGURED;
samux 14:757226626acb 267 }
samux 14:757226626acb 268 else
samux 14:757226626acb 269 {
samux 14:757226626acb 270 return false;
samux 14:757226626acb 271 }
samux 14:757226626acb 272 }
samux 14:757226626acb 273
samux 14:757226626acb 274 return true;
samux 14:757226626acb 275 }
samux 14:757226626acb 276
samux 14:757226626acb 277 bool USBDevice::requestGetConfiguration(void)
samux 14:757226626acb 278 {
samux 14:757226626acb 279 /* Send the device configuration */
samux 14:757226626acb 280 transfer.ptr = &device.configuration;
samux 14:757226626acb 281 transfer.remaining = sizeof(device.configuration);
samux 14:757226626acb 282 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 283 return true;
samux 14:757226626acb 284 }
samux 14:757226626acb 285
samux 14:757226626acb 286 bool USBDevice::requestGetInterface(void)
samux 14:757226626acb 287 {
samux 14:757226626acb 288 /* Return the selected alternate setting for an interface */
samux 14:757226626acb 289
samux 14:757226626acb 290 if (device.state != CONFIGURED)
samux 14:757226626acb 291 {
samux 14:757226626acb 292 return false;
samux 14:757226626acb 293 }
samux 14:757226626acb 294
samux 14:757226626acb 295 /* Send the alternate setting */
samux 14:757226626acb 296 transfer.setup.wIndex = currentInterface;
samux 14:757226626acb 297 transfer.ptr = &currentAlternate;
samux 14:757226626acb 298 transfer.remaining = sizeof(currentAlternate);
samux 14:757226626acb 299 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 300 return true;
samux 14:757226626acb 301 }
samux 14:757226626acb 302
samux 14:757226626acb 303 bool USBDevice::requestSetInterface(void)
samux 14:757226626acb 304 {
samux 14:757226626acb 305 bool success = false;
samux 14:757226626acb 306 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
samux 14:757226626acb 307 {
samux 14:757226626acb 308 success = true;
samux 14:757226626acb 309 currentInterface = transfer.setup.wIndex;
samux 14:757226626acb 310 currentAlternate = transfer.setup.wValue;
samux 14:757226626acb 311 }
samux 14:757226626acb 312 return success;
samux 14:757226626acb 313 }
samux 14:757226626acb 314
samux 14:757226626acb 315 bool USBDevice::requestSetFeature()
samux 14:757226626acb 316 {
samux 14:757226626acb 317 bool success = false;
samux 14:757226626acb 318
samux 14:757226626acb 319 if (device.state != CONFIGURED)
samux 14:757226626acb 320 {
samux 14:757226626acb 321 /* Endpoint or interface must be zero */
samux 14:757226626acb 322 if (transfer.setup.wIndex != 0)
samux 14:757226626acb 323 {
samux 14:757226626acb 324 return false;
samux 14:757226626acb 325 }
samux 14:757226626acb 326 }
samux 14:757226626acb 327
samux 14:757226626acb 328 switch (transfer.setup.bmRequestType.Recipient)
samux 14:757226626acb 329 {
samux 14:757226626acb 330 case DEVICE_RECIPIENT:
samux 14:757226626acb 331 /* TODO: Remote wakeup feature not supported */
samux 14:757226626acb 332 break;
samux 14:757226626acb 333 case ENDPOINT_RECIPIENT:
samux 14:757226626acb 334 if (transfer.setup.wValue == ENDPOINT_HALT)
samux 14:757226626acb 335 {
samux 14:757226626acb 336 /* TODO: We should check that the endpoint number is valid */
samux 14:757226626acb 337 stallEndpoint(
samux 14:757226626acb 338 WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
samux 14:757226626acb 339 success = true;
samux 14:757226626acb 340 }
samux 14:757226626acb 341 break;
samux 14:757226626acb 342 default:
samux 14:757226626acb 343 break;
samux 14:757226626acb 344 }
samux 14:757226626acb 345
samux 14:757226626acb 346 return success;
samux 14:757226626acb 347 }
samux 14:757226626acb 348
samux 14:757226626acb 349 bool USBDevice::requestClearFeature()
samux 14:757226626acb 350 {
samux 14:757226626acb 351 bool success = false;
samux 14:757226626acb 352
samux 14:757226626acb 353 if (device.state != CONFIGURED)
samux 14:757226626acb 354 {
samux 14:757226626acb 355 /* Endpoint or interface must be zero */
samux 14:757226626acb 356 if (transfer.setup.wIndex != 0)
samux 14:757226626acb 357 {
samux 14:757226626acb 358 return false;
samux 14:757226626acb 359 }
samux 14:757226626acb 360 }
samux 14:757226626acb 361
samux 14:757226626acb 362 switch (transfer.setup.bmRequestType.Recipient)
samux 14:757226626acb 363 {
samux 14:757226626acb 364 case DEVICE_RECIPIENT:
samux 14:757226626acb 365 /* TODO: Remote wakeup feature not supported */
samux 14:757226626acb 366 break;
samux 14:757226626acb 367 case ENDPOINT_RECIPIENT:
samux 14:757226626acb 368 /* TODO: We should check that the endpoint number is valid */
samux 14:757226626acb 369 if (transfer.setup.wValue == ENDPOINT_HALT)
samux 14:757226626acb 370 {
samux 14:757226626acb 371 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
samux 14:757226626acb 372 success = true;
samux 14:757226626acb 373 }
samux 14:757226626acb 374 break;
samux 14:757226626acb 375 default:
samux 14:757226626acb 376 break;
samux 14:757226626acb 377 }
samux 14:757226626acb 378
samux 14:757226626acb 379 return success;
samux 14:757226626acb 380 }
samux 14:757226626acb 381
samux 14:757226626acb 382 bool USBDevice::requestGetStatus(void)
samux 14:757226626acb 383 {
samux 14:757226626acb 384 static uint16_t status;
samux 14:757226626acb 385 bool success = false;
samux 14:757226626acb 386
samux 14:757226626acb 387 if (device.state != CONFIGURED)
samux 14:757226626acb 388 {
samux 14:757226626acb 389 /* Endpoint or interface must be zero */
samux 14:757226626acb 390 if (transfer.setup.wIndex != 0)
samux 14:757226626acb 391 {
samux 14:757226626acb 392 return false;
samux 14:757226626acb 393 }
samux 14:757226626acb 394 }
samux 14:757226626acb 395
samux 14:757226626acb 396 switch (transfer.setup.bmRequestType.Recipient)
samux 14:757226626acb 397 {
samux 14:757226626acb 398 case DEVICE_RECIPIENT:
samux 14:757226626acb 399 /* TODO: Currently only supports self powered devices */
samux 14:757226626acb 400 status = DEVICE_STATUS_SELF_POWERED;
samux 14:757226626acb 401 success = true;
samux 14:757226626acb 402 break;
samux 14:757226626acb 403 case INTERFACE_RECIPIENT:
samux 14:757226626acb 404 status = 0;
samux 14:757226626acb 405 success = true;
samux 14:757226626acb 406 break;
samux 14:757226626acb 407 case ENDPOINT_RECIPIENT:
samux 14:757226626acb 408 /* TODO: We should check that the endpoint number is valid */
samux 14:757226626acb 409 if (getEndpointStallState(
samux 14:757226626acb 410 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
samux 14:757226626acb 411 {
samux 14:757226626acb 412 status = ENDPOINT_STATUS_HALT;
samux 14:757226626acb 413 }
samux 14:757226626acb 414 else
samux 14:757226626acb 415 {
samux 14:757226626acb 416 status = 0;
samux 14:757226626acb 417 }
samux 14:757226626acb 418 success = true;
samux 14:757226626acb 419 break;
samux 14:757226626acb 420 default:
samux 14:757226626acb 421 break;
samux 14:757226626acb 422 }
samux 14:757226626acb 423
samux 14:757226626acb 424 if (success)
samux 14:757226626acb 425 {
samux 14:757226626acb 426 /* Send the status */
samux 14:757226626acb 427 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
samux 14:757226626acb 428 transfer.remaining = sizeof(status);
samux 14:757226626acb 429 transfer.direction = DEVICE_TO_HOST;
samux 14:757226626acb 430 }
samux 14:757226626acb 431
samux 14:757226626acb 432 return success;
samux 14:757226626acb 433 }
samux 14:757226626acb 434
samux 14:757226626acb 435 bool USBDevice::requestSetup(void)
samux 14:757226626acb 436 {
samux 14:757226626acb 437 bool success = false;
samux 14:757226626acb 438
samux 14:757226626acb 439 /* Process standard requests */
samux 14:757226626acb 440 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
samux 14:757226626acb 441 {
samux 14:757226626acb 442 switch (transfer.setup.bRequest)
samux 14:757226626acb 443 {
samux 14:757226626acb 444 case GET_STATUS:
samux 14:757226626acb 445 success = requestGetStatus();
samux 14:757226626acb 446 break;
samux 14:757226626acb 447 case CLEAR_FEATURE:
samux 14:757226626acb 448 success = requestClearFeature();
samux 14:757226626acb 449 break;
samux 14:757226626acb 450 case SET_FEATURE:
samux 14:757226626acb 451 success = requestSetFeature();
samux 14:757226626acb 452 break;
samux 14:757226626acb 453 case SET_ADDRESS:
samux 14:757226626acb 454 success = requestSetAddress();
samux 14:757226626acb 455 break;
samux 14:757226626acb 456 case GET_DESCRIPTOR:
samux 14:757226626acb 457 success = requestGetDescriptor();
samux 14:757226626acb 458 break;
samux 14:757226626acb 459 case SET_DESCRIPTOR:
samux 14:757226626acb 460 /* TODO: Support is optional, not implemented here */
samux 14:757226626acb 461 success = false;
samux 14:757226626acb 462 break;
samux 14:757226626acb 463 case GET_CONFIGURATION:
samux 14:757226626acb 464 success = requestGetConfiguration();
samux 14:757226626acb 465 break;
samux 14:757226626acb 466 case SET_CONFIGURATION:
samux 14:757226626acb 467 success = requestSetConfiguration();
samux 14:757226626acb 468 break;
samux 14:757226626acb 469 case GET_INTERFACE:
samux 14:757226626acb 470 success = requestGetInterface();
samux 14:757226626acb 471 break;
samux 14:757226626acb 472 case SET_INTERFACE:
samux 14:757226626acb 473 success = requestSetInterface();
samux 14:757226626acb 474 break;
samux 14:757226626acb 475 default:
samux 14:757226626acb 476 break;
samux 14:757226626acb 477 }
samux 14:757226626acb 478 }
samux 14:757226626acb 479
samux 14:757226626acb 480 return success;
samux 14:757226626acb 481 }
samux 14:757226626acb 482
samux 14:757226626acb 483 bool USBDevice::controlSetup(void)
samux 14:757226626acb 484 {
samux 14:757226626acb 485 bool success = false;
samux 14:757226626acb 486
samux 14:757226626acb 487 /* Control transfer setup stage */
samux 14:757226626acb 488 uint8_t buffer[MAX_PACKET_SIZE_EP0];
samux 14:757226626acb 489
samux 14:757226626acb 490 EP0setup(buffer);
samux 14:757226626acb 491
samux 14:757226626acb 492 /* Initialise control transfer state */
samux 14:757226626acb 493 decodeSetupPacket(buffer, &transfer.setup);
samux 14:757226626acb 494 transfer.ptr = NULL;
samux 14:757226626acb 495 transfer.remaining = 0;
samux 14:757226626acb 496 transfer.direction = 0;
samux 14:757226626acb 497 transfer.zlp = false;
samux 14:757226626acb 498 transfer.notify = false;
samux 14:757226626acb 499
samux 14:757226626acb 500 /* Class / vendor specific */
samux 14:757226626acb 501 success = USBCallback_request();
samux 14:757226626acb 502
samux 14:757226626acb 503 if (!success)
samux 14:757226626acb 504 {
samux 14:757226626acb 505 /* Standard requests */
samux 14:757226626acb 506 if (!requestSetup())
samux 14:757226626acb 507 {
samux 14:757226626acb 508 return false;
samux 14:757226626acb 509 }
samux 14:757226626acb 510 }
samux 14:757226626acb 511
samux 14:757226626acb 512 /* Check transfer size and direction */
samux 14:757226626acb 513 if (transfer.setup.wLength>0)
samux 14:757226626acb 514 {
samux 14:757226626acb 515 if (transfer.setup.bmRequestType.dataTransferDirection \
samux 14:757226626acb 516 == DEVICE_TO_HOST)
samux 14:757226626acb 517 {
samux 14:757226626acb 518 /* IN data stage is required */
samux 14:757226626acb 519 if (transfer.direction != DEVICE_TO_HOST)
samux 14:757226626acb 520 {
samux 14:757226626acb 521 return false;
samux 14:757226626acb 522 }
samux 14:757226626acb 523
samux 14:757226626acb 524 /* Transfer must be less than or equal to the size */
samux 14:757226626acb 525 /* requested by the host */
samux 14:757226626acb 526 if (transfer.remaining > transfer.setup.wLength)
samux 14:757226626acb 527 {
samux 14:757226626acb 528 transfer.remaining = transfer.setup.wLength;
samux 14:757226626acb 529 }
samux 14:757226626acb 530 }
samux 14:757226626acb 531 else
samux 14:757226626acb 532 {
samux 14:757226626acb 533
samux 14:757226626acb 534 /* OUT data stage is required */
samux 14:757226626acb 535 if (transfer.direction != HOST_TO_DEVICE)
samux 14:757226626acb 536 {
samux 14:757226626acb 537 return false;
samux 14:757226626acb 538 }
samux 14:757226626acb 539
samux 14:757226626acb 540 /* Transfer must be equal to the size requested by the host */
samux 14:757226626acb 541 if (transfer.remaining != transfer.setup.wLength)
samux 14:757226626acb 542 {
samux 14:757226626acb 543 return false;
samux 14:757226626acb 544 }
samux 14:757226626acb 545 }
samux 14:757226626acb 546 }
samux 14:757226626acb 547 else
samux 14:757226626acb 548 {
samux 14:757226626acb 549 /* No data stage; transfer size must be zero */
samux 14:757226626acb 550 if (transfer.remaining != 0)
samux 14:757226626acb 551 {
samux 14:757226626acb 552 return false;
samux 14:757226626acb 553 }
samux 14:757226626acb 554 }
samux 14:757226626acb 555
samux 14:757226626acb 556 /* Data or status stage if applicable */
samux 14:757226626acb 557 if (transfer.setup.wLength>0)
samux 14:757226626acb 558 {
samux 14:757226626acb 559 if (transfer.setup.bmRequestType.dataTransferDirection \
samux 14:757226626acb 560 == DEVICE_TO_HOST)
samux 14:757226626acb 561 {
samux 14:757226626acb 562 /* Check if we'll need to send a zero length packet at */
samux 14:757226626acb 563 /* the end of this transfer */
samux 14:757226626acb 564 if (transfer.setup.wLength > transfer.remaining)
samux 14:757226626acb 565 {
samux 14:757226626acb 566 /* Device wishes to transfer less than host requested */
samux 14:757226626acb 567 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
samux 14:757226626acb 568 {
samux 14:757226626acb 569 /* Transfer is a multiple of EP0 max packet size */
samux 14:757226626acb 570 transfer.zlp = true;
samux 14:757226626acb 571 }
samux 14:757226626acb 572 }
samux 14:757226626acb 573
samux 14:757226626acb 574 /* IN stage */
samux 14:757226626acb 575 controlIn();
samux 14:757226626acb 576 }
samux 14:757226626acb 577 else
samux 14:757226626acb 578 {
samux 14:757226626acb 579 /* OUT stage */
samux 14:757226626acb 580 EP0read();
samux 14:757226626acb 581 }
samux 14:757226626acb 582 }
samux 14:757226626acb 583 else
samux 14:757226626acb 584 {
samux 14:757226626acb 585 /* Status stage */
samux 14:757226626acb 586 EP0write(NULL, 0);
samux 14:757226626acb 587 }
samux 14:757226626acb 588
samux 14:757226626acb 589 return true;
samux 14:757226626acb 590 }
samux 14:757226626acb 591
samux 14:757226626acb 592 void USBDevice::busReset(void)
samux 14:757226626acb 593 {
samux 14:757226626acb 594 device.state = DEFAULT;
samux 14:757226626acb 595 device.configuration = 0;
samux 14:757226626acb 596 device.suspended = false;
samux 14:757226626acb 597
samux 14:757226626acb 598 /* Call class / vendor specific busReset function */
samux 14:757226626acb 599 USBCallback_busReset();
samux 14:757226626acb 600 }
samux 14:757226626acb 601
samux 14:757226626acb 602 void USBDevice::EP0setupCallback(void)
samux 14:757226626acb 603 {
samux 14:757226626acb 604 /* Endpoint 0 setup event */
samux 14:757226626acb 605 if (!controlSetup())
samux 14:757226626acb 606 {
samux 14:757226626acb 607 /* Protocol stall */
samux 14:757226626acb 608 EP0stall();
samux 14:757226626acb 609 }
samux 14:757226626acb 610
samux 14:757226626acb 611 /* Return true if an OUT data stage is expected */
samux 14:757226626acb 612 }
samux 14:757226626acb 613
samux 14:757226626acb 614 void USBDevice::EP0out(void)
samux 14:757226626acb 615 {
samux 14:757226626acb 616 /* Endpoint 0 OUT data event */
samux 14:757226626acb 617 if (!controlOut())
samux 14:757226626acb 618 {
samux 14:757226626acb 619 /* Protocol stall; this will stall both endpoints */
samux 14:757226626acb 620 EP0stall();
samux 14:757226626acb 621 }
samux 14:757226626acb 622 }
samux 14:757226626acb 623
samux 14:757226626acb 624 void USBDevice::EP0in(void)
samux 14:757226626acb 625 {
samux 14:757226626acb 626 /* Endpoint 0 IN data event */
samux 14:757226626acb 627 if (!controlIn())
samux 14:757226626acb 628 {
samux 14:757226626acb 629 /* Protocol stall; this will stall both endpoints */
samux 14:757226626acb 630 EP0stall();
samux 14:757226626acb 631 }
samux 14:757226626acb 632 }
samux 14:757226626acb 633
samux 14:757226626acb 634 bool USBDevice::configured(void)
samux 14:757226626acb 635 {
samux 14:757226626acb 636 /* Returns true if device is in the CONFIGURED state */
samux 14:757226626acb 637 return (device.state == CONFIGURED);
samux 14:757226626acb 638 }
samux 14:757226626acb 639
samux 14:757226626acb 640 void USBDevice::connect(void)
samux 14:757226626acb 641 {
samux 14:757226626acb 642 /* Connect device */
samux 14:757226626acb 643 USBHAL::connect();
samux 14:757226626acb 644 /* Block if not configured */
samux 14:757226626acb 645 while (!configured());
samux 14:757226626acb 646 }
samux 14:757226626acb 647
samux 14:757226626acb 648 void USBDevice::disconnect(void)
samux 14:757226626acb 649 {
samux 14:757226626acb 650 /* Disconnect device */
samux 14:757226626acb 651 USBHAL::disconnect();
samux 14:757226626acb 652 }
samux 14:757226626acb 653
samux 14:757226626acb 654 CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
samux 14:757226626acb 655 {
samux 14:757226626acb 656 return &transfer;
samux 14:757226626acb 657 }
samux 14:757226626acb 658
samux 14:757226626acb 659 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
samux 14:757226626acb 660 {
samux 14:757226626acb 661 return realiseEndpoint(endpoint, maxPacket, 0);
samux 14:757226626acb 662 }
samux 14:757226626acb 663
samux 14:757226626acb 664 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
samux 14:757226626acb 665 {
samux 14:757226626acb 666 /* For interrupt endpoints only */
samux 14:757226626acb 667 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
samux 14:757226626acb 668 }
samux 14:757226626acb 669
samux 14:757226626acb 670 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
samux 14:757226626acb 671 {
samux 14:757226626acb 672 /* Find a descriptor within the list of descriptors */
samux 14:757226626acb 673 /* following a configuration descriptor. */
samux 14:757226626acb 674 uint16_t wTotalLength;
samux 14:757226626acb 675 uint8_t *ptr;
samux 14:757226626acb 676
samux 14:757226626acb 677 if (configurationDesc() == NULL)
samux 14:757226626acb 678 {
samux 14:757226626acb 679 return NULL;
samux 14:757226626acb 680 }
samux 14:757226626acb 681
samux 14:757226626acb 682 /* Check this is a configuration descriptor */
samux 14:757226626acb 683 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
samux 14:757226626acb 684 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
samux 14:757226626acb 685 {
samux 14:757226626acb 686 return NULL;
samux 14:757226626acb 687 }
samux 14:757226626acb 688
samux 14:757226626acb 689 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
samux 14:757226626acb 690
samux 14:757226626acb 691 /* Check there are some more descriptors to follow */
samux 14:757226626acb 692 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
samux 14:757226626acb 693 /* +2 is for bLength and bDescriptorType of next descriptor */
samux 14:757226626acb 694 {
samux 14:757226626acb 695 return false;
samux 14:757226626acb 696 }
samux 14:757226626acb 697
samux 14:757226626acb 698 /* Start at first descriptor after the configuration descriptor */
samux 14:757226626acb 699 ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
samux 14:757226626acb 700
samux 14:757226626acb 701 do {
samux 14:757226626acb 702 if (ptr[1] /* bDescriptorType */ == descriptorType)
samux 14:757226626acb 703 {
samux 14:757226626acb 704 /* Found */
samux 14:757226626acb 705 return ptr;
samux 14:757226626acb 706 }
samux 14:757226626acb 707
samux 14:757226626acb 708 /* Skip to next descriptor */
samux 14:757226626acb 709 ptr += ptr[0]; /* bLength */
samux 14:757226626acb 710 } while (ptr < (configurationDesc() + wTotalLength));
samux 14:757226626acb 711
samux 14:757226626acb 712 /* Reached end of the descriptors - not found */
samux 14:757226626acb 713 return NULL;
samux 14:757226626acb 714 }
samux 14:757226626acb 715
samux 14:757226626acb 716
samux 14:757226626acb 717 void USBDevice::connectStateChanged(unsigned int connected)
samux 14:757226626acb 718 {
samux 14:757226626acb 719 }
samux 14:757226626acb 720
samux 14:757226626acb 721 void USBDevice::suspendStateChanged(unsigned int suspended)
samux 14:757226626acb 722 {
samux 14:757226626acb 723 }
samux 14:757226626acb 724
samux 14:757226626acb 725
samux 14:757226626acb 726 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
samux 14:757226626acb 727 VENDOR_ID = vendor_id;
samux 14:757226626acb 728 PRODUCT_ID = product_id;
samux 14:757226626acb 729 PRODUCT_RELEASE = product_release;
samux 14:757226626acb 730
samux 14:757226626acb 731 /* Set initial device state */
samux 14:757226626acb 732 device.state = POWERED;
samux 14:757226626acb 733 device.configuration = 0;
samux 14:757226626acb 734 device.suspended = false;
samux 14:757226626acb 735 };
samux 14:757226626acb 736
samux 14:757226626acb 737
samux 14:757226626acb 738 bool USBDevice::readStart(uint8_t endpoint, uint16_t maxSize)
samux 14:757226626acb 739 {
samux 14:757226626acb 740 return endpointRead(endpoint, maxSize) == EP_PENDING;
samux 14:757226626acb 741 }
samux 14:757226626acb 742
samux 14:757226626acb 743
samux 14:757226626acb 744 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize)
samux 14:757226626acb 745 {
samux 14:757226626acb 746 EP_STATUS result;
samux 14:757226626acb 747
samux 14:757226626acb 748 if (size > maxSize)
samux 14:757226626acb 749 {
samux 14:757226626acb 750 return false;
samux 14:757226626acb 751 }
samux 14:757226626acb 752
samux 14:757226626acb 753
samux 14:757226626acb 754 if(!configured()) {
samux 14:757226626acb 755 return false;
samux 14:757226626acb 756 }
samux 14:757226626acb 757
samux 14:757226626acb 758 /* Send report */
samux 14:757226626acb 759 result = endpointWrite(endpoint, buffer, size);
samux 14:757226626acb 760
samux 14:757226626acb 761 if (result != EP_PENDING)
samux 14:757226626acb 762 {
samux 14:757226626acb 763 return false;
samux 14:757226626acb 764 }
samux 14:757226626acb 765
samux 14:757226626acb 766 /* Wait for completion */
samux 14:757226626acb 767 do {
samux 14:757226626acb 768 result = endpointWriteResult(endpoint);
samux 14:757226626acb 769 } while ((result == EP_PENDING) && configured());
samux 14:757226626acb 770
samux 14:757226626acb 771 return (result == EP_COMPLETED);
samux 14:757226626acb 772 }
samux 14:757226626acb 773
samux 14:757226626acb 774
samux 14:757226626acb 775 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint16_t size, uint16_t maxSize)
samux 14:757226626acb 776 {
samux 14:757226626acb 777 EP_STATUS result;
samux 14:757226626acb 778
samux 14:757226626acb 779 if (size > maxSize)
samux 14:757226626acb 780 {
samux 14:757226626acb 781 return false;
samux 14:757226626acb 782 }
samux 14:757226626acb 783
samux 14:757226626acb 784 if(!configured()) {
samux 14:757226626acb 785 return false;
samux 14:757226626acb 786 }
samux 14:757226626acb 787
samux 14:757226626acb 788 /* Send report */
samux 14:757226626acb 789 result = endpointWrite(endpoint, buffer, size);
samux 14:757226626acb 790
samux 14:757226626acb 791 if (result != EP_PENDING)
samux 14:757226626acb 792 {
samux 14:757226626acb 793 return false;
samux 14:757226626acb 794 }
samux 14:757226626acb 795
samux 14:757226626acb 796 result = endpointWriteResult(endpoint);
samux 14:757226626acb 797
samux 14:757226626acb 798 return (result == EP_COMPLETED);
samux 14:757226626acb 799 }
samux 14:757226626acb 800
samux 14:757226626acb 801
samux 14:757226626acb 802
samux 14:757226626acb 803 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
samux 14:757226626acb 804 {
samux 14:757226626acb 805 EP_STATUS result;
samux 14:757226626acb 806
samux 14:757226626acb 807 if(!configured()) {
samux 14:757226626acb 808 return false;
samux 14:757226626acb 809 }
samux 14:757226626acb 810
samux 14:757226626acb 811 /* Wait for completion */
samux 14:757226626acb 812 do {
samux 14:757226626acb 813 result = endpointReadResult(endpoint, buffer, (uint32_t *)size);
samux 14:757226626acb 814 } while ((result == EP_PENDING) && configured());
samux 14:757226626acb 815
samux 14:757226626acb 816 return (result == EP_COMPLETED);
samux 14:757226626acb 817 }
samux 14:757226626acb 818
samux 14:757226626acb 819
samux 14:757226626acb 820 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint16_t * size, uint16_t maxSize)
samux 14:757226626acb 821 {
samux 14:757226626acb 822 EP_STATUS result;
samux 14:757226626acb 823
samux 14:757226626acb 824 if(!configured()) {
samux 14:757226626acb 825 return false;
samux 14:757226626acb 826 }
samux 14:757226626acb 827
samux 14:757226626acb 828 result = endpointReadResult(endpoint, buffer, (uint32_t *)size);
samux 14:757226626acb 829
samux 14:757226626acb 830 return (result == EP_COMPLETED);
samux 14:757226626acb 831 }
samux 14:757226626acb 832
samux 14:757226626acb 833
samux 14:757226626acb 834
samux 14:757226626acb 835 uint8_t * USBDevice::deviceDesc() {
samux 14:757226626acb 836 static uint8_t deviceDescriptor[] = {
samux 14:757226626acb 837 DEVICE_DESCRIPTOR_LENGTH, /* bLength */
samux 14:757226626acb 838 DEVICE_DESCRIPTOR, /* bDescriptorType */
samux 14:757226626acb 839 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
samux 14:757226626acb 840 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
samux 14:757226626acb 841 0x00, /* bDeviceClass */
samux 14:757226626acb 842 0x00, /* bDeviceSubClass */
samux 14:757226626acb 843 0x00, /* bDeviceprotocol */
samux 14:757226626acb 844 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
samux 14:757226626acb 845 LSB(VENDOR_ID), /* idVendor (LSB) */
samux 14:757226626acb 846 MSB(VENDOR_ID), /* idVendor (MSB) */
samux 14:757226626acb 847 LSB(PRODUCT_ID), /* idProduct (LSB) */
samux 14:757226626acb 848 MSB(PRODUCT_ID), /* idProduct (MSB) */
samux 14:757226626acb 849 LSB(PRODUCT_RELEASE), /* bcdDevice (LSB) */
samux 14:757226626acb 850 MSB(PRODUCT_RELEASE), /* bcdDevice (MSB) */
samux 14:757226626acb 851 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
samux 14:757226626acb 852 STRING_OFFSET_IPRODUCT, /* iProduct */
samux 14:757226626acb 853 STRING_OFFSET_ISERIAL, /* iSerialNumber */
samux 14:757226626acb 854 0x01 /* bNumConfigurations */
samux 14:757226626acb 855 };
samux 14:757226626acb 856 return deviceDescriptor;
samux 14:757226626acb 857 }
samux 14:757226626acb 858
samux 14:757226626acb 859 uint8_t * USBDevice::stringLangidDesc() {
samux 14:757226626acb 860 static uint8_t stringLangidDescriptor[] = {
samux 14:757226626acb 861 0x04, /*bLength*/
samux 14:757226626acb 862 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 863 0x09,0x00, /*bString Lang ID - 0x009 - English*/
samux 14:757226626acb 864 };
samux 14:757226626acb 865 return stringLangidDescriptor;
samux 14:757226626acb 866 }
samux 14:757226626acb 867
samux 14:757226626acb 868 uint8_t * USBDevice::stringImanufacturerDesc() {
samux 14:757226626acb 869 static uint8_t stringImanufacturerDescriptor[] = {
samux 14:757226626acb 870 0x12, /*bLength*/
samux 14:757226626acb 871 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 872 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
samux 14:757226626acb 873 };
samux 14:757226626acb 874 return stringImanufacturerDescriptor;
samux 14:757226626acb 875 }
samux 14:757226626acb 876
samux 14:757226626acb 877 uint8_t * USBDevice::stringIserialDesc() {
samux 14:757226626acb 878 static uint8_t stringIserialDescriptor[] = {
samux 14:757226626acb 879 0x16, /*bLength*/
samux 14:757226626acb 880 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 881 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
samux 14:757226626acb 882 };
samux 14:757226626acb 883 return stringIserialDescriptor;
samux 14:757226626acb 884 }
samux 14:757226626acb 885
samux 14:757226626acb 886 uint8_t * USBDevice::stringIConfigurationDesc() {
samux 14:757226626acb 887 static uint8_t stringIconfigurationDescriptor[] = {
samux 14:757226626acb 888 0x06, /*bLength*/
samux 14:757226626acb 889 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 890 '0',0,'1',0, /*bString iConfiguration - 01*/
samux 14:757226626acb 891 };
samux 14:757226626acb 892 return stringIconfigurationDescriptor;
samux 14:757226626acb 893 }
samux 14:757226626acb 894
samux 14:757226626acb 895 uint8_t * USBDevice::stringIinterfaceDesc() {
samux 14:757226626acb 896 static uint8_t stringIinterfaceDescriptor[] = {
samux 14:757226626acb 897 0x08, /*bLength*/
samux 14:757226626acb 898 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 899 'U',0,'S',0,'B',0, /*bString iInterface - USB*/
samux 14:757226626acb 900 };
samux 14:757226626acb 901 return stringIinterfaceDescriptor;
samux 14:757226626acb 902 }
samux 14:757226626acb 903
samux 14:757226626acb 904 uint8_t * USBDevice::stringIproductDesc() {
samux 14:757226626acb 905 static uint8_t stringIproductDescriptor[] = {
samux 14:757226626acb 906 0x16, /*bLength*/
samux 14:757226626acb 907 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
samux 14:757226626acb 908 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
samux 14:757226626acb 909 };
samux 14:757226626acb 910 return stringIproductDescriptor;
samux 14:757226626acb 911 }