Transistor Gijutsu, October 2014, Special Features Chapter 8,Software of the thermistor thermometer of 0.001 ° resolution, トランジスタ技術2014年10月号 特集第8章のソフトウェア 0.001℃分解能で気配もキャッチ「超敏感肌温度計」

Dependencies:   USBDevice mbed

Information

tg_201410s8_AD7714 トランジスタ技術 2014年 10月号 第8章のソフトウェア

Program for Section 8 in October. 2014 issue of the Transistor Gijutsu
(Japanese electronics magazine)

概要

このプログラムは、サーミスタの抵抗値変化をAD7714(24bitADC)で測定し、抵抗値を温度値に変換することで、0.001℃程度の分解能で温度変化を測定します。

ファイル

このソフトウエアは、次のファイルから構成されています。

  • AD7714.cpp - AD7714の内部レジスタを設定
  • Thermistor.cpp - サーミスタの抵抗値から温度値に変換
  • ExpAvr.cpp - 指数平均によるソフトウエアLPF
  • main.cpp - main()関数

詳細については、10月号の記事および上記ファイル中のコメントを参照してください。

Committer:
Dance
Date:
Fri Aug 29 08:38:36 2014 +0000
Revision:
0:de885a6da962
Transistor Gijutsu, October 2014, Special Features Chapter 8; ????????2014?10??????8????????

Who changed what in which revision?

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