test

Dependencies:   BMI160 max32630hsp3 MemoryLCD USBDevice

Committer:
seyhmus.cacina
Date:
Mon Mar 18 10:21:53 2019 +0300
Revision:
0:ac4dea3e2894
ME11B Sample Code First Commit

Who changed what in which revision?

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