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