xd

Dependencies:   mbed

Fork of Simple_Touch_Sens by Veikko Kero

Committer:
Vekotin
Date:
Thu Jan 30 06:13:55 2014 +0000
Revision:
1:7ed7d128d225
egw

Who changed what in which revision?

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