USB Keyboard and mouse Example. Based on USBMouse

Dependencies:   mbed

Fork of USBKeyboardMouse by Zack Clobes

Committer:
Wabouz
Date:
Wed May 08 09:33:27 2013 +0000
Revision:
1:9c83250ce43b
Parent:
0:86603687efec
Un petit programme.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zackc 0:86603687efec 1 /* usbdevice.cpp */
zackc 0:86603687efec 2 /* Generic USB device */
zackc 0:86603687efec 3 /* Copyright (c) Phil Wright 2008 */
zackc 0:86603687efec 4
zackc 0:86603687efec 5 #include "mbed.h"
zackc 0:86603687efec 6 #include "usbdevice.h"
zackc 0:86603687efec 7
zackc 0:86603687efec 8 /* Standard requests */
zackc 0:86603687efec 9 #define GET_STATUS (0)
zackc 0:86603687efec 10 #define CLEAR_FEATURE (1)
zackc 0:86603687efec 11 #define SET_FEATURE (3)
zackc 0:86603687efec 12 #define SET_ADDRESS (5)
zackc 0:86603687efec 13 #define GET_DESCRIPTOR (6)
zackc 0:86603687efec 14 #define SET_DESCRIPTOR (7)
zackc 0:86603687efec 15 #define GET_CONFIGURATION (8)
zackc 0:86603687efec 16 #define SET_CONFIGURATION (9)
zackc 0:86603687efec 17 #define GET_INTERFACE (10)
zackc 0:86603687efec 18 #define SET_INTERFACE (11)
zackc 0:86603687efec 19
zackc 0:86603687efec 20 /* Device status */
zackc 0:86603687efec 21 #define DEVICE_STATUS_SELF_POWERED (1<<0)
zackc 0:86603687efec 22 #define DEVICE_STATUS_REMOTE_WAKEUP (1<<1)
zackc 0:86603687efec 23
zackc 0:86603687efec 24 /* Endpoint status */
zackc 0:86603687efec 25 #define ENDPOINT_STATUS_HALT (1<<0)
zackc 0:86603687efec 26
zackc 0:86603687efec 27 /* Standard feature selectors */
zackc 0:86603687efec 28 #define DEVICE_REMOTE_WAKEUP (1)
zackc 0:86603687efec 29 #define ENDPOINT_HALT (0)
zackc 0:86603687efec 30
zackc 0:86603687efec 31 /* Macro to convert wIndex endpoint number to physical endpoint number */
zackc 0:86603687efec 32 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + ((endpoint & 0x80) ? 1 : 0))
zackc 0:86603687efec 33
zackc 0:86603687efec 34 CONTROL_TRANSFER transfer;
zackc 0:86603687efec 35 USB_DEVICE device;
zackc 0:86603687efec 36
zackc 0:86603687efec 37 usbdevice::usbdevice()
zackc 0:86603687efec 38 {
zackc 0:86603687efec 39 /* Set initial device state */
zackc 0:86603687efec 40 device.state = POWERED;
zackc 0:86603687efec 41 device.configuration = 0;
zackc 0:86603687efec 42 device.suspended = false;
zackc 0:86603687efec 43
zackc 0:86603687efec 44 /* Set the maximum packet size for the control endpoints */
zackc 0:86603687efec 45 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0);
zackc 0:86603687efec 46 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0);
zackc 0:86603687efec 47
zackc 0:86603687efec 48 /* Enable endpoint events for EP0 */
zackc 0:86603687efec 49 enableEndpointEvent(EP0IN);
zackc 0:86603687efec 50 enableEndpointEvent(EP0OUT);
zackc 0:86603687efec 51 }
zackc 0:86603687efec 52
zackc 0:86603687efec 53 void usbdevice::endpointEventEP0Setup(void)
zackc 0:86603687efec 54 {
zackc 0:86603687efec 55 /* Endpoint 0 setup event */
zackc 0:86603687efec 56 if (!controlSetup())
zackc 0:86603687efec 57 {
zackc 0:86603687efec 58 /* Protocol stall; this will stall both endpoints */
zackc 0:86603687efec 59 stallEndpoint(EP0OUT);
zackc 0:86603687efec 60 }
zackc 0:86603687efec 61 }
zackc 0:86603687efec 62
zackc 0:86603687efec 63 void usbdevice::endpointEventEP0Out(void)
zackc 0:86603687efec 64 {
zackc 0:86603687efec 65 /* Endpoint 0 OUT data event */
zackc 0:86603687efec 66 if (!controlOut())
zackc 0:86603687efec 67 {
zackc 0:86603687efec 68 /* Protocol stall; this will stall both endpoints */
zackc 0:86603687efec 69 stallEndpoint(EP0OUT);
zackc 0:86603687efec 70 }
zackc 0:86603687efec 71 }
zackc 0:86603687efec 72
zackc 0:86603687efec 73 void usbdevice::endpointEventEP0In(void)
zackc 0:86603687efec 74 {
zackc 0:86603687efec 75 /* Endpoint 0 IN data event */
zackc 0:86603687efec 76 if (!controlIn())
zackc 0:86603687efec 77 {
zackc 0:86603687efec 78 /* Protocol stall; this will stall both endpoints */
zackc 0:86603687efec 79 stallEndpoint(EP0OUT);
zackc 0:86603687efec 80 }
zackc 0:86603687efec 81 }
zackc 0:86603687efec 82
zackc 0:86603687efec 83 void usbdevice::deviceEventReset(void)
zackc 0:86603687efec 84 {
zackc 0:86603687efec 85 device.state = DEFAULT;
zackc 0:86603687efec 86 device.configuration = 0;
zackc 0:86603687efec 87 device.suspended = false;
zackc 0:86603687efec 88 }
zackc 0:86603687efec 89
zackc 0:86603687efec 90 void usbdevice::decodeSetupPacket(unsigned char *data, SETUP_PACKET *packet)
zackc 0:86603687efec 91 {
zackc 0:86603687efec 92 /* Fill in the elements of a SETUP_PACKET structure from raw data */
zackc 0:86603687efec 93 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
zackc 0:86603687efec 94 packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
zackc 0:86603687efec 95 packet->bmRequestType.Recipient = data[0] & 0x1f;
zackc 0:86603687efec 96 packet->bRequest = data[1];
zackc 0:86603687efec 97 packet->wValue = (data[2] | (unsigned short)data[3] << 8);
zackc 0:86603687efec 98 packet->wIndex = (data[4] | (unsigned short)data[5] << 8);
zackc 0:86603687efec 99 packet->wLength = (data[6] | (unsigned short)data[7] << 8);
zackc 0:86603687efec 100 }
zackc 0:86603687efec 101
zackc 0:86603687efec 102 bool usbdevice::controlSetup(void)
zackc 0:86603687efec 103 {
zackc 0:86603687efec 104 /* Control transfer setup stage */
zackc 0:86603687efec 105 unsigned char buffer[MAX_PACKET_SIZE_EP0];
zackc 0:86603687efec 106 unsigned long count;
zackc 0:86603687efec 107
zackc 0:86603687efec 108 count = endpointRead(EP0OUT, buffer);
zackc 0:86603687efec 109
zackc 0:86603687efec 110 /* Must be 8 bytes of data */
zackc 0:86603687efec 111 if (count != 8)
zackc 0:86603687efec 112 {
zackc 0:86603687efec 113 return false;
zackc 0:86603687efec 114 }
zackc 0:86603687efec 115
zackc 0:86603687efec 116 /* Initialise control transfer state */
zackc 0:86603687efec 117 decodeSetupPacket(buffer, &transfer.setup);
zackc 0:86603687efec 118 transfer.ptr = NULL;
zackc 0:86603687efec 119 transfer.remaining = 0;
zackc 0:86603687efec 120 transfer.direction = 0;
zackc 0:86603687efec 121 transfer.zlp = false;
zackc 0:86603687efec 122
zackc 0:86603687efec 123 /* Process request */
zackc 0:86603687efec 124 if (!requestSetup())
zackc 0:86603687efec 125 {
zackc 0:86603687efec 126 return false;
zackc 0:86603687efec 127 }
zackc 0:86603687efec 128
zackc 0:86603687efec 129 /* Check transfer size and direction */
zackc 0:86603687efec 130 if (transfer.setup.wLength>0)
zackc 0:86603687efec 131 {
zackc 0:86603687efec 132 if (transfer.setup.bmRequestType.dataTransferDirection==DEVICE_TO_HOST)
zackc 0:86603687efec 133 {
zackc 0:86603687efec 134 /* IN data stage is required */
zackc 0:86603687efec 135 if (transfer.direction != DEVICE_TO_HOST)
zackc 0:86603687efec 136 {
zackc 0:86603687efec 137 return false;
zackc 0:86603687efec 138 }
zackc 0:86603687efec 139
zackc 0:86603687efec 140 /* Transfer must be less than or equal to the size requested by the host */
zackc 0:86603687efec 141 if (transfer.remaining > transfer.setup.wLength)
zackc 0:86603687efec 142 {
zackc 0:86603687efec 143 transfer.remaining = transfer.setup.wLength;
zackc 0:86603687efec 144 }
zackc 0:86603687efec 145 }
zackc 0:86603687efec 146 else
zackc 0:86603687efec 147 {
zackc 0:86603687efec 148 /* OUT data stage is required */
zackc 0:86603687efec 149 if (transfer.direction != HOST_TO_DEVICE)
zackc 0:86603687efec 150 {
zackc 0:86603687efec 151 return false;
zackc 0:86603687efec 152 }
zackc 0:86603687efec 153
zackc 0:86603687efec 154 /* Transfer must be equal to the size requested by the host */
zackc 0:86603687efec 155 if (transfer.remaining != transfer.setup.wLength)
zackc 0:86603687efec 156 {
zackc 0:86603687efec 157 return false;
zackc 0:86603687efec 158 }
zackc 0:86603687efec 159 }
zackc 0:86603687efec 160 }
zackc 0:86603687efec 161 else
zackc 0:86603687efec 162 {
zackc 0:86603687efec 163 /* No data stage; transfer size must be zero */
zackc 0:86603687efec 164 if (transfer.remaining != 0)
zackc 0:86603687efec 165 {
zackc 0:86603687efec 166 return false;
zackc 0:86603687efec 167 }
zackc 0:86603687efec 168 }
zackc 0:86603687efec 169
zackc 0:86603687efec 170 /* Data or status stage if applicable */
zackc 0:86603687efec 171 if (transfer.setup.wLength>0)
zackc 0:86603687efec 172 {
zackc 0:86603687efec 173 if (transfer.setup.bmRequestType.dataTransferDirection==DEVICE_TO_HOST)
zackc 0:86603687efec 174 {
zackc 0:86603687efec 175 /* Check if we'll need to send a zero length packet at the end of this transfer */
zackc 0:86603687efec 176 if (transfer.setup.wLength > transfer.remaining)
zackc 0:86603687efec 177 {
zackc 0:86603687efec 178 /* Device wishes to transfer less than host requested */
zackc 0:86603687efec 179 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
zackc 0:86603687efec 180 {
zackc 0:86603687efec 181 /* Transfer is a multiple of EP0 max packet size */
zackc 0:86603687efec 182 transfer.zlp = true;
zackc 0:86603687efec 183 }
zackc 0:86603687efec 184 }
zackc 0:86603687efec 185
zackc 0:86603687efec 186 /* IN stage */
zackc 0:86603687efec 187 controlIn();
zackc 0:86603687efec 188 }
zackc 0:86603687efec 189 }
zackc 0:86603687efec 190 else
zackc 0:86603687efec 191 {
zackc 0:86603687efec 192 /* Status stage */
zackc 0:86603687efec 193 endpointWrite(EP0IN, NULL, 0);
zackc 0:86603687efec 194 }
zackc 0:86603687efec 195
zackc 0:86603687efec 196 return true;
zackc 0:86603687efec 197 }
zackc 0:86603687efec 198
zackc 0:86603687efec 199 bool usbdevice::controlOut(void)
zackc 0:86603687efec 200 {
zackc 0:86603687efec 201 /* Control transfer data OUT stage */
zackc 0:86603687efec 202 unsigned char buffer[MAX_PACKET_SIZE_EP0];
zackc 0:86603687efec 203 unsigned long packetSize;
zackc 0:86603687efec 204
zackc 0:86603687efec 205 /* Check we should be transferring data OUT */
zackc 0:86603687efec 206 if (transfer.direction != HOST_TO_DEVICE)
zackc 0:86603687efec 207 {
zackc 0:86603687efec 208 return false;
zackc 0:86603687efec 209 }
zackc 0:86603687efec 210
zackc 0:86603687efec 211 /* Read from endpoint */
zackc 0:86603687efec 212 packetSize = endpointRead(EP0OUT, buffer);
zackc 0:86603687efec 213
zackc 0:86603687efec 214 /* Check if transfer size is valid */
zackc 0:86603687efec 215 if (packetSize > transfer.remaining)
zackc 0:86603687efec 216 {
zackc 0:86603687efec 217 /* Too big */
zackc 0:86603687efec 218 return false;
zackc 0:86603687efec 219 }
zackc 0:86603687efec 220
zackc 0:86603687efec 221 /* Update transfer */
zackc 0:86603687efec 222 transfer.ptr += packetSize;
zackc 0:86603687efec 223 transfer.remaining -= packetSize;
zackc 0:86603687efec 224
zackc 0:86603687efec 225 /* Check if transfer has completed */
zackc 0:86603687efec 226 if (transfer.remaining == 0)
zackc 0:86603687efec 227 {
zackc 0:86603687efec 228 /* Process request */
zackc 0:86603687efec 229 if (!requestOut())
zackc 0:86603687efec 230 {
zackc 0:86603687efec 231 return false;
zackc 0:86603687efec 232 }
zackc 0:86603687efec 233
zackc 0:86603687efec 234 /* Status stage */
zackc 0:86603687efec 235 endpointWrite(EP0IN, NULL, 0);
zackc 0:86603687efec 236 }
zackc 0:86603687efec 237
zackc 0:86603687efec 238 return true;
zackc 0:86603687efec 239 }
zackc 0:86603687efec 240
zackc 0:86603687efec 241 bool usbdevice::controlIn(void)
zackc 0:86603687efec 242 {
zackc 0:86603687efec 243 /* Control transfer data IN stage */
zackc 0:86603687efec 244 unsigned packetSize;
zackc 0:86603687efec 245
zackc 0:86603687efec 246 /* Check if transfer has completed (status stage transactions also have transfer.remaining == 0) */
zackc 0:86603687efec 247 if (transfer.remaining == 0)
zackc 0:86603687efec 248 {
zackc 0:86603687efec 249 if (transfer.zlp)
zackc 0:86603687efec 250 {
zackc 0:86603687efec 251 /* Send zero length packet */
zackc 0:86603687efec 252 endpointWrite(EP0IN, NULL, 0);
zackc 0:86603687efec 253 transfer.zlp = false;
zackc 0:86603687efec 254 }
zackc 0:86603687efec 255
zackc 0:86603687efec 256 /* Completed */
zackc 0:86603687efec 257 return true;
zackc 0:86603687efec 258 }
zackc 0:86603687efec 259
zackc 0:86603687efec 260 /* Check we should be transferring data IN */
zackc 0:86603687efec 261 if (transfer.direction != DEVICE_TO_HOST)
zackc 0:86603687efec 262 {
zackc 0:86603687efec 263 return false;
zackc 0:86603687efec 264 }
zackc 0:86603687efec 265
zackc 0:86603687efec 266 packetSize = transfer.remaining;
zackc 0:86603687efec 267
zackc 0:86603687efec 268 if (packetSize > MAX_PACKET_SIZE_EP0)
zackc 0:86603687efec 269 {
zackc 0:86603687efec 270 packetSize = MAX_PACKET_SIZE_EP0;
zackc 0:86603687efec 271 }
zackc 0:86603687efec 272
zackc 0:86603687efec 273 /* Write to endpoint */
zackc 0:86603687efec 274 endpointWrite(EP0IN, transfer.ptr, packetSize);
zackc 0:86603687efec 275
zackc 0:86603687efec 276 /* Update transfer */
zackc 0:86603687efec 277 transfer.ptr += packetSize;
zackc 0:86603687efec 278 transfer.remaining -= packetSize;
zackc 0:86603687efec 279
zackc 0:86603687efec 280 return true;
zackc 0:86603687efec 281 }
zackc 0:86603687efec 282
zackc 0:86603687efec 283 bool usbdevice::requestSetup(void)
zackc 0:86603687efec 284 {
zackc 0:86603687efec 285 bool success = false;
zackc 0:86603687efec 286
zackc 0:86603687efec 287 /* Process standard requests */
zackc 0:86603687efec 288 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
zackc 0:86603687efec 289 {
zackc 0:86603687efec 290 switch (transfer.setup.bRequest)
zackc 0:86603687efec 291 {
zackc 0:86603687efec 292 case GET_STATUS:
zackc 0:86603687efec 293 success = requestGetStatus();
zackc 0:86603687efec 294 break;
zackc 0:86603687efec 295 case CLEAR_FEATURE:
zackc 0:86603687efec 296 success = requestClearFeature();
zackc 0:86603687efec 297 break;
zackc 0:86603687efec 298 case SET_FEATURE:
zackc 0:86603687efec 299 success = requestSetFeature();
zackc 0:86603687efec 300 break;
zackc 0:86603687efec 301 case SET_ADDRESS:
zackc 0:86603687efec 302 success = requestSetAddress();
zackc 0:86603687efec 303 break;
zackc 0:86603687efec 304 case GET_DESCRIPTOR:
zackc 0:86603687efec 305 success = requestGetDescriptor();
zackc 0:86603687efec 306 break;
zackc 0:86603687efec 307 case SET_DESCRIPTOR:
zackc 0:86603687efec 308 /* TODO: Support is optional, not implemented here */
zackc 0:86603687efec 309 success = false;
zackc 0:86603687efec 310 break;
zackc 0:86603687efec 311 case GET_CONFIGURATION:
zackc 0:86603687efec 312 success = requestGetConfiguration();
zackc 0:86603687efec 313 break;
zackc 0:86603687efec 314 case SET_CONFIGURATION:
zackc 0:86603687efec 315 success = requestSetConfiguration();
zackc 0:86603687efec 316 break;
zackc 0:86603687efec 317 case GET_INTERFACE:
zackc 0:86603687efec 318 success = requestGetInterface();
zackc 0:86603687efec 319 break;
zackc 0:86603687efec 320 case SET_INTERFACE:
zackc 0:86603687efec 321 success = requestSetInterface();
zackc 0:86603687efec 322 break;
zackc 0:86603687efec 323 default:
zackc 0:86603687efec 324 break;
zackc 0:86603687efec 325 }
zackc 0:86603687efec 326 }
zackc 0:86603687efec 327
zackc 0:86603687efec 328 return success;
zackc 0:86603687efec 329 }
zackc 0:86603687efec 330
zackc 0:86603687efec 331 bool usbdevice::requestOut(void)
zackc 0:86603687efec 332 {
zackc 0:86603687efec 333 return true;
zackc 0:86603687efec 334 }
zackc 0:86603687efec 335
zackc 0:86603687efec 336 bool usbdevice::requestSetAddress(void)
zackc 0:86603687efec 337 {
zackc 0:86603687efec 338 /* Set the device address */
zackc 0:86603687efec 339 setAddress(transfer.setup.wValue);
zackc 0:86603687efec 340
zackc 0:86603687efec 341 if (transfer.setup.wValue == 0)
zackc 0:86603687efec 342 {
zackc 0:86603687efec 343 device.state = DEFAULT;
zackc 0:86603687efec 344 }
zackc 0:86603687efec 345 else
zackc 0:86603687efec 346 {
zackc 0:86603687efec 347 device.state = ADDRESS;
zackc 0:86603687efec 348 }
zackc 0:86603687efec 349
zackc 0:86603687efec 350 return true;
zackc 0:86603687efec 351 }
zackc 0:86603687efec 352
zackc 0:86603687efec 353 bool usbdevice::requestSetConfiguration(void)
zackc 0:86603687efec 354 {
zackc 0:86603687efec 355 /* Set the device configuration */
zackc 0:86603687efec 356 if (transfer.setup.wValue == 0)
zackc 0:86603687efec 357 {
zackc 0:86603687efec 358 /* Not configured */
zackc 0:86603687efec 359 unconfigureDevice();
zackc 0:86603687efec 360 device.state = ADDRESS;
zackc 0:86603687efec 361 }
zackc 0:86603687efec 362 else
zackc 0:86603687efec 363 {
zackc 0:86603687efec 364 configureDevice();
zackc 0:86603687efec 365 device.state = CONFIGURED;
zackc 0:86603687efec 366 }
zackc 0:86603687efec 367
zackc 0:86603687efec 368 /* TODO: We do not currently support multiple configurations, just keep a record of the configuration value */
zackc 0:86603687efec 369 device.configuration = transfer.setup.wValue;
zackc 0:86603687efec 370
zackc 0:86603687efec 371 return true;
zackc 0:86603687efec 372 }
zackc 0:86603687efec 373
zackc 0:86603687efec 374 bool usbdevice::requestGetConfiguration(void)
zackc 0:86603687efec 375 {
zackc 0:86603687efec 376 /* Send the device configuration */
zackc 0:86603687efec 377 transfer.ptr = &device.configuration;
zackc 0:86603687efec 378 transfer.remaining = sizeof(device.configuration);
zackc 0:86603687efec 379 transfer.direction = DEVICE_TO_HOST;
zackc 0:86603687efec 380 return true;
zackc 0:86603687efec 381 }
zackc 0:86603687efec 382
zackc 0:86603687efec 383 bool usbdevice::requestGetInterface(void)
zackc 0:86603687efec 384 {
zackc 0:86603687efec 385 static unsigned char alternateSetting;
zackc 0:86603687efec 386
zackc 0:86603687efec 387 /* Return the selected alternate setting for an interface */
zackc 0:86603687efec 388
zackc 0:86603687efec 389 if (device.state != CONFIGURED)
zackc 0:86603687efec 390 {
zackc 0:86603687efec 391 return false;
zackc 0:86603687efec 392 }
zackc 0:86603687efec 393
zackc 0:86603687efec 394 /* TODO: We currently do not support alternate settings so always return zero */
zackc 0:86603687efec 395 /* TODO: Should check that the interface number is valid */
zackc 0:86603687efec 396 alternateSetting = 0;
zackc 0:86603687efec 397
zackc 0:86603687efec 398 /* Send the alternate setting */
zackc 0:86603687efec 399 transfer.ptr = &alternateSetting;
zackc 0:86603687efec 400 transfer.remaining = sizeof(alternateSetting);
zackc 0:86603687efec 401 transfer.direction = DEVICE_TO_HOST;
zackc 0:86603687efec 402 return true;
zackc 0:86603687efec 403 }
zackc 0:86603687efec 404
zackc 0:86603687efec 405 bool usbdevice::requestSetInterface(void)
zackc 0:86603687efec 406 {
zackc 0:86603687efec 407 /* TODO: We currently do not support alternate settings, return false */
zackc 0:86603687efec 408 return false;
zackc 0:86603687efec 409 }
zackc 0:86603687efec 410
zackc 0:86603687efec 411 bool usbdevice::requestSetFeature()
zackc 0:86603687efec 412 {
zackc 0:86603687efec 413 bool success = false;
zackc 0:86603687efec 414
zackc 0:86603687efec 415 if (device.state != CONFIGURED)
zackc 0:86603687efec 416 {
zackc 0:86603687efec 417 /* Endpoint or interface must be zero */
zackc 0:86603687efec 418 if (transfer.setup.wIndex != 0)
zackc 0:86603687efec 419 {
zackc 0:86603687efec 420 return false;
zackc 0:86603687efec 421 }
zackc 0:86603687efec 422 }
zackc 0:86603687efec 423
zackc 0:86603687efec 424 switch (transfer.setup.bmRequestType.Recipient)
zackc 0:86603687efec 425 {
zackc 0:86603687efec 426 case DEVICE_RECIPIENT:
zackc 0:86603687efec 427 /* TODO: Remote wakeup feature not supported */
zackc 0:86603687efec 428 break;
zackc 0:86603687efec 429 case ENDPOINT_RECIPIENT:
zackc 0:86603687efec 430 if (transfer.setup.wValue == ENDPOINT_HALT)
zackc 0:86603687efec 431 {
zackc 0:86603687efec 432 /* TODO: We should check that the endpoint number is valid */
zackc 0:86603687efec 433 stallEndpoint(WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
zackc 0:86603687efec 434 success = true;
zackc 0:86603687efec 435 }
zackc 0:86603687efec 436 break;
zackc 0:86603687efec 437 default:
zackc 0:86603687efec 438 break;
zackc 0:86603687efec 439 }
zackc 0:86603687efec 440
zackc 0:86603687efec 441 return success;
zackc 0:86603687efec 442 }
zackc 0:86603687efec 443
zackc 0:86603687efec 444 bool usbdevice::requestClearFeature()
zackc 0:86603687efec 445 {
zackc 0:86603687efec 446 bool success = false;
zackc 0:86603687efec 447
zackc 0:86603687efec 448 if (device.state != CONFIGURED)
zackc 0:86603687efec 449 {
zackc 0:86603687efec 450 /* Endpoint or interface must be zero */
zackc 0:86603687efec 451 if (transfer.setup.wIndex != 0)
zackc 0:86603687efec 452 {
zackc 0:86603687efec 453 return false;
zackc 0:86603687efec 454 }
zackc 0:86603687efec 455 }
zackc 0:86603687efec 456
zackc 0:86603687efec 457 switch (transfer.setup.bmRequestType.Recipient)
zackc 0:86603687efec 458 {
zackc 0:86603687efec 459 case DEVICE_RECIPIENT:
zackc 0:86603687efec 460 /* TODO: Remote wakeup feature not supported */
zackc 0:86603687efec 461 break;
zackc 0:86603687efec 462 case ENDPOINT_RECIPIENT:
zackc 0:86603687efec 463 /* TODO: We should check that the endpoint number is valid */
zackc 0:86603687efec 464 if (transfer.setup.wValue == ENDPOINT_HALT)
zackc 0:86603687efec 465 {
zackc 0:86603687efec 466 unstallEndpoint(WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
zackc 0:86603687efec 467 success = true;
zackc 0:86603687efec 468 }
zackc 0:86603687efec 469 break;
zackc 0:86603687efec 470 default:
zackc 0:86603687efec 471 break;
zackc 0:86603687efec 472 }
zackc 0:86603687efec 473
zackc 0:86603687efec 474 return success;
zackc 0:86603687efec 475 }
zackc 0:86603687efec 476
zackc 0:86603687efec 477 bool usbdevice::requestGetStatus(void)
zackc 0:86603687efec 478 {
zackc 0:86603687efec 479 static unsigned short status;
zackc 0:86603687efec 480 bool success = false;
zackc 0:86603687efec 481
zackc 0:86603687efec 482 if (device.state != CONFIGURED)
zackc 0:86603687efec 483 {
zackc 0:86603687efec 484 /* Endpoint or interface must be zero */
zackc 0:86603687efec 485 if (transfer.setup.wIndex != 0)
zackc 0:86603687efec 486 {
zackc 0:86603687efec 487 return false;
zackc 0:86603687efec 488 }
zackc 0:86603687efec 489 }
zackc 0:86603687efec 490
zackc 0:86603687efec 491 switch (transfer.setup.bmRequestType.Recipient)
zackc 0:86603687efec 492 {
zackc 0:86603687efec 493 case DEVICE_RECIPIENT:
zackc 0:86603687efec 494 /* TODO: Currently only supports self powered devices */
zackc 0:86603687efec 495 status = DEVICE_STATUS_SELF_POWERED;
zackc 0:86603687efec 496 success = true;
zackc 0:86603687efec 497 break;
zackc 0:86603687efec 498 case INTERFACE_RECIPIENT:
zackc 0:86603687efec 499 status = 0;
zackc 0:86603687efec 500 success = true;
zackc 0:86603687efec 501 break;
zackc 0:86603687efec 502 case ENDPOINT_RECIPIENT:
zackc 0:86603687efec 503 /* TODO: We should check that the endpoint number is valid */
zackc 0:86603687efec 504 if (getEndpointStallState(WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
zackc 0:86603687efec 505 {
zackc 0:86603687efec 506 status = ENDPOINT_STATUS_HALT;
zackc 0:86603687efec 507 }
zackc 0:86603687efec 508 else
zackc 0:86603687efec 509 {
zackc 0:86603687efec 510 status = 0;
zackc 0:86603687efec 511 }
zackc 0:86603687efec 512 success = true;
zackc 0:86603687efec 513 break;
zackc 0:86603687efec 514 default:
zackc 0:86603687efec 515 break;
zackc 0:86603687efec 516 }
zackc 0:86603687efec 517
zackc 0:86603687efec 518 if (success)
zackc 0:86603687efec 519 {
zackc 0:86603687efec 520 /* Send the status */
zackc 0:86603687efec 521 transfer.ptr = (unsigned char *)&status; /* Assumes little endian */
zackc 0:86603687efec 522 transfer.remaining = sizeof(status);
zackc 0:86603687efec 523 transfer.direction = DEVICE_TO_HOST;
zackc 0:86603687efec 524 }
zackc 0:86603687efec 525
zackc 0:86603687efec 526 return success;
zackc 0:86603687efec 527 }
zackc 0:86603687efec 528
zackc 0:86603687efec 529 bool usbdevice::requestGetDescriptor(void)
zackc 0:86603687efec 530 {
zackc 0:86603687efec 531 return false;
zackc 0:86603687efec 532 }