Point Labs / USBDevice

Dependents:   Example_WatchDog_Timer

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