B. H. / Mbed 2 deprecated trolololol

Dependencies:   mbed

Committer:
znuh
Date:
Tue Nov 29 21:26:20 2011 +0000
Revision:
0:505207de8566

        

Who changed what in which revision?

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