Forked to make modifications to bring the USBHID into USB compliance and add additional features.

Dependents:   HW4_AudioControl

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