USB device stack

Fork of USBDevice by mbed official

Committer:
nikitamere
Date:
Fri Sep 16 01:03:54 2016 +0000
Revision:
66:b6940e641a15
Modified

Who changed what in which revision?

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