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