This program allows to transform analog signal from rotary dial phone to numeric keys.

Dependencies:   mbed

Committer:
amigainc
Date:
Sun Aug 07 09:10:18 2011 +0000
Revision:
0:2c8568cec97f

        

Who changed what in which revision?

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