RAMDisk example for the USBFileSystem

Dependencies:   mbed USBFileSystem

Fork of USBFileSystem_RAMDISK_HelloWorld by Erik -

Committer:
Sissors
Date:
Tue Jul 30 18:27:18 2013 +0000
Revision:
1:e1b0157ce547
Memory leaks -_-

Who changed what in which revision?

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