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