Fork of https://developer.mbed.org/users/bscott/code/STM32_USBDevice/

Fork of STM32_USBDevice by Bradley Scott

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.cpp Source File

USBDevice.cpp

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