Fork of official USB device library just changed PID (Product ID) in constructor in USBMSD.h to be different for USBMSD_AT45_HelloWorld program

Dependents:   USBMSD_AT45_HelloWorld

Fork of USBDevice by mbed official

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