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