Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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