blablabla

Dependencies:   MAG3110 MMA8451Q SLCD- TSI USBDevice mbed

Committer:
Osator
Date:
Wed Apr 16 12:20:00 2014 +0000
Revision:
0:339b7abfa147
blablabla

Who changed what in which revision?

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