USB device stack for NUCLEO-F042K6, NUCLEO-L152RE and NUCLEO-F103RB.

Dependents:   LPE-SEM01

Fork of L152RE_USBDevice by Norimasa Okamoto

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