USB device stack, with KL25Z fixes for USB 3.0 hosts and sleep/resume interrupt handling

Dependents:   frdm_Slider_Keyboard idd_hw2_figlax_PanType idd_hw2_appachu_finger_chording idd_hw3_AngieWangAntonioDeLimaFernandesDanielLim_BladeSymphony ... more

Fork of USBDevice by mbed official

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