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.
Fork of USBDevice by
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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 return false; 00191 } 00192 00193 /* Read from endpoint */ 00194 packetSize = EP0getReadResult(buffer); 00195 00196 /* Check if transfer size is valid */ 00197 if (packetSize > transfer.remaining) 00198 { 00199 /* Too big */ 00200 return false; 00201 } 00202 00203 /* Update transfer */ 00204 transfer.ptr += packetSize; 00205 transfer.remaining -= packetSize; 00206 00207 /* Check if transfer has completed */ 00208 if (transfer.remaining == 0) 00209 { 00210 /* Transfer completed */ 00211 if (transfer.notify) 00212 { 00213 /* Notify class layer. */ 00214 USBCallback_requestCompleted(buffer, packetSize); 00215 transfer.notify = false; 00216 } 00217 /* Status stage */ 00218 EP0write(NULL, 0); 00219 } 00220 else 00221 { 00222 EP0read(); 00223 } 00224 00225 return true; 00226 } 00227 00228 bool USBDevice::controlIn(void) 00229 { 00230 /* Control transfer data IN stage */ 00231 uint32_t packetSize; 00232 00233 /* Check if transfer has completed (status stage transactions */ 00234 /* also have transfer.remaining == 0) */ 00235 if (transfer.remaining == 0) 00236 { 00237 if (transfer.zlp) 00238 { 00239 /* Send zero length packet */ 00240 EP0write(NULL, 0); 00241 transfer.zlp = false; 00242 } 00243 00244 /* Transfer completed */ 00245 if (transfer.notify) 00246 { 00247 /* Notify class layer. */ 00248 USBCallback_requestCompleted(NULL, 0); 00249 transfer.notify = false; 00250 } 00251 00252 EP0read(); 00253 00254 /* Completed */ 00255 return true; 00256 } 00257 00258 /* Check we should be transferring data IN */ 00259 if (transfer.direction != DEVICE_TO_HOST) 00260 { 00261 return false; 00262 } 00263 00264 packetSize = transfer.remaining; 00265 00266 if (packetSize > MAX_PACKET_SIZE_EP0) 00267 { 00268 packetSize = MAX_PACKET_SIZE_EP0; 00269 } 00270 00271 /* Write to endpoint */ 00272 EP0write(transfer.ptr, packetSize); 00273 00274 /* Update transfer */ 00275 transfer.ptr += packetSize; 00276 transfer.remaining -= packetSize; 00277 00278 return true; 00279 } 00280 00281 bool USBDevice::requestSetAddress(void) 00282 { 00283 /* Set the device address */ 00284 setAddress(transfer.setup.wValue); 00285 00286 if (transfer.setup.wValue == 0) 00287 { 00288 device.state = DEFAULT; 00289 } 00290 else 00291 { 00292 device.state = ADDRESS; 00293 } 00294 00295 return true; 00296 } 00297 00298 bool USBDevice::requestSetConfiguration(void) 00299 { 00300 00301 device.configuration = transfer.setup.wValue; 00302 /* Set the device configuration */ 00303 if (device.configuration == 0) 00304 { 00305 /* Not configured */ 00306 unconfigureDevice(); 00307 device.state = ADDRESS; 00308 } 00309 else 00310 { 00311 if (USBCallback_setConfiguration(device.configuration)) 00312 { 00313 /* Valid configuration */ 00314 configureDevice(); 00315 device.state = CONFIGURED; 00316 } 00317 else 00318 { 00319 return false; 00320 } 00321 } 00322 00323 return true; 00324 } 00325 00326 bool USBDevice::requestGetConfiguration(void) 00327 { 00328 /* Send the device configuration */ 00329 transfer.ptr = &device.configuration; 00330 transfer.remaining = sizeof(device.configuration); 00331 transfer.direction = DEVICE_TO_HOST; 00332 return true; 00333 } 00334 00335 bool USBDevice::requestGetInterface(void) 00336 { 00337 /* Return the selected alternate setting for an interface */ 00338 00339 if (device.state != CONFIGURED) 00340 { 00341 return false; 00342 } 00343 00344 /* Send the alternate setting */ 00345 transfer.setup.wIndex = currentInterface; 00346 transfer.ptr = ¤tAlternate; 00347 transfer.remaining = sizeof(currentAlternate); 00348 transfer.direction = DEVICE_TO_HOST; 00349 return true; 00350 } 00351 00352 bool USBDevice::requestSetInterface(void) 00353 { 00354 bool success = false; 00355 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue)) 00356 { 00357 success = true; 00358 currentInterface = transfer.setup.wIndex; 00359 currentAlternate = transfer.setup.wValue; 00360 } 00361 return success; 00362 } 00363 00364 bool USBDevice::requestSetFeature() 00365 { 00366 bool success = false; 00367 00368 if (device.state != CONFIGURED) 00369 { 00370 /* Endpoint or interface must be zero */ 00371 if (transfer.setup.wIndex != 0) 00372 { 00373 return false; 00374 } 00375 } 00376 00377 switch (transfer.setup.bmRequestType.Recipient) 00378 { 00379 case DEVICE_RECIPIENT: 00380 /* TODO: Remote wakeup feature not supported */ 00381 break; 00382 case ENDPOINT_RECIPIENT: 00383 if (transfer.setup.wValue == ENDPOINT_HALT) 00384 { 00385 /* TODO: We should check that the endpoint number is valid */ 00386 stallEndpoint( 00387 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)); 00388 success = true; 00389 } 00390 break; 00391 default: 00392 break; 00393 } 00394 00395 return success; 00396 } 00397 00398 bool USBDevice::requestClearFeature() 00399 { 00400 bool success = false; 00401 00402 if (device.state != CONFIGURED) 00403 { 00404 /* Endpoint or interface must be zero */ 00405 if (transfer.setup.wIndex != 0) 00406 { 00407 return false; 00408 } 00409 } 00410 00411 switch (transfer.setup.bmRequestType.Recipient) 00412 { 00413 case DEVICE_RECIPIENT: 00414 /* TODO: Remote wakeup feature not supported */ 00415 break; 00416 case ENDPOINT_RECIPIENT: 00417 /* TODO: We should check that the endpoint number is valid */ 00418 if (transfer.setup.wValue == ENDPOINT_HALT) 00419 { 00420 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex)); 00421 success = true; 00422 } 00423 break; 00424 default: 00425 break; 00426 } 00427 00428 return success; 00429 } 00430 00431 bool USBDevice::requestGetStatus(void) 00432 { 00433 static uint16_t status; 00434 bool success = false; 00435 00436 if (device.state != CONFIGURED) 00437 { 00438 /* Endpoint or interface must be zero */ 00439 if (transfer.setup.wIndex != 0) 00440 { 00441 return false; 00442 } 00443 } 00444 00445 switch (transfer.setup.bmRequestType.Recipient) 00446 { 00447 case DEVICE_RECIPIENT: 00448 /* TODO: Currently only supports self powered devices */ 00449 status = DEVICE_STATUS_SELF_POWERED; 00450 success = true; 00451 break; 00452 case INTERFACE_RECIPIENT: 00453 status = 0; 00454 success = true; 00455 break; 00456 case ENDPOINT_RECIPIENT: 00457 /* TODO: We should check that the endpoint number is valid */ 00458 if (getEndpointStallState( 00459 WINDEX_TO_PHYSICAL(transfer.setup.wIndex))) 00460 { 00461 status = ENDPOINT_STATUS_HALT; 00462 } 00463 else 00464 { 00465 status = 0; 00466 } 00467 success = true; 00468 break; 00469 default: 00470 break; 00471 } 00472 00473 if (success) 00474 { 00475 /* Send the status */ 00476 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */ 00477 transfer.remaining = sizeof(status); 00478 transfer.direction = DEVICE_TO_HOST; 00479 } 00480 00481 return success; 00482 } 00483 00484 bool USBDevice::requestSetup(void) 00485 { 00486 bool success = false; 00487 00488 /* Process standard requests */ 00489 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE)) 00490 { 00491 switch (transfer.setup.bRequest) 00492 { 00493 case GET_STATUS: 00494 success = requestGetStatus(); 00495 break; 00496 case CLEAR_FEATURE: 00497 success = requestClearFeature(); 00498 break; 00499 case SET_FEATURE: 00500 success = requestSetFeature(); 00501 break; 00502 case SET_ADDRESS: 00503 success = requestSetAddress(); 00504 break; 00505 case GET_DESCRIPTOR: 00506 success = requestGetDescriptor(); 00507 break; 00508 case SET_DESCRIPTOR: 00509 /* TODO: Support is optional, not implemented here */ 00510 success = false; 00511 break; 00512 case GET_CONFIGURATION: 00513 success = requestGetConfiguration(); 00514 break; 00515 case SET_CONFIGURATION: 00516 success = requestSetConfiguration(); 00517 break; 00518 case GET_INTERFACE: 00519 success = requestGetInterface(); 00520 break; 00521 case SET_INTERFACE: 00522 success = requestSetInterface(); 00523 break; 00524 default: 00525 break; 00526 } 00527 } 00528 00529 return success; 00530 } 00531 00532 bool USBDevice::controlSetup(void) 00533 { 00534 bool success = false; 00535 00536 /* Control transfer setup stage */ 00537 uint8_t buffer[MAX_PACKET_SIZE_EP0]; 00538 00539 EP0setup(buffer); 00540 00541 /* Initialise control transfer state */ 00542 decodeSetupPacket(buffer, &transfer.setup); 00543 transfer.ptr = NULL; 00544 transfer.remaining = 0; 00545 transfer.direction = 0; 00546 transfer.zlp = false; 00547 transfer.notify = false; 00548 00549 #ifdef DEBUG 00550 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, 00551 transfer.setup.bmRequestType.Type, 00552 transfer.setup.bmRequestType.Recipient, 00553 transfer.setup.bRequest, 00554 transfer.setup.wValue, 00555 transfer.setup.wIndex, 00556 transfer.setup.wLength); 00557 #endif 00558 00559 /* Class / vendor specific */ 00560 success = USBCallback_request(); 00561 00562 if (!success) 00563 { 00564 /* Standard requests */ 00565 if (!requestSetup()) 00566 { 00567 #ifdef DEBUG 00568 printf("fail!!!!\r\n"); 00569 #endif 00570 return false; 00571 } 00572 } 00573 00574 /* Check transfer size and direction */ 00575 if (transfer.setup.wLength>0) 00576 { 00577 if (transfer.setup.bmRequestType.dataTransferDirection \ 00578 == DEVICE_TO_HOST) 00579 { 00580 /* IN data stage is required */ 00581 if (transfer.direction != DEVICE_TO_HOST) 00582 { 00583 return false; 00584 } 00585 00586 /* Transfer must be less than or equal to the size */ 00587 /* requested by the host */ 00588 if (transfer.remaining > transfer.setup.wLength) 00589 { 00590 transfer.remaining = transfer.setup.wLength; 00591 } 00592 } 00593 else 00594 { 00595 00596 /* OUT data stage is required */ 00597 if (transfer.direction != HOST_TO_DEVICE) 00598 { 00599 return false; 00600 } 00601 00602 /* Transfer must be equal to the size requested by the host */ 00603 if (transfer.remaining != transfer.setup.wLength) 00604 { 00605 return false; 00606 } 00607 } 00608 } 00609 else 00610 { 00611 /* No data stage; transfer size must be zero */ 00612 if (transfer.remaining != 0) 00613 { 00614 return false; 00615 } 00616 } 00617 00618 /* Data or status stage if applicable */ 00619 if (transfer.setup.wLength>0) 00620 { 00621 if (transfer.setup.bmRequestType.dataTransferDirection \ 00622 == DEVICE_TO_HOST) 00623 { 00624 /* Check if we'll need to send a zero length packet at */ 00625 /* the end of this transfer */ 00626 if (transfer.setup.wLength > transfer.remaining) 00627 { 00628 /* Device wishes to transfer less than host requested */ 00629 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0) 00630 { 00631 /* Transfer is a multiple of EP0 max packet size */ 00632 transfer.zlp = true; 00633 } 00634 } 00635 00636 /* IN stage */ 00637 controlIn(); 00638 } 00639 else 00640 { 00641 /* OUT stage */ 00642 EP0read(); 00643 } 00644 } 00645 else 00646 { 00647 /* Status stage */ 00648 EP0write(NULL, 0); 00649 } 00650 00651 return true; 00652 } 00653 00654 void USBDevice::busReset(void) 00655 { 00656 device.state = DEFAULT; 00657 device.configuration = 0; 00658 device.suspended = false; 00659 00660 /* Call class / vendor specific busReset function */ 00661 USBCallback_busReset(); 00662 } 00663 00664 void USBDevice::EP0setupCallback(void) 00665 { 00666 /* Endpoint 0 setup event */ 00667 if (!controlSetup()) 00668 { 00669 /* Protocol stall */ 00670 EP0stall(); 00671 } 00672 00673 /* Return true if an OUT data stage is expected */ 00674 } 00675 00676 void USBDevice::EP0out(void) 00677 { 00678 /* Endpoint 0 OUT data event */ 00679 if (!controlOut()) 00680 { 00681 /* Protocol stall; this will stall both endpoints */ 00682 EP0stall(); 00683 } 00684 } 00685 00686 void USBDevice::EP0in(void) 00687 { 00688 #ifdef DEBUG 00689 printf("EP0IN\r\n"); 00690 #endif 00691 /* Endpoint 0 IN data event */ 00692 if (!controlIn()) 00693 { 00694 /* Protocol stall; this will stall both endpoints */ 00695 EP0stall(); 00696 } 00697 } 00698 00699 bool USBDevice::configured(void) 00700 { 00701 /* Returns true if device is in the CONFIGURED state */ 00702 return (device.state == CONFIGURED); 00703 } 00704 00705 void USBDevice::connect(void) 00706 { 00707 /* Connect device */ 00708 USBHAL::connect(); 00709 /* Block if not configured */ 00710 while (!configured()); 00711 } 00712 00713 void USBDevice::disconnect(void) 00714 { 00715 /* Disconnect device */ 00716 USBHAL::disconnect(); 00717 } 00718 00719 CONTROL_TRANSFER * USBDevice::getTransferPtr(void) 00720 { 00721 return &transfer; 00722 } 00723 00724 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket) 00725 { 00726 return realiseEndpoint(endpoint, maxPacket, 0); 00727 } 00728 00729 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket) 00730 { 00731 /* For interrupt endpoints only */ 00732 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE); 00733 } 00734 00735 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType) 00736 { 00737 /* Find a descriptor within the list of descriptors */ 00738 /* following a configuration descriptor. */ 00739 uint16_t wTotalLength; 00740 uint8_t *ptr; 00741 00742 if (configurationDesc() == NULL) 00743 { 00744 return NULL; 00745 } 00746 00747 /* Check this is a configuration descriptor */ 00748 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \ 00749 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR)) 00750 { 00751 return NULL; 00752 } 00753 00754 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8); 00755 00756 /* Check there are some more descriptors to follow */ 00757 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2)) 00758 /* +2 is for bLength and bDescriptorType of next descriptor */ 00759 { 00760 return false; 00761 } 00762 00763 /* Start at first descriptor after the configuration descriptor */ 00764 ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]); 00765 00766 do { 00767 if (ptr[1] /* bDescriptorType */ == descriptorType) 00768 { 00769 /* Found */ 00770 return ptr; 00771 } 00772 00773 /* Skip to next descriptor */ 00774 ptr += ptr[0]; /* bLength */ 00775 } while (ptr < (configurationDesc() + wTotalLength)); 00776 00777 /* Reached end of the descriptors - not found */ 00778 return NULL; 00779 } 00780 00781 00782 void USBDevice::connectStateChanged(unsigned int connected) 00783 { 00784 } 00785 00786 void USBDevice::suspendStateChanged(unsigned int suspended) 00787 { 00788 } 00789 00790 00791 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){ 00792 VENDOR_ID = vendor_id; 00793 PRODUCT_ID = product_id; 00794 PRODUCT_RELEASE = product_release; 00795 00796 /* Set initial device state */ 00797 device.state = POWERED; 00798 device.configuration = 0; 00799 device.suspended = false; 00800 }; 00801 00802 00803 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize) 00804 { 00805 return endpointRead(endpoint, maxSize) == EP_PENDING; 00806 } 00807 00808 00809 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00810 { 00811 EP_STATUS result; 00812 00813 if (size > maxSize) 00814 { 00815 return false; 00816 } 00817 00818 00819 if(!configured()) { 00820 return false; 00821 } 00822 00823 /* Send report */ 00824 result = endpointWrite(endpoint, buffer, size); 00825 00826 if (result != EP_PENDING) 00827 { 00828 return false; 00829 } 00830 00831 /* Wait for completion */ 00832 do { 00833 result = endpointWriteResult(endpoint); 00834 } while ((result == EP_PENDING) && configured()); 00835 00836 return (result == EP_COMPLETED); 00837 } 00838 00839 00840 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00841 { 00842 EP_STATUS result; 00843 00844 if (size > maxSize) 00845 { 00846 return false; 00847 } 00848 00849 if(!configured()) { 00850 return false; 00851 } 00852 00853 /* Send report */ 00854 result = endpointWrite(endpoint, buffer, size); 00855 00856 if (result != EP_PENDING) 00857 { 00858 return false; 00859 } 00860 00861 result = endpointWriteResult(endpoint); 00862 00863 return (result == EP_COMPLETED); 00864 } 00865 00866 00867 00868 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00869 { 00870 EP_STATUS result; 00871 00872 if(!configured()) { 00873 return false; 00874 } 00875 00876 /* Wait for completion */ 00877 do { 00878 result = endpointReadResult(endpoint, buffer, size); 00879 } while ((result == EP_PENDING) && configured()); 00880 00881 return (result == EP_COMPLETED); 00882 } 00883 00884 00885 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00886 { 00887 EP_STATUS result; 00888 00889 if(!configured()) { 00890 return false; 00891 } 00892 00893 result = endpointReadResult(endpoint, buffer, size); 00894 00895 return (result == EP_COMPLETED); 00896 } 00897 00898 00899 00900 uint8_t * USBDevice::deviceDesc() { 00901 static uint8_t deviceDescriptor[] = { 00902 DEVICE_DESCRIPTOR_LENGTH, /* bLength */ 00903 DEVICE_DESCRIPTOR, /* bDescriptorType */ 00904 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */ 00905 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */ 00906 0x00, /* bDeviceClass */ 00907 0x00, /* bDeviceSubClass */ 00908 0x00, /* bDeviceprotocol */ 00909 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */ 00910 LSB(VENDOR_ID), /* idVendor (LSB) */ 00911 MSB(VENDOR_ID), /* idVendor (MSB) */ 00912 LSB(PRODUCT_ID), /* idProduct (LSB) */ 00913 MSB(PRODUCT_ID), /* idProduct (MSB) */ 00914 LSB(PRODUCT_RELEASE), /* bcdDevice (LSB) */ 00915 MSB(PRODUCT_RELEASE), /* bcdDevice (MSB) */ 00916 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */ 00917 STRING_OFFSET_IPRODUCT, /* iProduct */ 00918 STRING_OFFSET_ISERIAL, /* iSerialNumber */ 00919 0x01 /* bNumConfigurations */ 00920 }; 00921 return deviceDescriptor; 00922 } 00923 00924 uint8_t * USBDevice::stringLangidDesc() { 00925 static uint8_t stringLangidDescriptor[] = { 00926 0x04, /*bLength*/ 00927 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00928 0x09,0x00, /*bString Lang ID - 0x009 - English*/ 00929 }; 00930 return stringLangidDescriptor; 00931 } 00932 00933 uint8_t * USBDevice::stringImanufacturerDesc() { 00934 static uint8_t stringImanufacturerDescriptor[] = { 00935 0x12, /*bLength*/ 00936 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00937 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/ 00938 }; 00939 return stringImanufacturerDescriptor; 00940 } 00941 00942 uint8_t * USBDevice::stringIserialDesc() { 00943 static uint8_t stringIserialDescriptor[] = { 00944 0x16, /*bLength*/ 00945 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00946 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/ 00947 }; 00948 return stringIserialDescriptor; 00949 } 00950 00951 uint8_t * USBDevice::stringIConfigurationDesc() { 00952 static uint8_t stringIconfigurationDescriptor[] = { 00953 0x06, /*bLength*/ 00954 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00955 '0',0,'1',0, /*bString iConfiguration - 01*/ 00956 }; 00957 return stringIconfigurationDescriptor; 00958 } 00959 00960 uint8_t * USBDevice::stringIinterfaceDesc() { 00961 static uint8_t stringIinterfaceDescriptor[] = { 00962 0x08, /*bLength*/ 00963 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00964 'U',0,'S',0,'B',0, /*bString iInterface - USB*/ 00965 }; 00966 return stringIinterfaceDescriptor; 00967 } 00968 00969 uint8_t * USBDevice::stringIproductDesc() { 00970 static uint8_t stringIproductDescriptor[] = { 00971 0x16, /*bLength*/ 00972 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00973 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/ 00974 }; 00975 return stringIproductDescriptor; 00976 }
Generated on Wed Jul 13 2022 03:25:45 by
 1.7.2
 1.7.2 
    