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