A copy of the mbed USBDevice with USBSerial library

Dependents:   STM32L0_LoRa Smartage STM32L0_LoRa Turtle_RadioShuttle

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.cpp Source File

USBDevice.cpp

00001 #include "mbed.h"
00002 #include "PinMap.h"
00003 
00004 #ifdef FEATURE_USBSERIAL
00005 
00006 /* Copyright (c) 2010-2011 mbed.org, MIT License
00007 *
00008 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00009 * and associated documentation files (the "Software"), to deal in the Software without
00010 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00011 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00012 * Software is furnished to do so, subject to the following conditions:
00013 *
00014 * The above copyright notice and this permission notice shall be included in all copies or
00015 * substantial portions of the Software.
00016 *
00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00018 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00020 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 */
00023 
00024 #include "stdint.h"
00025 
00026 #include "USBEndpoints.h"
00027 #include "USBDevice.h"
00028 #include "USBDescriptor.h"
00029 
00030 //#define DEBUG
00031 
00032 /* Device status */
00033 #define DEVICE_STATUS_SELF_POWERED  (1U<<0)
00034 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
00035 
00036 /* Endpoint status */
00037 #define ENDPOINT_STATUS_HALT        (1U<<0)
00038 
00039 /* Standard feature selectors */
00040 #define DEVICE_REMOTE_WAKEUP        (1)
00041 #define ENDPOINT_HALT               (0)
00042 
00043 /* Macro to convert wIndex endpoint number to physical endpoint number */
00044 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
00045     ((endpoint & 0x80) ? 1 : 0))
00046 
00047 
00048 bool USBDevice::requestGetDescriptor(void)
00049 {
00050     bool success = false;
00051 #ifdef DEBUG
00052     printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
00053 #endif
00054     switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
00055     {
00056         case DEVICE_DESCRIPTOR:
00057             if (deviceDesc() != NULL)
00058             {
00059                 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
00060                     && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
00061                 {
00062 #ifdef DEBUG
00063                     printf("device descr\r\n");
00064 #endif
00065                     transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
00066                     transfer.ptr = (uint8_t*)deviceDesc();
00067                     transfer.direction = DEVICE_TO_HOST;
00068                     success = true;
00069                 }
00070             }
00071             break;
00072         case CONFIGURATION_DESCRIPTOR:
00073             if (configurationDesc() != NULL)
00074             {
00075                 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
00076                     && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
00077                 {
00078 #ifdef DEBUG
00079                     printf("conf descr request\r\n");
00080 #endif
00081                     /* Get wTotalLength */
00082                     transfer.remaining = configurationDesc()[2] \
00083                         | (configurationDesc()[3] << 8);
00084 
00085                     transfer.ptr = (uint8_t*)configurationDesc();
00086                     transfer.direction = DEVICE_TO_HOST;
00087                     success = true;
00088                 }
00089             }
00090             break;
00091         case STRING_DESCRIPTOR:
00092 #ifdef DEBUG
00093             printf("str descriptor\r\n");
00094 #endif
00095             switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
00096             {
00097                             case STRING_OFFSET_LANGID:
00098 #ifdef DEBUG
00099                                 printf("1\r\n");
00100 #endif
00101                                 transfer.remaining = stringLangidDesc()[0];
00102                                 transfer.ptr = (uint8_t*)stringLangidDesc();
00103                                 transfer.direction = DEVICE_TO_HOST;
00104                                 success = true;
00105                                 break;
00106                             case STRING_OFFSET_IMANUFACTURER:
00107 #ifdef DEBUG
00108                                 printf("2\r\n");
00109 #endif
00110                                 transfer.remaining =  stringImanufacturerDesc()[0];
00111                                 transfer.ptr = (uint8_t*)stringImanufacturerDesc();
00112                                 transfer.direction = DEVICE_TO_HOST;
00113                                 success = true;
00114                                 break;
00115                             case STRING_OFFSET_IPRODUCT:
00116 #ifdef DEBUG
00117                                 printf("3\r\n");
00118 #endif
00119                                 transfer.remaining = stringIproductDesc()[0];
00120                                 transfer.ptr = (uint8_t*)stringIproductDesc();
00121                                 transfer.direction = DEVICE_TO_HOST;
00122                                 success = true;
00123                                 break;
00124                             case STRING_OFFSET_ISERIAL:
00125 #ifdef DEBUG
00126                                 printf("4\r\n");
00127 #endif
00128                                 transfer.remaining = stringIserialDesc()[0];
00129                                 transfer.ptr = (uint8_t*)stringIserialDesc();
00130                                 transfer.direction = DEVICE_TO_HOST;
00131                                 success = true;
00132                                 break;
00133                             case STRING_OFFSET_ICONFIGURATION:
00134 #ifdef DEBUG
00135                                 printf("5\r\n");
00136 #endif
00137                                 transfer.remaining = stringIConfigurationDesc()[0];
00138                                 transfer.ptr = (uint8_t*)stringIConfigurationDesc();
00139                                 transfer.direction = DEVICE_TO_HOST;
00140                                 success = true;
00141                                 break;
00142                             case STRING_OFFSET_IINTERFACE:
00143 #ifdef DEBUG
00144                                 printf("6\r\n");
00145 #endif
00146                                 transfer.remaining = stringIinterfaceDesc()[0];
00147                                 transfer.ptr = (uint8_t*)stringIinterfaceDesc();
00148                                 transfer.direction = DEVICE_TO_HOST;
00149                                 success = true;
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         default:
00164 #ifdef DEBUG
00165             printf("ERROR\r\n");
00166 #endif
00167             break;
00168     }
00169 
00170     return success;
00171 }
00172 
00173 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
00174 {
00175     /* Fill in the elements of a SETUP_PACKET structure from raw data */
00176     packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
00177     packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
00178     packet->bmRequestType.Recipient = data[0] & 0x1f;
00179     packet->bRequest = data[1];
00180     packet->wValue = (data[2] | (uint16_t)data[3] << 8);
00181     packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
00182     packet->wLength = (data[6] | (uint16_t)data[7] << 8);
00183 }
00184 
00185 
00186 bool USBDevice::controlOut(void)
00187 {
00188     /* Control transfer data OUT stage */
00189     uint8_t buffer[MAX_PACKET_SIZE_EP0];
00190     uint32_t packetSize;
00191 
00192     /* Check we should be transferring data OUT */
00193     if (transfer.direction != HOST_TO_DEVICE)
00194     {
00195          /* for other platforms, count on the HAL to handle this case */
00196          return false;
00197     }
00198 
00199     /* Read from endpoint */
00200     packetSize = EP0getReadResult(buffer);
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     transfer.ptr += packetSize;
00211     transfer.remaining -= packetSize;
00212 
00213     /* Check if transfer has completed */
00214     if (transfer.remaining == 0)
00215     {
00216         /* Transfer completed */
00217         if (transfer.notify)
00218         {
00219             /* Notify class layer. */
00220             USBCallback_requestCompleted(buffer, packetSize);
00221             transfer.notify = false;
00222         }
00223         /* Status stage */
00224         EP0write(NULL, 0);
00225     }
00226     else
00227     {
00228         EP0read();
00229     }
00230 
00231     return true;
00232 }
00233 
00234 bool USBDevice::controlIn(void)
00235 {
00236     /* Control transfer data IN stage */
00237     uint32_t packetSize;
00238 
00239     /* Check if transfer has completed (status stage transactions */
00240     /* also have transfer.remaining == 0) */
00241     if (transfer.remaining == 0)
00242     {
00243         if (transfer.zlp)
00244         {
00245             /* Send zero length packet */
00246             EP0write(NULL, 0);
00247             transfer.zlp = false;
00248         }
00249 
00250         /* Transfer completed */
00251         if (transfer.notify)
00252         {
00253             /* Notify class layer. */
00254             USBCallback_requestCompleted(NULL, 0);
00255             transfer.notify = false;
00256         }
00257 
00258         EP0read();
00259         EP0readStage();
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 = &currentAlternate;
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(bool blocking)
00713 {
00714     /* Connect device */
00715     USBHAL::connect();
00716 
00717     if (blocking) {
00718         /* Block if not configured */
00719         while (!configured());
00720     }
00721 }
00722 
00723 void USBDevice::disconnect(void)
00724 {
00725     /* Disconnect device */
00726     USBHAL::disconnect();
00727     
00728     /* Set initial device state */
00729     device.state = POWERED;
00730     device.configuration = 0;
00731     device.suspended = false;
00732 }
00733 
00734 CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
00735 {
00736     return &transfer;
00737 }
00738 
00739 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
00740 {
00741     return realiseEndpoint(endpoint, maxPacket, 0);
00742 }
00743 
00744 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
00745 {
00746     /* For interrupt endpoints only */
00747     return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
00748 }
00749 
00750 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
00751 {
00752     /* Find a descriptor within the list of descriptors */
00753     /* following a configuration descriptor. */
00754     uint16_t wTotalLength;
00755     uint8_t *ptr;
00756 
00757     if (configurationDesc() == NULL)
00758     {
00759         return NULL;
00760     }
00761 
00762     /* Check this is a configuration descriptor */
00763     if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
00764             || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
00765     {
00766         return NULL;
00767     }
00768 
00769     wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
00770 
00771     /* Check there are some more descriptors to follow */
00772     if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
00773     /* +2 is for bLength and bDescriptorType of next descriptor */
00774     {
00775         return NULL;
00776     }
00777 
00778     /* Start at first descriptor after the configuration descriptor */
00779     ptr = &(((uint8_t*)configurationDesc())[CONFIGURATION_DESCRIPTOR_LENGTH]);
00780 
00781     do {
00782         if (ptr[1] /* bDescriptorType */ == descriptorType)
00783         {
00784             /* Found */
00785             return ptr;
00786         }
00787 
00788         /* Skip to next descriptor */
00789         ptr += ptr[0]; /* bLength */
00790     } while (ptr < (configurationDesc() + wTotalLength));
00791 
00792     /* Reached end of the descriptors - not found */
00793     return NULL;
00794 }
00795 
00796 
00797 void USBDevice::connectStateChanged(unsigned int connected)
00798 {
00799 }
00800 
00801 void USBDevice::suspendStateChanged(unsigned int suspended)
00802 {
00803 }
00804 
00805 
00806 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
00807     VENDOR_ID = vendor_id;
00808     PRODUCT_ID = product_id;
00809     PRODUCT_RELEASE = product_release;
00810 
00811     /* Set initial device state */
00812     device.state = POWERED;
00813     device.configuration = 0;
00814     device.suspended = false;
00815 };
00816 
00817 
00818 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize)
00819 {
00820     return endpointRead(endpoint, maxSize) == EP_PENDING;
00821 }
00822 
00823 
00824 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
00825 {
00826     EP_STATUS result;
00827 
00828     if (size > maxSize)
00829     {
00830         return false;
00831     }
00832 
00833 
00834     if(!configured()) {
00835         return false;
00836     }
00837 
00838     /* Send report */
00839     result = endpointWrite(endpoint, buffer, size);
00840 
00841     if (result != EP_PENDING)
00842     {
00843         return false;
00844     }
00845 
00846     /* Wait for completion */
00847     do {
00848         result = endpointWriteResult(endpoint);
00849     } while ((result == EP_PENDING) && configured());
00850 
00851     return (result == EP_COMPLETED);
00852 }
00853 
00854 
00855 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
00856 {
00857     EP_STATUS result;
00858 
00859     if (size > maxSize)
00860     {
00861         return false;
00862     }
00863 
00864     if(!configured()) {
00865         return false;
00866     }
00867 
00868     /* Send report */
00869     result = endpointWrite(endpoint, buffer, size);
00870 
00871     if (result != EP_PENDING)
00872     {
00873         return false;
00874     }
00875 
00876     result = endpointWriteResult(endpoint);
00877 
00878     return (result == EP_COMPLETED);
00879 }
00880 
00881 
00882 
00883 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
00884 {
00885     EP_STATUS result;
00886 
00887     if(!configured()) {
00888         return false;
00889     }
00890 
00891     /* Wait for completion */
00892     do {
00893         result = endpointReadResult(endpoint, buffer, size);
00894     } while ((result == EP_PENDING) && configured());
00895 
00896     return (result == EP_COMPLETED);
00897 }
00898 
00899 
00900 bool USBDevice::readEP_NB(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     result = endpointReadResult(endpoint, buffer, size);
00909 
00910     return (result == EP_COMPLETED);
00911 }
00912 
00913 
00914 
00915 const uint8_t * USBDevice::deviceDesc() {
00916     uint8_t deviceDescriptorTemp[] = {
00917         DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
00918         DEVICE_DESCRIPTOR,              /* bDescriptorType */
00919         LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
00920         MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
00921         0x00,                           /* bDeviceClass */
00922         0x00,                           /* bDeviceSubClass */
00923         0x00,                           /* bDeviceprotocol */
00924         MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
00925         (uint8_t)(LSB(VENDOR_ID)),                 /* idVendor (LSB) */
00926         (uint8_t)(MSB(VENDOR_ID)),                 /* idVendor (MSB) */
00927         (uint8_t)(LSB(PRODUCT_ID)),                /* idProduct (LSB) */
00928         (uint8_t)(MSB(PRODUCT_ID)),                /* idProduct (MSB) */
00929         (uint8_t)(LSB(PRODUCT_RELEASE)),           /* bcdDevice (LSB) */
00930         (uint8_t)(MSB(PRODUCT_RELEASE)),           /* bcdDevice (MSB) */
00931         STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
00932         STRING_OFFSET_IPRODUCT,         /* iProduct */
00933         STRING_OFFSET_ISERIAL,          /* iSerialNumber */
00934         0x01                            /* bNumConfigurations */
00935     };
00936     MBED_ASSERT(sizeof(deviceDescriptorTemp) == sizeof(deviceDescriptor));
00937     memcpy(deviceDescriptor, deviceDescriptorTemp, sizeof(deviceDescriptor));
00938     return deviceDescriptor;
00939 }
00940 
00941 const uint8_t * USBDevice::stringLangidDesc() {
00942     static const uint8_t stringLangidDescriptor[] = {
00943         0x04,               /*bLength*/
00944         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
00945         0x09,0x04,          /*bString Lang ID - 0x0409 - English*/
00946     };
00947     return (uint8_t *)stringLangidDescriptor;
00948 }
00949 
00950 const uint8_t * USBDevice::stringImanufacturerDesc() {
00951     static const uint8_t stringImanufacturerDescriptor[] = {
00952         0x14,                                            /*bLength*/
00953         STRING_DESCRIPTOR,                               /*bDescriptorType 0x03*/
00954         'h',0,'e',0,'l',0,'i',0,'o',0,'s',0,'.',0,'d',0,'e',0,/*bString iManufacturer - helios.de */
00955     };
00956     return stringImanufacturerDescriptor;
00957 }
00958 
00959 const uint8_t * USBDevice::stringIserialDesc() {
00960     static const uint8_t stringIserialDescriptor[] = {
00961         0x16,                                                           /*bLength*/
00962         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
00963         '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
00964     };
00965     return stringIserialDescriptor;
00966 }
00967 
00968 const uint8_t * USBDevice::stringIConfigurationDesc() {
00969     static const uint8_t stringIconfigurationDescriptor[] = {
00970         0x06,               /*bLength*/
00971         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
00972         '0',0,'1',0,        /*bString iConfiguration - 01*/
00973     };
00974     return stringIconfigurationDescriptor;
00975 }
00976 
00977 const uint8_t * USBDevice::stringIinterfaceDesc() {
00978     static const uint8_t stringIinterfaceDescriptor[] = {
00979         0x08,               /*bLength*/
00980         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
00981         'U',0,'S',0,'B',0,  /*bString iInterface - USB*/
00982     };
00983     return stringIinterfaceDescriptor;
00984 }
00985 
00986 const uint8_t * USBDevice::stringIproductDesc() {
00987     static const uint8_t stringIproductDescriptor[] = {
00988         0x16,                                                       /*bLength*/
00989         STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
00990         'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
00991     };
00992     return stringIproductDescriptor;
00993 }
00994 
00995 #endif // FEATURE_USBSERIAL