USB Mouse (relative) example for mbed NXP LPC11U24 beta

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.c Source File

USBDevice.c

00001 /* USBDevice.c */
00002 /* Generic USB device */
00003 /* Copyright (c) 2011 ARM Limited. All rights reserved. */
00004 
00005 /* Reference: */
00006 /* Universal Serial Bus Specification Revision 2.0, Chapter 9 "USB Device Framework" */
00007 
00008 #include "stdint.h"
00009 
00010 #include "USBEndpoints.h"
00011 #include "USBBusInterface.h"
00012 #include "USBDevice.h"
00013 #include "USBDescriptor.h"
00014 #include "USBHID_Types.h"
00015 
00016 /* Device status */
00017 #define DEVICE_STATUS_SELF_POWERED  (1U<<0)
00018 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
00019 
00020 /* Endpoint status */
00021 #define ENDPOINT_STATUS_HALT        (1U<<0)
00022 
00023 /* Standard feature selectors */
00024 #define DEVICE_REMOTE_WAKEUP        (1)
00025 #define ENDPOINT_HALT               (0)
00026 
00027 /* Macro to convert wIndex endpoint number to physical endpoint number */
00028 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
00029     ((endpoint & 0x80) ? 1 : 0))
00030 
00031 CONTROL_TRANSFER transfer;
00032 USB_DEVICE device;
00033 static USBDevice * instDevice = NULL;
00034 
00035 void setInstanceDevice(USBDevice * _inst){ instDevice = _inst;};
00036 
00037 static bool requestGetDescriptor(void)
00038 {
00039     bool success = false;
00040 
00041     switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
00042     {
00043         case DEVICE_DESCRIPTOR:
00044             if (instDevice->DeviceDesc() != NULL)
00045             {
00046                 printf("get device desc\r\n");
00047                 if ((instDevice->DeviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
00048                     && (instDevice->DeviceDesc()[1] == DEVICE_DESCRIPTOR))
00049                 {
00050                     transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
00051                     transfer.ptr = instDevice->DeviceDesc();
00052                     transfer.direction = DEVICE_TO_HOST;
00053                     success = true;
00054                 }
00055             }
00056             break;
00057         case CONFIGURATION_DESCRIPTOR:
00058             if (instDevice->ConfigurationDesc() != NULL)
00059             {
00060                 if ((instDevice->ConfigurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
00061                     && (instDevice->ConfigurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
00062                 {
00063                     printf("get conf desc\r\n");
00064                     /* Get wTotalLength */
00065                     transfer.remaining = instDevice->ConfigurationDesc()[2] \
00066                         | (instDevice->ConfigurationDesc()[3] << 8);
00067 
00068                     transfer.ptr = instDevice->ConfigurationDesc();
00069                     transfer.direction = DEVICE_TO_HOST;
00070                     success = true;
00071                 }
00072             }
00073             break;
00074         case STRING_DESCRIPTOR:
00075             switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
00076             {
00077                             case STRING_OFFSET_LANGID:
00078                                 transfer.remaining = instDevice->StringLangidDesc()[0];
00079                                 transfer.ptr = instDevice->StringLangidDesc();
00080                                 transfer.direction = DEVICE_TO_HOST;
00081                                 success = true;
00082                                 break;
00083                             case STRING_OFFSET_IMANUFACTURER:
00084                                 transfer.remaining =  instDevice->StringImanufacturerDesc()[0];
00085                                 transfer.ptr = instDevice->StringImanufacturerDesc();
00086                                 transfer.direction = DEVICE_TO_HOST;
00087                                 success = true;
00088                                 break;       
00089                             case STRING_OFFSET_IPRODUCT:
00090                                 transfer.remaining = instDevice->StringIproductDesc()[0];
00091                                 transfer.ptr = instDevice->StringIproductDesc();
00092                                 transfer.direction = DEVICE_TO_HOST;
00093                                 success = true;
00094                                 break;            
00095                             case STRING_OFFSET_ISERIAL:
00096                                 transfer.remaining = instDevice->StringIserialDesc()[0];
00097                                 transfer.ptr = instDevice->StringIserialDesc();
00098                                 transfer.direction = DEVICE_TO_HOST;
00099                                 success = true;
00100                                 break;        
00101                             case STRING_OFFSET_ICONFIGURATION:
00102                                 transfer.remaining = instDevice->StringIConfigurationDesc()[0];
00103                                 transfer.ptr = instDevice->StringIConfigurationDesc();
00104                                 transfer.direction = DEVICE_TO_HOST;
00105                                 success = true;
00106                                 break; 
00107                             case STRING_OFFSET_IINTERFACE:
00108                                 transfer.remaining = instDevice->StringIinterfaceDesc()[0];
00109                                 transfer.ptr = instDevice->StringIinterfaceDesc();
00110                                 transfer.direction = DEVICE_TO_HOST;
00111                                 success = true;
00112                                 break; 
00113             }
00114             break;
00115         case INTERFACE_DESCRIPTOR:
00116         case ENDPOINT_DESCRIPTOR:
00117             /* TODO: Support is optional, not implemented here */
00118             break;
00119         default:
00120             break;
00121     }
00122 
00123     return success;
00124 }
00125 
00126 static void decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
00127 {
00128     /* Fill in the elements of a SETUP_PACKET structure from raw data */
00129     packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
00130     packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
00131     packet->bmRequestType.Recipient = data[0] & 0x1f;
00132     packet->bRequest = data[1];
00133     packet->wValue = (data[2] | (uint16_t)data[3] << 8);
00134     packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
00135     packet->wLength = (data[6] | (uint16_t)data[7] << 8);
00136 }
00137 
00138 static bool controlOut(void)
00139 {
00140     /* Control transfer data OUT stage */
00141     uint8_t buffer[MAX_PACKET_SIZE_EP0];
00142     uint32_t packetSize;
00143 
00144     /* Check we should be transferring data OUT */
00145     if (transfer.direction != HOST_TO_DEVICE)
00146     {
00147         return false;
00148     }
00149 
00150     /* Read from endpoint */
00151     packetSize = USBBusInterface_EP0getReadResult(buffer);
00152 
00153     /* Check if transfer size is valid */
00154     if (packetSize > transfer.remaining)
00155     {
00156         /* Too big */
00157         return false;
00158     }
00159 
00160     /* Update transfer */
00161     transfer.ptr += packetSize;
00162     transfer.remaining -= packetSize;
00163 
00164     /* Check if transfer has completed */
00165     if (transfer.remaining == 0)
00166     {
00167         /* Transfer completed */
00168         if (transfer.notify)
00169         {
00170             /* Notify class layer. */
00171             instDevice->USBCallback_requestCompleted();
00172             transfer.notify = false;
00173         }
00174 
00175         /* Status stage */
00176         USBBusInterface_EP0write(NULL, 0);
00177     }
00178     else
00179     {
00180         USBBusInterface_EP0read();
00181     }
00182 
00183     return true;
00184 }
00185 
00186 static bool controlIn(void)
00187 {
00188     /* Control transfer data IN stage */
00189     uint32_t packetSize;
00190 
00191     /* Check if transfer has completed (status stage transactions */
00192     /* also have transfer.remaining == 0) */
00193     if (transfer.remaining == 0)
00194     {
00195         if (transfer.zlp)
00196         {
00197             /* Send zero length packet */
00198             USBBusInterface_EP0write(NULL, 0);
00199             transfer.zlp = false;
00200         }
00201 
00202         /* Transfer completed */
00203         if (transfer.notify)
00204         {
00205             /* Notify class layer. */
00206             instDevice->USBCallback_requestCompleted();
00207             transfer.notify = false;
00208         }
00209 
00210         USBBusInterface_EP0read();
00211 
00212         /* Completed */
00213         return true;
00214     }
00215 
00216     /* Check we should be transferring data IN */
00217     if (transfer.direction != DEVICE_TO_HOST)
00218     {
00219         return false;
00220     }
00221 
00222     packetSize = transfer.remaining;
00223 
00224     if (packetSize > MAX_PACKET_SIZE_EP0)
00225     {
00226         packetSize = MAX_PACKET_SIZE_EP0;
00227     }
00228 
00229     /* Write to endpoint */
00230     USBBusInterface_EP0write(transfer.ptr, packetSize);
00231 
00232     /* Update transfer */
00233     transfer.ptr += packetSize;
00234     transfer.remaining -= packetSize;
00235 
00236     return true;
00237 }
00238 
00239 static bool requestSetAddress(void)
00240 {
00241     /* Set the device address */
00242     USBBusInterface_setAddress(transfer.setup.wValue);
00243 
00244     if (transfer.setup.wValue == 0)
00245     {
00246         device.state = DEFAULT;
00247     }
00248     else
00249     {
00250         device.state = ADDRESS;
00251     }
00252 
00253     return true;
00254 }
00255 
00256 static bool requestSetConfiguration(void)
00257 {
00258 
00259     device.configuration = transfer.setup.wValue;
00260 
00261     /* Set the device configuration */
00262     if (device.configuration == 0)
00263     {
00264         /* Not configured */
00265         USBBusInterface_unconfigureDevice();
00266         device.state = ADDRESS;
00267     }
00268     else
00269     {
00270         if (instDevice->USBCallback_setConfiguration(device.configuration))
00271         {
00272             /* Valid configuration */
00273             USBBusInterface_configureDevice();
00274             device.state = CONFIGURED;
00275         }
00276         else
00277         {
00278             return false;
00279         }
00280     }
00281 
00282     return true;
00283 }
00284 
00285 static bool requestGetConfiguration(void)
00286 {
00287     /* Send the device configuration */
00288     transfer.ptr = &device.configuration;
00289     transfer.remaining = sizeof(device.configuration);
00290     transfer.direction = DEVICE_TO_HOST;
00291     return true;
00292 }
00293 
00294 static bool requestGetInterface(void)
00295 {
00296     static uint8_t alternateSetting;
00297 
00298     /* Return the selected alternate setting for an interface */
00299 
00300     if (device.state != CONFIGURED)
00301     {
00302         return false;
00303     }
00304 
00305     /* TODO: We currently do not support alternate settings */
00306     /* so always return zero */
00307     /* TODO: Should check that the interface number is valid */
00308     alternateSetting = 0;
00309 
00310     /* Send the alternate setting */
00311     transfer.ptr = &alternateSetting;
00312     transfer.remaining = sizeof(alternateSetting);
00313     transfer.direction = DEVICE_TO_HOST;
00314     return true;
00315 }
00316 
00317 static bool requestSetInterface(void)
00318 {
00319     /* TODO: We currently do not support alternate settings, return false */
00320     return false;
00321 }
00322 
00323 static bool requestSetFeature()
00324 {
00325     bool success = false;
00326 
00327     if (device.state != CONFIGURED)
00328     {
00329         /* Endpoint or interface must be zero */
00330         if (transfer.setup.wIndex != 0)
00331         {
00332             return false;
00333         }
00334     }
00335 
00336     switch (transfer.setup.bmRequestType.Recipient)
00337     {
00338         case DEVICE_RECIPIENT:
00339             /* TODO: Remote wakeup feature not supported */
00340             break;
00341         case ENDPOINT_RECIPIENT:
00342             if (transfer.setup.wValue == ENDPOINT_HALT)
00343             {
00344                 /* TODO: We should check that the endpoint number is valid */
00345                 USBBusInterface_stallEndpoint(
00346                     WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
00347                 success = true;
00348             }
00349             break;
00350         default:
00351             break;
00352     }
00353 
00354     return success;
00355 }
00356 
00357 static bool requestClearFeature()
00358 {
00359     bool success = false;
00360 
00361     if (device.state != CONFIGURED)
00362     {
00363         /* Endpoint or interface must be zero */
00364         if (transfer.setup.wIndex != 0)
00365         {
00366             return false;
00367         }
00368     }
00369 
00370     switch (transfer.setup.bmRequestType.Recipient)
00371     {
00372         case DEVICE_RECIPIENT:
00373             /* TODO: Remote wakeup feature not supported */
00374             break;
00375         case ENDPOINT_RECIPIENT:
00376             /* TODO: We should check that the endpoint number is valid */
00377             if (transfer.setup.wValue == ENDPOINT_HALT)
00378             {
00379                 USBBusInterface_unstallEndpoint(
00380                     WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
00381                 success = true;
00382             }
00383             break;
00384         default:
00385             break;
00386     }
00387 
00388     return success;
00389 }
00390 
00391 static bool requestGetStatus(void)
00392 {
00393     static uint16_t status;
00394     bool success = false;
00395 
00396     if (device.state != CONFIGURED)
00397     {
00398         /* Endpoint or interface must be zero */
00399         if (transfer.setup.wIndex != 0)
00400         {
00401             return false;
00402         }
00403     }
00404 
00405     switch (transfer.setup.bmRequestType.Recipient)
00406     {
00407         case DEVICE_RECIPIENT:
00408             /* TODO: Currently only supports self powered devices */
00409             status = DEVICE_STATUS_SELF_POWERED;
00410             success = true;
00411             break;
00412         case INTERFACE_RECIPIENT:
00413             status = 0;
00414             success = true;
00415             break;
00416         case ENDPOINT_RECIPIENT:
00417             /* TODO: We should check that the endpoint number is valid */
00418             if (USBBusInterface_getEndpointStallState(
00419                 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
00420             {
00421                 status = ENDPOINT_STATUS_HALT;
00422             }
00423             else
00424             {
00425                 status = 0;
00426             }
00427             success = true;
00428             break;
00429         default:
00430             break;
00431     }
00432 
00433     if (success)
00434     {
00435         /* Send the status */ 
00436         transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
00437         transfer.remaining = sizeof(status);
00438         transfer.direction = DEVICE_TO_HOST;
00439     }
00440     
00441     return success;
00442 }
00443 
00444 static bool requestSetup(void)
00445 {
00446     bool success = false;
00447 
00448     /* Process standard requests */
00449     if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
00450     {
00451         switch (transfer.setup.bRequest)
00452         {
00453              case GET_STATUS:
00454                  success = requestGetStatus();
00455                  break;
00456              case CLEAR_FEATURE:
00457                  success = requestClearFeature();
00458                  break;
00459              case SET_FEATURE:
00460                  success = requestSetFeature();
00461                  break;
00462              case SET_ADDRESS:
00463                 success = requestSetAddress();
00464                  break;
00465              case GET_DESCRIPTOR:
00466                  success = requestGetDescriptor();
00467                  break;
00468              case SET_DESCRIPTOR:
00469                  /* TODO: Support is optional, not implemented here */
00470                  success = false;
00471                  break;
00472              case GET_CONFIGURATION:
00473                  success = requestGetConfiguration();
00474                  break;
00475              case SET_CONFIGURATION:
00476                  success = requestSetConfiguration();
00477                  break;
00478              case GET_INTERFACE:
00479                  success = requestGetInterface();
00480                  break;
00481              case SET_INTERFACE:
00482                  success = requestSetInterface();
00483                  break;
00484              default:
00485                  break;
00486         }
00487     }
00488 
00489     return success;
00490 }
00491 
00492 static bool controlSetup(void)
00493 {
00494     bool success = false;
00495 
00496     /* Control transfer setup stage */
00497     uint8_t buffer[MAX_PACKET_SIZE_EP0];
00498 
00499     USBBusInterface_EP0setup(buffer);
00500 
00501     /* Initialise control transfer state */
00502     decodeSetupPacket(buffer, &transfer.setup);
00503     transfer.ptr = NULL;
00504     transfer.remaining = 0;
00505     transfer.direction = 0;
00506     transfer.zlp = false;
00507     transfer.notify = false;
00508 
00509     /* Process request */
00510 
00511     /* Class / vendor specific */
00512     success = instDevice->USBCallback_request();
00513 
00514     if (!success)
00515     {
00516         /* Standard requests */
00517         if (!requestSetup())
00518         {
00519             return false;
00520         }
00521     }
00522 
00523     /* Check transfer size and direction */
00524     if (transfer.setup.wLength>0)
00525     {
00526         if (transfer.setup.bmRequestType.dataTransferDirection \
00527             == DEVICE_TO_HOST)
00528         {
00529             /* IN data stage is required */
00530             if (transfer.direction != DEVICE_TO_HOST)
00531             {
00532                 return false;
00533             }
00534 
00535             /* Transfer must be less than or equal to the size */
00536             /* requested by the host */
00537             if (transfer.remaining > transfer.setup.wLength)
00538             {
00539                 transfer.remaining = transfer.setup.wLength;
00540             }
00541         }
00542         else
00543         {
00544             /* OUT data stage is required */
00545             if (transfer.direction != HOST_TO_DEVICE)
00546             {
00547                 return false;
00548             }
00549 
00550             /* Transfer must be equal to the size requested by the host */
00551             if (transfer.remaining != transfer.setup.wLength)
00552             {
00553                 return false;
00554             }
00555         }
00556     }
00557     else
00558     {
00559         /* No data stage; transfer size must be zero */
00560         if (transfer.remaining != 0)
00561         {
00562             return false;
00563         }
00564     }
00565 
00566     /* Data or status stage if applicable */
00567     if (transfer.setup.wLength>0)
00568     {
00569         if (transfer.setup.bmRequestType.dataTransferDirection \
00570             == DEVICE_TO_HOST)
00571         {
00572             /* Check if we'll need to send a zero length packet at */
00573             /* the end of this transfer */
00574             if (transfer.setup.wLength > transfer.remaining)
00575             {
00576                 /* Device wishes to transfer less than host requested */
00577                 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
00578                 {
00579                     /* Transfer is a multiple of EP0 max packet size */
00580                     transfer.zlp = true;
00581                 }
00582             }
00583 
00584             /* IN stage */
00585             controlIn();
00586         }
00587         else
00588         {
00589             /* OUT stage */
00590             USBBusInterface_EP0read();
00591         }
00592     }
00593     else
00594     {
00595         /* Status stage */
00596         USBBusInterface_EP0write(NULL, 0);
00597     }
00598 
00599     return true;
00600 }
00601 
00602 void USBDevice_busReset(void)
00603 {
00604     device.state = DEFAULT;
00605     device.configuration = 0;
00606     device.suspended = false;
00607 
00608     /* Call class / vendor specific busReset function */
00609     instDevice->USBCallback_busReset();
00610 }
00611 
00612 void USBDevice_EP0setup(void)
00613 {
00614     /* Endpoint 0 setup event */
00615     if (!controlSetup())
00616     {
00617         /* Protocol stall */
00618         USBBusInterface_EP0stall();
00619     }
00620 
00621     /* Return true if an OUT data stage is expected */
00622 }
00623 
00624 void USBDevice_EP0out(void)
00625 {
00626     /* Endpoint 0 OUT data event */
00627     if (!controlOut())
00628     {
00629         /* Protocol stall; this will stall both endpoints */
00630         USBBusInterface_EP0stall();
00631     }
00632 }
00633 
00634 void USBDevice_EP0in(void)
00635 {
00636     /* Endpoint 0 IN data event */
00637     if (!controlIn())
00638     {
00639         /* Protocol stall; this will stall both endpoints */
00640         USBBusInterface_EP0stall();
00641     }
00642 }
00643 
00644 bool USBDevice_isConfigured(void)
00645 {
00646     /* Returns true if device is in the CONFIGURED state */
00647     return (device.state == CONFIGURED);
00648 }
00649 
00650 bool USBDevice_init(void)
00651 {
00652     /* Set initial device state */
00653     device.state = POWERED;
00654     device.configuration = 0;
00655     device.suspended = false;
00656 
00657     /* Initialise bus interface */
00658     return USBBusInterface_init();
00659 }
00660 
00661 void USBDevice_uninit(void)
00662 {
00663     /* Uninitialise bus interface */
00664     USBBusInterface_uninit();
00665 }
00666 
00667 void USBDevice_connect(void)
00668 {
00669     /* Connect device */
00670     USBBusInterface_connect();
00671 }
00672 
00673 void USBDevice_disconnect(void)
00674 {
00675     /* Disconnect device */
00676     USBBusInterface_disconnect();
00677 }
00678 
00679 CONTROL_TRANSFER *USBDevice_getTransferPtr(void)
00680 {
00681     return &transfer;
00682 }
00683 
00684 bool USBDevice_addEndpoint(uint8_t endpoint, uint32_t maxPacket)
00685 {
00686     return USBBusInterface_realiseEndpoint(endpoint, maxPacket, 0);
00687 }
00688 
00689 bool USBDevice_addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
00690 {
00691     /* For interrupt endpoints only */
00692     return USBBusInterface_realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
00693 }
00694 
00695 uint8_t *USBDevice_findDescriptor(uint8_t descriptorType)
00696 {
00697     /* Find a descriptor within the list of descriptors */
00698     /* following a configuration descriptor. */
00699     uint16_t wTotalLength;
00700     uint8_t *ptr;
00701 
00702     if (instDevice->ConfigurationDesc() == NULL)
00703     {
00704         return NULL;
00705     }
00706 
00707     /* Check this is a configuration descriptor */
00708     if ((instDevice->ConfigurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
00709             || (instDevice->ConfigurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
00710     {
00711         return NULL;
00712     }
00713 
00714     wTotalLength = instDevice->ConfigurationDesc()[2] | (instDevice->ConfigurationDesc()[3] << 8);
00715 
00716     /* Check there are some more descriptors to follow */
00717     if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
00718     /* +2 is for bLength and bDescriptorType of next descriptor */
00719     {
00720         return false;
00721     }
00722 
00723     /* Start at first descriptor after the configuration descriptor */
00724     ptr = &(instDevice->ConfigurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
00725 
00726     do {
00727         if (ptr[1] /* bDescriptorType */ == descriptorType)
00728         {
00729             /* Found */
00730             return ptr;
00731         }
00732 
00733         /* Skip to next descriptor */
00734         ptr += ptr[0]; /* bLength */
00735     } while (ptr < (instDevice->ConfigurationDesc() + wTotalLength));
00736 
00737     /* Reached end of the descriptors - not found */
00738     return NULL;
00739 }
00740 
00741 void USBDevice_SOF(int frameNumber)
00742 {
00743 }
00744 
00745 void USBDevice_connectStateChanged(unsigned int connected)
00746 {
00747 }
00748 
00749 void USBDevice_suspendStateChanged(unsigned int suspended)
00750 {
00751 }
00752 
00753 
00754 USBDevice::USBDevice(){setInstanceDevice(this);};
00755 
00756 //By default
00757 #define VENDOR_ID       (0x1234)
00758 #define PRODUCT_ID      (0x0001)
00759 #define PRODUCT_RELEASE (0x0100)
00760 
00761 uint8_t * USBDevice::DeviceDesc() {
00762     static uint8_t deviceDescriptor[] = {
00763         DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
00764         DEVICE_DESCRIPTOR,              /* bDescriptorType */
00765         LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
00766         MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
00767         0x00,                           /* bDeviceClass */
00768         0x00,                           /* bDeviceSubClass */
00769         0x00,                           /* bDeviceprotocol */
00770         MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
00771         LSB(VENDOR_ID),                 /* idVendor (LSB) */
00772         MSB(VENDOR_ID),                 /* idVendor (MSB) */
00773         LSB(PRODUCT_ID),                /* idProduct (LSB) */
00774         MSB(PRODUCT_ID),                /* idProduct (MSB) */
00775         LSB(PRODUCT_RELEASE),           /* bcdDevice (LSB) */
00776         MSB(PRODUCT_RELEASE),           /* bcdDevice (MSB) */
00777         STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
00778         STRING_OFFSET_IPRODUCT,         /* iProduct */
00779         STRING_OFFSET_ISERIAL,          /* iSerialNumber */
00780         0x01                            /* bNumConfigurations */
00781     };
00782     return deviceDescriptor;
00783 }
00784 
00785 uint8_t * USBDevice::StringLangidDesc() {
00786     static uint8_t stringLangidDescriptor[] = {
00787         0x04,                                                   /*bLength*/
00788         STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
00789         0x09,0x00,                                              /*bString Lang ID - 0x009 - English*/
00790     };
00791     return stringLangidDescriptor;
00792 }
00793 
00794 uint8_t * USBDevice::StringImanufacturerDesc() {
00795     static uint8_t stringImanufacturerDescriptor[] = {
00796         0x12,                                                   /*bLength*/
00797         STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
00798         'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0,        /*bString iManufacturer - mbed.org*/
00799     };
00800     return stringImanufacturerDescriptor;
00801 }
00802 
00803 uint8_t * USBDevice::StringIserialDesc() {
00804     static uint8_t stringIserialDescriptor[] = {
00805         0x16,                                                           /*bLength*/
00806         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
00807         '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
00808     };
00809     return stringIserialDescriptor;
00810 }
00811 
00812 uint8_t * USBDevice::StringIConfigurationDesc() {
00813     static uint8_t stringIconfigurationDescriptor[] = {
00814         0x06,                                                           /*bLength*/
00815         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
00816         '0',0,'1',0,                                                    /*bString iConfiguration - 01*/
00817     };
00818     return stringIconfigurationDescriptor;
00819 }
00820 
00821 uint8_t * USBDevice::StringIinterfaceDesc() {
00822     static uint8_t stringIinterfaceDescriptor[] = {
00823         0x08,                                                           /*bLength*/
00824         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
00825         'H',0,'I',0,'D',0,                                              /*bString iInterface - HID*/
00826     };
00827     return stringIinterfaceDescriptor;
00828 }
00829 
00830 uint8_t * USBDevice::StringIproductDesc() {
00831     static uint8_t stringIproductDescriptor[] = {
00832         0x16,                                                   /*bLength*/
00833         STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
00834         'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0  /*bString iProduct - Rel Mouse*/
00835     };
00836     return stringIproductDescriptor;
00837 }
00838 
00839 #define DEFAULT_CONFIGURATION (1)
00840 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00841                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
00842                                + (1 * HID_DESCRIPTOR_LENGTH) \
00843                                + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
00844 
00845 uint8_t * USBDevice::ConfigurationDesc() {
00846     static uint8_t configurationDescriptor[] = {
00847         CONFIGURATION_DESCRIPTOR_LENGTH,/* bLength */
00848         CONFIGURATION_DESCRIPTOR,       /* bDescriptorType */
00849         LSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (LSB) */
00850         MSB(TOTAL_DESCRIPTOR_LENGTH),   /* wTotalLength (MSB) */
00851         0x01,                           /* bNumInterfaces */
00852         DEFAULT_CONFIGURATION,          /* bConfigurationValue */
00853         0x00,                           /* iConfiguration */
00854         C_RESERVED | C_SELF_POWERED,    /* bmAttributes */
00855         C_POWER(0),                     /* bMaxPower */
00856 
00857         INTERFACE_DESCRIPTOR_LENGTH,    /* bLength */
00858         INTERFACE_DESCRIPTOR,           /* bDescriptorType */
00859         0x00,                           /* bInterfaceNumber */
00860         0x00,                           /* bAlternateSetting */
00861         0x01,                           /* bNumEndpoints */
00862         HID_CLASS,                      /* bInterfaceClass */
00863         HID_SUBCLASS_NONE,              /* bInterfaceSubClass */
00864         HID_PROTOCOL_NONE,              /* bInterfaceProtocol */
00865         0x00,                           /* iInterface */
00866 
00867         HID_DESCRIPTOR_LENGTH,          /* bLength */
00868         HID_DESCRIPTOR,                 /* bDescriptorType */
00869         LSB(HID_VERSION_1_11),          /* bcdHID (LSB) */
00870         MSB(HID_VERSION_1_11),          /* bcdHID (MSB) */
00871         0x00,                           /* bCountryCode */
00872         0x01,                           /* bNumDescriptors */
00873         REPORT_DESCRIPTOR,              /* bDescriptorType */
00874         LSB(this->ReportDescLength()),    /* wDescriptorLength (LSB) */
00875         MSB(this->ReportDescLength()),    /* wDescriptorLength (MSB) */
00876 
00877         ENDPOINT_DESCRIPTOR_LENGTH,     /* bLength */
00878         ENDPOINT_DESCRIPTOR,            /* bDescriptorType */
00879         PHY_TO_DESC(EPINT_IN),          /* bEndpointAddress */
00880         E_INTERRUPT,                    /* bmAttributes */
00881         LSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (LSB) */
00882         MSB(MAX_PACKET_SIZE_EPINT),     /* wMaxPacketSize (MSB) */
00883         10,                             /* bInterval (milliseconds) */
00884     };
00885     return configurationDescriptor;
00886 }
00887