Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBDevice.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 00021 #include "USBEndpoints.h" 00022 #include "USBDevice.h" 00023 #include "USBDescriptor.h" 00024 00025 //#define DEBUG 00026 00027 /* Device status */ 00028 #define DEVICE_STATUS_SELF_POWERED (1U<<0) 00029 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1) 00030 00031 /* Endpoint status */ 00032 #define ENDPOINT_STATUS_HALT (1U<<0) 00033 00034 /* Standard feature selectors */ 00035 #define DEVICE_REMOTE_WAKEUP (1) 00036 #define ENDPOINT_HALT (0) 00037 00038 /* Macro to convert wIndex endpoint number to physical endpoint number */ 00039 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \ 00040 ((endpoint & 0x80) ? 1 : 0)) 00041 00042 00043 bool USBDevice::requestGetDescriptor(void) 00044 { 00045 bool success = false; 00046 #ifdef DEBUG 00047 printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue)); 00048 #endif 00049 switch (DESCRIPTOR_TYPE(transfer.setup.wValue)) 00050 { 00051 case DEVICE_DESCRIPTOR: 00052 if (deviceDesc() != NULL) 00053 { 00054 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \ 00055 && (deviceDesc()[1] == DEVICE_DESCRIPTOR)) 00056 { 00057 #ifdef DEBUG 00058 printf("device descr\r\n"); 00059 #endif 00060 transfer.remaining = DEVICE_DESCRIPTOR_LENGTH; 00061 transfer.ptr = (uint8_t*)deviceDesc(); 00062 transfer.direction = DEVICE_TO_HOST; 00063 success = true; 00064 } 00065 } 00066 break; 00067 case CONFIGURATION_DESCRIPTOR: 00068 if (configurationDesc() != NULL) 00069 { 00070 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \ 00071 && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR)) 00072 { 00073 #ifdef DEBUG 00074 printf("conf descr request\r\n"); 00075 #endif 00076 /* Get wTotalLength */ 00077 transfer.remaining = configurationDesc()[2] \ 00078 | (configurationDesc()[3] << 8); 00079 00080 transfer.ptr = (uint8_t*)configurationDesc(); 00081 transfer.direction = DEVICE_TO_HOST; 00082 success = true; 00083 } 00084 } 00085 break; 00086 case STRING_DESCRIPTOR: 00087 #ifdef DEBUG 00088 printf("str descriptor\r\n"); 00089 #endif 00090 switch (DESCRIPTOR_INDEX(transfer.setup.wValue)) 00091 { 00092 case STRING_OFFSET_LANGID: 00093 #ifdef DEBUG 00094 printf("1\r\n"); 00095 #endif 00096 transfer.remaining = stringLangidDesc()[0]; 00097 transfer.ptr = (uint8_t*)stringLangidDesc(); 00098 transfer.direction = DEVICE_TO_HOST; 00099 success = true; 00100 break; 00101 case STRING_OFFSET_IMANUFACTURER: 00102 #ifdef DEBUG 00103 printf("2\r\n"); 00104 #endif 00105 transfer.remaining = stringImanufacturerDesc()[0]; 00106 transfer.ptr = (uint8_t*)stringImanufacturerDesc(); 00107 transfer.direction = DEVICE_TO_HOST; 00108 success = true; 00109 break; 00110 case STRING_OFFSET_IPRODUCT: 00111 #ifdef DEBUG 00112 printf("3\r\n"); 00113 #endif 00114 transfer.remaining = stringIproductDesc()[0]; 00115 transfer.ptr = (uint8_t*)stringIproductDesc(); 00116 transfer.direction = DEVICE_TO_HOST; 00117 success = true; 00118 break; 00119 case STRING_OFFSET_ISERIAL: 00120 #ifdef DEBUG 00121 printf("4\r\n"); 00122 #endif 00123 transfer.remaining = stringIserialDesc()[0]; 00124 transfer.ptr = (uint8_t*)stringIserialDesc(); 00125 transfer.direction = DEVICE_TO_HOST; 00126 success = true; 00127 break; 00128 case STRING_OFFSET_ICONFIGURATION: 00129 #ifdef DEBUG 00130 printf("5\r\n"); 00131 #endif 00132 transfer.remaining = stringIConfigurationDesc()[0]; 00133 transfer.ptr = (uint8_t*)stringIConfigurationDesc(); 00134 transfer.direction = DEVICE_TO_HOST; 00135 success = true; 00136 break; 00137 case STRING_OFFSET_IINTERFACE: 00138 #ifdef DEBUG 00139 printf("6\r\n"); 00140 #endif 00141 transfer.remaining = stringIinterfaceDesc()[0]; 00142 transfer.ptr = (uint8_t*)stringIinterfaceDesc(); 00143 transfer.direction = DEVICE_TO_HOST; 00144 success = true; 00145 break; 00146 } 00147 break; 00148 case INTERFACE_DESCRIPTOR: 00149 #ifdef DEBUG 00150 printf("interface descr\r\n"); 00151 #endif 00152 case ENDPOINT_DESCRIPTOR: 00153 #ifdef DEBUG 00154 printf("endpoint descr\r\n"); 00155 #endif 00156 /* TODO: Support is optional, not implemented here */ 00157 break; 00158 default: 00159 #ifdef DEBUG 00160 printf("ERROR\r\n"); 00161 #endif 00162 break; 00163 } 00164 00165 return success; 00166 } 00167 00168 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet) 00169 { 00170 /* Fill in the elements of a SETUP_PACKET structure from raw data */ 00171 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7; 00172 packet->bmRequestType.Type = (data[0] & 0x60) >> 5; 00173 packet->bmRequestType.Recipient = data[0] & 0x1f; 00174 packet->bRequest = data[1]; 00175 packet->wValue = (data[2] | (uint16_t)data[3] << 8); 00176 packet->wIndex = (data[4] | (uint16_t)data[5] << 8); 00177 packet->wLength = (data[6] | (uint16_t)data[7] << 8); 00178 } 00179 00180 00181 bool USBDevice::controlOut(void) 00182 { 00183 /* Control transfer data OUT stage */ 00184 uint8_t buffer[MAX_PACKET_SIZE_EP0]; 00185 uint32_t packetSize; 00186 00187 /* Check we should be transferring data OUT */ 00188 if (transfer.direction != HOST_TO_DEVICE) 00189 { 00190 /* for other platforms, count on the HAL to handle this case */ 00191 return false; 00192 } 00193 00194 /* Read from endpoint */ 00195 packetSize = EP0getReadResult(buffer); 00196 00197 /* Check if transfer size is valid */ 00198 if (packetSize > transfer.remaining) 00199 { 00200 /* Too big */ 00201 return false; 00202 } 00203 00204 /* Update transfer */ 00205 transfer.ptr += packetSize; 00206 transfer.remaining -= packetSize; 00207 00208 /* Check if transfer has completed */ 00209 if (transfer.remaining == 0) 00210 { 00211 /* Transfer completed */ 00212 if (transfer.notify) 00213 { 00214 /* Notify class layer. */ 00215 USBCallback_requestCompleted(buffer, packetSize); 00216 transfer.notify = false; 00217 } 00218 /* Status stage */ 00219 EP0write(NULL, 0); 00220 } 00221 else 00222 { 00223 EP0read(); 00224 } 00225 00226 return true; 00227 } 00228 00229 bool USBDevice::controlIn(void) 00230 { 00231 /* Control transfer data IN stage */ 00232 uint32_t packetSize; 00233 00234 /* Check if transfer has completed (status stage transactions */ 00235 /* also have transfer.remaining == 0) */ 00236 if (transfer.remaining == 0) 00237 { 00238 if (transfer.zlp) 00239 { 00240 /* Send zero length packet */ 00241 EP0write(NULL, 0); 00242 transfer.zlp = false; 00243 } 00244 00245 /* Transfer completed */ 00246 if (transfer.notify) 00247 { 00248 /* Notify class layer. */ 00249 USBCallback_requestCompleted(NULL, 0); 00250 transfer.notify = false; 00251 } 00252 00253 EP0read(); 00254 EP0readStage(); 00255 00256 /* Completed */ 00257 return true; 00258 } 00259 00260 /* Check we should be transferring data IN */ 00261 if (transfer.direction != DEVICE_TO_HOST) 00262 { 00263 return false; 00264 } 00265 00266 packetSize = transfer.remaining; 00267 00268 if (packetSize > MAX_PACKET_SIZE_EP0) 00269 { 00270 packetSize = MAX_PACKET_SIZE_EP0; 00271 } 00272 00273 /* Write to endpoint */ 00274 EP0write(transfer.ptr, packetSize); 00275 00276 /* Update transfer */ 00277 transfer.ptr += packetSize; 00278 transfer.remaining -= packetSize; 00279 00280 return true; 00281 } 00282 00283 bool USBDevice::requestSetAddress(void) 00284 { 00285 /* Set the device address */ 00286 setAddress(transfer.setup.wValue); 00287 00288 if (transfer.setup.wValue == 0) 00289 { 00290 device.state = DEFAULT; 00291 } 00292 else 00293 { 00294 device.state = ADDRESS; 00295 } 00296 00297 return true; 00298 } 00299 00300 bool USBDevice::requestSetConfiguration(void) 00301 { 00302 00303 device.configuration = transfer.setup.wValue; 00304 /* Set the device configuration */ 00305 if (device.configuration == 0) 00306 { 00307 /* Not configured */ 00308 unconfigureDevice(); 00309 device.state = ADDRESS; 00310 } 00311 else 00312 { 00313 if (USBCallback_setConfiguration(device.configuration)) 00314 { 00315 /* Valid configuration */ 00316 configureDevice(); 00317 device.state = CONFIGURED; 00318 } 00319 else 00320 { 00321 return false; 00322 } 00323 } 00324 00325 return true; 00326 } 00327 00328 bool USBDevice::requestGetConfiguration(void) 00329 { 00330 /* Send the device configuration */ 00331 transfer.ptr = &device.configuration; 00332 transfer.remaining = sizeof(device.configuration); 00333 transfer.direction = DEVICE_TO_HOST; 00334 return true; 00335 } 00336 00337 bool USBDevice::requestGetInterface(void) 00338 { 00339 /* Return the selected alternate setting for an interface */ 00340 00341 if (device.state != CONFIGURED) 00342 { 00343 return false; 00344 } 00345 00346 /* Send the alternate setting */ 00347 transfer.setup.wIndex = currentInterface; 00348 transfer.ptr = ¤tAlternate; 00349 transfer.remaining = sizeof(currentAlternate); 00350 transfer.direction = DEVICE_TO_HOST; 00351 return true; 00352 } 00353 00354 bool USBDevice::requestSetInterface(void) 00355 { 00356 bool success = false; 00357 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue)) 00358 { 00359 success = true; 00360 currentInterface = transfer.setup.wIndex; 00361 currentAlternate = transfer.setup.wValue; 00362 } 00363 return success; 00364 } 00365 00366 bool USBDevice::requestSetFeature() 00367 { 00368 bool success = false; 00369 00370 if (device.state != CONFIGURED) 00371 { 00372 /* Endpoint or interface must be zero */ 00373 if (transfer.setup.wIndex != 0) 00374 { 00375 return false; 00376 } 00377 } 00378 00379 switch (transfer.setup.bmRequestType.Recipient) 00380 { 00381 case DEVICE_RECIPIENT: 00382 /* TODO: Remote wakeup feature not supported */ 00383 break; 00384 case ENDPOINT_RECIPIENT: 00385 if (transfer.setup.wValue == ENDPOINT_HALT) 00386 { 00387 /* TODO: We should check that the endpoint number is valid */ 00388 stallEndpoint( 00389 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)); 00390 success = true; 00391 } 00392 break; 00393 default: 00394 break; 00395 } 00396 00397 return success; 00398 } 00399 00400 bool USBDevice::requestClearFeature() 00401 { 00402 bool success = false; 00403 00404 if (device.state != CONFIGURED) 00405 { 00406 /* Endpoint or interface must be zero */ 00407 if (transfer.setup.wIndex != 0) 00408 { 00409 return false; 00410 } 00411 } 00412 00413 switch (transfer.setup.bmRequestType.Recipient) 00414 { 00415 case DEVICE_RECIPIENT: 00416 /* TODO: Remote wakeup feature not supported */ 00417 break; 00418 case ENDPOINT_RECIPIENT: 00419 /* TODO: We should check that the endpoint number is valid */ 00420 if (transfer.setup.wValue == ENDPOINT_HALT) 00421 { 00422 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex)); 00423 success = true; 00424 } 00425 break; 00426 default: 00427 break; 00428 } 00429 00430 return success; 00431 } 00432 00433 bool USBDevice::requestGetStatus(void) 00434 { 00435 static uint16_t status; 00436 bool success = false; 00437 00438 if (device.state != CONFIGURED) 00439 { 00440 /* Endpoint or interface must be zero */ 00441 if (transfer.setup.wIndex != 0) 00442 { 00443 return false; 00444 } 00445 } 00446 00447 switch (transfer.setup.bmRequestType.Recipient) 00448 { 00449 case DEVICE_RECIPIENT: 00450 /* TODO: Currently only supports self powered devices */ 00451 status = DEVICE_STATUS_SELF_POWERED; 00452 success = true; 00453 break; 00454 case INTERFACE_RECIPIENT: 00455 status = 0; 00456 success = true; 00457 break; 00458 case ENDPOINT_RECIPIENT: 00459 /* TODO: We should check that the endpoint number is valid */ 00460 if (getEndpointStallState( 00461 WINDEX_TO_PHYSICAL(transfer.setup.wIndex))) 00462 { 00463 status = ENDPOINT_STATUS_HALT; 00464 } 00465 else 00466 { 00467 status = 0; 00468 } 00469 success = true; 00470 break; 00471 default: 00472 break; 00473 } 00474 00475 if (success) 00476 { 00477 /* Send the status */ 00478 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */ 00479 transfer.remaining = sizeof(status); 00480 transfer.direction = DEVICE_TO_HOST; 00481 } 00482 00483 return success; 00484 } 00485 00486 bool USBDevice::requestSetup(void) 00487 { 00488 bool success = false; 00489 00490 /* Process standard requests */ 00491 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE)) 00492 { 00493 switch (transfer.setup.bRequest) 00494 { 00495 case GET_STATUS: 00496 success = requestGetStatus(); 00497 break; 00498 case CLEAR_FEATURE: 00499 success = requestClearFeature(); 00500 break; 00501 case SET_FEATURE: 00502 success = requestSetFeature(); 00503 break; 00504 case SET_ADDRESS: 00505 success = requestSetAddress(); 00506 break; 00507 case GET_DESCRIPTOR: 00508 success = requestGetDescriptor(); 00509 break; 00510 case SET_DESCRIPTOR: 00511 /* TODO: Support is optional, not implemented here */ 00512 success = false; 00513 break; 00514 case GET_CONFIGURATION: 00515 success = requestGetConfiguration(); 00516 break; 00517 case SET_CONFIGURATION: 00518 success = requestSetConfiguration(); 00519 break; 00520 case GET_INTERFACE: 00521 success = requestGetInterface(); 00522 break; 00523 case SET_INTERFACE: 00524 success = requestSetInterface(); 00525 break; 00526 default: 00527 break; 00528 } 00529 } 00530 00531 return success; 00532 } 00533 00534 bool USBDevice::controlSetup(void) 00535 { 00536 bool success = false; 00537 00538 /* Control transfer setup stage */ 00539 uint8_t buffer[MAX_PACKET_SIZE_EP0]; 00540 00541 EP0setup(buffer); 00542 00543 /* Initialise control transfer state */ 00544 decodeSetupPacket(buffer, &transfer.setup); 00545 transfer.ptr = NULL; 00546 transfer.remaining = 0; 00547 transfer.direction = 0; 00548 transfer.zlp = false; 00549 transfer.notify = false; 00550 00551 #ifdef DEBUG 00552 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, 00553 transfer.setup.bmRequestType.Type, 00554 transfer.setup.bmRequestType.Recipient, 00555 transfer.setup.bRequest, 00556 transfer.setup.wValue, 00557 transfer.setup.wIndex, 00558 transfer.setup.wLength); 00559 #endif 00560 00561 /* Class / vendor specific */ 00562 success = USBCallback_request(); 00563 00564 if (!success) 00565 { 00566 /* Standard requests */ 00567 if (!requestSetup()) 00568 { 00569 #ifdef DEBUG 00570 printf("fail!!!!\r\n"); 00571 #endif 00572 return false; 00573 } 00574 } 00575 00576 /* Check transfer size and direction */ 00577 if (transfer.setup.wLength>0) 00578 { 00579 if (transfer.setup.bmRequestType.dataTransferDirection \ 00580 == DEVICE_TO_HOST) 00581 { 00582 /* IN data stage is required */ 00583 if (transfer.direction != DEVICE_TO_HOST) 00584 { 00585 return false; 00586 } 00587 00588 /* Transfer must be less than or equal to the size */ 00589 /* requested by the host */ 00590 if (transfer.remaining > transfer.setup.wLength) 00591 { 00592 transfer.remaining = transfer.setup.wLength; 00593 } 00594 } 00595 else 00596 { 00597 00598 /* OUT data stage is required */ 00599 if (transfer.direction != HOST_TO_DEVICE) 00600 { 00601 return false; 00602 } 00603 00604 /* Transfer must be equal to the size requested by the host */ 00605 if (transfer.remaining != transfer.setup.wLength) 00606 { 00607 return false; 00608 } 00609 } 00610 } 00611 else 00612 { 00613 /* No data stage; transfer size must be zero */ 00614 if (transfer.remaining != 0) 00615 { 00616 return false; 00617 } 00618 } 00619 00620 /* Data or status stage if applicable */ 00621 if (transfer.setup.wLength>0) 00622 { 00623 if (transfer.setup.bmRequestType.dataTransferDirection \ 00624 == DEVICE_TO_HOST) 00625 { 00626 /* Check if we'll need to send a zero length packet at */ 00627 /* the end of this transfer */ 00628 if (transfer.setup.wLength > transfer.remaining) 00629 { 00630 /* Device wishes to transfer less than host requested */ 00631 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0) 00632 { 00633 /* Transfer is a multiple of EP0 max packet size */ 00634 transfer.zlp = true; 00635 } 00636 } 00637 00638 /* IN stage */ 00639 controlIn(); 00640 } 00641 else 00642 { 00643 /* OUT stage */ 00644 EP0read(); 00645 } 00646 } 00647 else 00648 { 00649 /* Status stage */ 00650 EP0write(NULL, 0); 00651 } 00652 00653 return true; 00654 } 00655 00656 void USBDevice::busReset(void) 00657 { 00658 device.state = DEFAULT; 00659 device.configuration = 0; 00660 device.suspended = false; 00661 00662 /* Call class / vendor specific busReset function */ 00663 USBCallback_busReset(); 00664 } 00665 00666 void USBDevice::EP0setupCallback(void) 00667 { 00668 /* Endpoint 0 setup event */ 00669 if (!controlSetup()) 00670 { 00671 /* Protocol stall */ 00672 EP0stall(); 00673 } 00674 00675 /* Return true if an OUT data stage is expected */ 00676 } 00677 00678 void USBDevice::EP0out(void) 00679 { 00680 /* Endpoint 0 OUT data event */ 00681 if (!controlOut()) 00682 { 00683 /* Protocol stall; this will stall both endpoints */ 00684 EP0stall(); 00685 } 00686 } 00687 00688 void USBDevice::EP0in(void) 00689 { 00690 #ifdef DEBUG 00691 printf("EP0IN\r\n"); 00692 #endif 00693 /* Endpoint 0 IN data event */ 00694 if (!controlIn()) 00695 { 00696 /* Protocol stall; this will stall both endpoints */ 00697 EP0stall(); 00698 } 00699 } 00700 00701 bool USBDevice::configured(void) 00702 { 00703 /* Returns true if device is in the CONFIGURED state */ 00704 return (device.state == CONFIGURED); 00705 } 00706 00707 void USBDevice::connect(bool blocking) 00708 { 00709 /* Connect device */ 00710 USBHAL::connect(); 00711 00712 if (blocking) { 00713 /* Block if not configured */ 00714 while (!configured()); 00715 } 00716 } 00717 00718 void USBDevice::disconnect(void) 00719 { 00720 /* Disconnect device */ 00721 USBHAL::disconnect(); 00722 00723 /* Set initial device state */ 00724 device.state = POWERED; 00725 device.configuration = 0; 00726 device.suspended = false; 00727 } 00728 00729 CONTROL_TRANSFER * USBDevice::getTransferPtr(void) 00730 { 00731 return &transfer; 00732 } 00733 00734 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket) 00735 { 00736 return realiseEndpoint(endpoint, maxPacket, 0); 00737 } 00738 00739 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket) 00740 { 00741 /* For interrupt endpoints only */ 00742 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE); 00743 } 00744 00745 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType) 00746 { 00747 /* Find a descriptor within the list of descriptors */ 00748 /* following a configuration descriptor. */ 00749 uint16_t wTotalLength; 00750 uint8_t *ptr; 00751 00752 if (configurationDesc() == NULL) 00753 { 00754 return NULL; 00755 } 00756 00757 /* Check this is a configuration descriptor */ 00758 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \ 00759 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR)) 00760 { 00761 return NULL; 00762 } 00763 00764 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8); 00765 00766 /* Check there are some more descriptors to follow */ 00767 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2)) 00768 /* +2 is for bLength and bDescriptorType of next descriptor */ 00769 { 00770 return NULL; 00771 } 00772 00773 /* Start at first descriptor after the configuration descriptor */ 00774 ptr = &(((uint8_t*)configurationDesc())[CONFIGURATION_DESCRIPTOR_LENGTH]); 00775 00776 do { 00777 if (ptr[1] /* bDescriptorType */ == descriptorType) 00778 { 00779 /* Found */ 00780 return ptr; 00781 } 00782 00783 /* Skip to next descriptor */ 00784 ptr += ptr[0]; /* bLength */ 00785 } while (ptr < (configurationDesc() + wTotalLength)); 00786 00787 /* Reached end of the descriptors - not found */ 00788 return NULL; 00789 } 00790 00791 00792 void USBDevice::connectStateChanged(unsigned int connected) 00793 { 00794 } 00795 00796 void USBDevice::suspendStateChanged(unsigned int suspended) 00797 { 00798 } 00799 00800 00801 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){ 00802 VENDOR_ID = vendor_id; 00803 PRODUCT_ID = product_id; 00804 PRODUCT_RELEASE = product_release; 00805 00806 /* Set initial device state */ 00807 device.state = POWERED; 00808 device.configuration = 0; 00809 device.suspended = false; 00810 }; 00811 00812 00813 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize) 00814 { 00815 return endpointRead(endpoint, maxSize) == EP_PENDING; 00816 } 00817 00818 00819 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00820 { 00821 EP_STATUS result; 00822 00823 if (size > maxSize) 00824 { 00825 return false; 00826 } 00827 00828 00829 if(!configured()) { 00830 return false; 00831 } 00832 00833 /* Send report */ 00834 result = endpointWrite(endpoint, buffer, size); 00835 00836 if (result != EP_PENDING) 00837 { 00838 return false; 00839 } 00840 00841 /* Wait for completion */ 00842 do { 00843 result = endpointWriteResult(endpoint); 00844 } while ((result == EP_PENDING) && configured()); 00845 00846 return (result == EP_COMPLETED); 00847 } 00848 00849 00850 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00851 { 00852 EP_STATUS result; 00853 00854 if (size > maxSize) 00855 { 00856 return false; 00857 } 00858 00859 if(!configured()) { 00860 return false; 00861 } 00862 00863 /* Send report */ 00864 result = endpointWrite(endpoint, buffer, size); 00865 00866 if (result != EP_PENDING) 00867 { 00868 return false; 00869 } 00870 00871 result = endpointWriteResult(endpoint); 00872 00873 return (result == EP_COMPLETED); 00874 } 00875 00876 00877 00878 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00879 { 00880 EP_STATUS result; 00881 00882 if(!configured()) { 00883 return false; 00884 } 00885 00886 /* Wait for completion */ 00887 do { 00888 result = endpointReadResult(endpoint, buffer, size); 00889 } while ((result == EP_PENDING) && configured()); 00890 00891 return (result == EP_COMPLETED); 00892 } 00893 00894 00895 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00896 { 00897 EP_STATUS result; 00898 00899 if(!configured()) { 00900 return false; 00901 } 00902 00903 result = endpointReadResult(endpoint, buffer, size); 00904 00905 return (result == EP_COMPLETED); 00906 } 00907 00908 00909 00910 const uint8_t * USBDevice::deviceDesc() { 00911 uint8_t deviceDescriptorTemp[] = { 00912 DEVICE_DESCRIPTOR_LENGTH, /* bLength */ 00913 DEVICE_DESCRIPTOR, /* bDescriptorType */ 00914 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */ 00915 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */ 00916 0x00, /* bDeviceClass */ 00917 0x00, /* bDeviceSubClass */ 00918 0x00, /* bDeviceprotocol */ 00919 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */ 00920 (uint8_t)(LSB(VENDOR_ID)), /* idVendor (LSB) */ 00921 (uint8_t)(MSB(VENDOR_ID)), /* idVendor (MSB) */ 00922 (uint8_t)(LSB(PRODUCT_ID)), /* idProduct (LSB) */ 00923 (uint8_t)(MSB(PRODUCT_ID)), /* idProduct (MSB) */ 00924 (uint8_t)(LSB(PRODUCT_RELEASE)), /* bcdDevice (LSB) */ 00925 (uint8_t)(MSB(PRODUCT_RELEASE)), /* bcdDevice (MSB) */ 00926 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */ 00927 STRING_OFFSET_IPRODUCT, /* iProduct */ 00928 STRING_OFFSET_ISERIAL, /* iSerialNumber */ 00929 0x01 /* bNumConfigurations */ 00930 }; 00931 MBED_ASSERT(sizeof(deviceDescriptorTemp) == sizeof(deviceDescriptor)); 00932 memcpy(deviceDescriptor, deviceDescriptorTemp, sizeof(deviceDescriptor)); 00933 return deviceDescriptor; 00934 } 00935 00936 const uint8_t * USBDevice::stringLangidDesc() { 00937 static const uint8_t stringLangidDescriptor[] = { 00938 0x04, /*bLength*/ 00939 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00940 0x09,0x04, /*bString Lang ID - 0x0409 - English*/ 00941 }; 00942 return (uint8_t *)stringLangidDescriptor; 00943 } 00944 00945 const uint8_t * USBDevice::stringImanufacturerDesc() { 00946 static const uint8_t stringImanufacturerDescriptor[] = { 00947 0x12, /*bLength*/ 00948 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00949 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/ 00950 }; 00951 return stringImanufacturerDescriptor; 00952 } 00953 00954 const uint8_t * USBDevice::stringIserialDesc() { 00955 static const uint8_t stringIserialDescriptor[] = { 00956 0x16, /*bLength*/ 00957 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00958 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/ 00959 }; 00960 return stringIserialDescriptor; 00961 } 00962 00963 const uint8_t * USBDevice::stringIConfigurationDesc() { 00964 static const uint8_t stringIconfigurationDescriptor[] = { 00965 0x06, /*bLength*/ 00966 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00967 '0',0,'1',0, /*bString iConfiguration - 01*/ 00968 }; 00969 return stringIconfigurationDescriptor; 00970 } 00971 00972 const uint8_t * USBDevice::stringIinterfaceDesc() { 00973 static const uint8_t stringIinterfaceDescriptor[] = { 00974 0x08, /*bLength*/ 00975 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00976 'U',0,'S',0,'B',0, /*bString iInterface - USB*/ 00977 }; 00978 return stringIinterfaceDescriptor; 00979 } 00980 00981 const uint8_t * USBDevice::stringIproductDesc() { 00982 static const uint8_t stringIproductDescriptor[] = { 00983 0x16, /*bLength*/ 00984 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00985 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/ 00986 }; 00987 return stringIproductDescriptor; 00988 }
Generated on Tue Jul 12 2022 14:25:13 by
