CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

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