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