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