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