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 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(void) 00707 { 00708 /* Connect device */ 00709 USBHAL::connect(); 00710 /* Block if not configured */ 00711 while (!configured()); 00712 } 00713 00714 void USBDevice::disconnect(void) 00715 { 00716 /* Disconnect device */ 00717 USBHAL::disconnect(); 00718 } 00719 00720 CONTROL_TRANSFER * USBDevice::getTransferPtr(void) 00721 { 00722 return &transfer; 00723 } 00724 00725 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket) 00726 { 00727 return realiseEndpoint(endpoint, maxPacket, 0); 00728 } 00729 00730 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket) 00731 { 00732 /* For interrupt endpoints only */ 00733 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE); 00734 } 00735 00736 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType) 00737 { 00738 /* Find a descriptor within the list of descriptors */ 00739 /* following a configuration descriptor. */ 00740 uint16_t wTotalLength; 00741 uint8_t *ptr; 00742 00743 if (configurationDesc() == NULL) 00744 { 00745 return NULL; 00746 } 00747 00748 /* Check this is a configuration descriptor */ 00749 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \ 00750 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR)) 00751 { 00752 return NULL; 00753 } 00754 00755 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8); 00756 00757 /* Check there are some more descriptors to follow */ 00758 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2)) 00759 /* +2 is for bLength and bDescriptorType of next descriptor */ 00760 { 00761 return false; 00762 } 00763 00764 /* Start at first descriptor after the configuration descriptor */ 00765 ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]); 00766 00767 do { 00768 if (ptr[1] /* bDescriptorType */ == descriptorType) 00769 { 00770 /* Found */ 00771 return ptr; 00772 } 00773 00774 /* Skip to next descriptor */ 00775 ptr += ptr[0]; /* bLength */ 00776 } while (ptr < (configurationDesc() + wTotalLength)); 00777 00778 /* Reached end of the descriptors - not found */ 00779 return NULL; 00780 } 00781 00782 00783 void USBDevice::connectStateChanged(unsigned int connected) 00784 { 00785 } 00786 00787 void USBDevice::suspendStateChanged(unsigned int suspended) 00788 { 00789 } 00790 00791 00792 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){ 00793 VENDOR_ID = vendor_id; 00794 PRODUCT_ID = product_id; 00795 PRODUCT_RELEASE = product_release; 00796 00797 /* Set initial device state */ 00798 device.state = POWERED; 00799 device.configuration = 0; 00800 device.suspended = false; 00801 }; 00802 00803 00804 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize) 00805 { 00806 return endpointRead(endpoint, maxSize) == EP_PENDING; 00807 } 00808 00809 00810 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00811 { 00812 EP_STATUS result; 00813 00814 if (size > maxSize) 00815 { 00816 return false; 00817 } 00818 00819 00820 if(!configured()) { 00821 return false; 00822 } 00823 00824 /* Send report */ 00825 result = endpointWrite(endpoint, buffer, size); 00826 00827 if (result != EP_PENDING) 00828 { 00829 return false; 00830 } 00831 00832 /* Wait for completion */ 00833 do { 00834 result = endpointWriteResult(endpoint); 00835 } while ((result == EP_PENDING) && configured()); 00836 00837 return (result == EP_COMPLETED); 00838 } 00839 00840 00841 bool USBDevice::writeNB(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 return false; 00852 } 00853 00854 /* Send report */ 00855 result = endpointWrite(endpoint, buffer, size); 00856 00857 if (result != EP_PENDING) 00858 { 00859 return false; 00860 } 00861 00862 result = endpointWriteResult(endpoint); 00863 00864 return (result == EP_COMPLETED); 00865 } 00866 00867 00868 00869 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00870 { 00871 EP_STATUS result; 00872 00873 if(!configured()) { 00874 return false; 00875 } 00876 00877 /* Wait for completion */ 00878 do { 00879 result = endpointReadResult(endpoint, buffer, size); 00880 } while ((result == EP_PENDING) && configured()); 00881 00882 return (result == EP_COMPLETED); 00883 } 00884 00885 00886 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00887 { 00888 EP_STATUS result; 00889 00890 if(!configured()) { 00891 return false; 00892 } 00893 00894 result = endpointReadResult(endpoint, buffer, size); 00895 00896 return (result == EP_COMPLETED); 00897 } 00898 00899 00900 00901 uint8_t * USBDevice::deviceDesc() { 00902 static uint8_t deviceDescriptor[] = { 00903 DEVICE_DESCRIPTOR_LENGTH, /* bLength */ 00904 DEVICE_DESCRIPTOR, /* bDescriptorType */ 00905 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */ 00906 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */ 00907 0x00, /* bDeviceClass */ 00908 0x00, /* bDeviceSubClass */ 00909 0x00, /* bDeviceprotocol */ 00910 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */ 00911 LSB(VENDOR_ID), /* idVendor (LSB) */ 00912 MSB(VENDOR_ID), /* idVendor (MSB) */ 00913 LSB(PRODUCT_ID), /* idProduct (LSB) */ 00914 MSB(PRODUCT_ID), /* idProduct (MSB) */ 00915 LSB(PRODUCT_RELEASE), /* bcdDevice (LSB) */ 00916 MSB(PRODUCT_RELEASE), /* bcdDevice (MSB) */ 00917 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */ 00918 STRING_OFFSET_IPRODUCT, /* iProduct */ 00919 STRING_OFFSET_ISERIAL, /* iSerialNumber */ 00920 0x01 /* bNumConfigurations */ 00921 }; 00922 return deviceDescriptor; 00923 } 00924 00925 uint8_t * USBDevice::stringLangidDesc() { 00926 static uint8_t stringLangidDescriptor[] = { 00927 0x04, /*bLength*/ 00928 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00929 0x09,0x00, /*bString Lang ID - 0x009 - English*/ 00930 }; 00931 return stringLangidDescriptor; 00932 } 00933 00934 uint8_t * USBDevice::stringImanufacturerDesc() { 00935 static uint8_t stringImanufacturerDescriptor[] = { 00936 0x12, /*bLength*/ 00937 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00938 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/ 00939 }; 00940 return stringImanufacturerDescriptor; 00941 } 00942 00943 uint8_t * USBDevice::stringIserialDesc() { 00944 static uint8_t stringIserialDescriptor[] = { 00945 0x16, /*bLength*/ 00946 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00947 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/ 00948 }; 00949 return stringIserialDescriptor; 00950 } 00951 00952 uint8_t * USBDevice::stringIConfigurationDesc() { 00953 static uint8_t stringIconfigurationDescriptor[] = { 00954 0x06, /*bLength*/ 00955 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00956 '0',0,'1',0, /*bString iConfiguration - 01*/ 00957 }; 00958 return stringIconfigurationDescriptor; 00959 } 00960 00961 uint8_t * USBDevice::stringIinterfaceDesc() { 00962 static uint8_t stringIinterfaceDescriptor[] = { 00963 0x08, /*bLength*/ 00964 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00965 'U',0,'S',0,'B',0, /*bString iInterface - USB*/ 00966 }; 00967 return stringIinterfaceDescriptor; 00968 } 00969 00970 uint8_t * USBDevice::stringIproductDesc() { 00971 static uint8_t stringIproductDescriptor[] = { 00972 0x16, /*bLength*/ 00973 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 00974 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/ 00975 }; 00976 return stringIproductDescriptor; 00977 }
Generated on Wed Jul 20 2022 00:01:16 by
