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