Ales Povalac / USBDeviceLite

Dependents:   EMIRv2

Fork of USBDevice by Ales Povalac

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.cpp Source File

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