mX mbed BaseBoard USB HID

Dependencies:   mbed

Committer:
ashwin_athani
Date:
Wed Dec 08 06:30:25 2010 +0000
Revision:
0:093612081f64

        

Who changed what in which revision?

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