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