Angel David Yaguana Hernandez / USBDevice2

Dependents:   USB_CDC_MSD_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHID.cpp Source File

USBHID.cpp

00001 // USBHID.c
00002 // Human Interface Device (HID) class
00003 // Copyright (c) 2011 ARM Limited. All rights reserved.
00004 
00005 #include "stdint.h"
00006 #include "USBBusInterface.h"
00007 #include "USBHID.h"
00008 
00009 
00010 USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)
00011 {
00012     output_length = output_report_length;
00013     input_length = input_report_length;
00014     if(connect) {
00015         USBDevice::connect();
00016     }
00017 }
00018 
00019 
00020 bool USBHID::send(HID_REPORT *report)
00021 {
00022     return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00023 }
00024 
00025 bool USBHID::sendNB(HID_REPORT *report)
00026 {
00027     return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00028 }
00029 
00030 
00031 bool USBHID::read(HID_REPORT *report)
00032 {
00033     uint16_t bytesRead = 0;
00034     bool result;
00035     result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00036     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
00037         return false;
00038     report->length = bytesRead;
00039     return result;
00040 }
00041 
00042 
00043 bool USBHID::readNB(HID_REPORT *report)
00044 {
00045     uint16_t bytesRead = 0;
00046     bool result;
00047     result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00048     report->length = bytesRead;
00049     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
00050         return false;
00051     return result;
00052 }
00053 
00054 
00055 uint16_t USBHID::reportDescLength() {
00056     reportDesc();
00057     return reportLength;
00058 }
00059 
00060 
00061 
00062 //
00063 //  Route callbacks from lower layers to class(es)
00064 //
00065 
00066 
00067 // Called in ISR context
00068 // Called by USBDevice on Endpoint0 request
00069 // This is used to handle extensions to standard requests
00070 // and class specific requests
00071 // Return true if class handles this request
00072 bool USBHID::USBCallback_request() {
00073     bool success = false;
00074     CONTROL_TRANSFER * transfer = getTransferPtr();
00075     uint8_t *hidDescriptor;
00076 
00077     // Process additional standard requests
00078 
00079     if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
00080     {
00081         switch (transfer->setup.bRequest)
00082         {
00083             case GET_DESCRIPTOR:
00084                 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
00085                 {
00086                     case REPORT_DESCRIPTOR:
00087                         if ((reportDesc() != NULL) \
00088                             && (reportDescLength() != 0))
00089                         {
00090                             transfer->remaining = reportDescLength();
00091                             transfer->ptr = reportDesc();
00092                             transfer->direction = DEVICE_TO_HOST;
00093                             success = true;
00094                         }
00095                         break;
00096                     case HID_DESCRIPTOR:
00097                             // Find the HID descriptor, after the configuration descriptor
00098                             hidDescriptor = findDescriptor(HID_DESCRIPTOR);
00099                             if (hidDescriptor != NULL)
00100                             {
00101                                 transfer->remaining = HID_DESCRIPTOR_LENGTH;
00102                                 transfer->ptr = hidDescriptor;
00103                                 transfer->direction = DEVICE_TO_HOST;
00104                                 success = true;
00105                             }
00106                             break;
00107                      
00108                     default:
00109                         break;
00110                 }
00111                 break;
00112             default:
00113                 break;
00114         }
00115     }
00116 
00117     // Process class-specific requests
00118 
00119     if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
00120     {
00121         switch (transfer->setup.bRequest)
00122         {
00123              case SET_REPORT:
00124                 // First byte will be used for report ID
00125                 outputReport.data[0] = transfer->setup.wValue & 0xff;
00126                 outputReport.length = transfer->setup.wLength + 1;
00127 
00128                 transfer->remaining = sizeof(outputReport.data) - 1;
00129                 transfer->ptr = &outputReport.data[1];
00130                 transfer->direction = HOST_TO_DEVICE;
00131                 transfer->notify = true;
00132                 success = true;
00133             default:
00134                 break;
00135         }
00136     }
00137 
00138     return success;
00139 }
00140 
00141 
00142 #define DEFAULT_CONFIGURATION (1)
00143 
00144 
00145 // Called in ISR context
00146 // Set configuration. Return false if the
00147 // configuration is not supported
00148 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
00149     if (configuration != DEFAULT_CONFIGURATION) {
00150         return false;
00151     }
00152 
00153     // Configure endpoints > 0
00154     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
00155     addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00156 
00157     // We activate the endpoint to be able to recceive data
00158     readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00159     return true;
00160 }
00161 
00162 
00163 uint8_t * USBHID::stringIinterfaceDesc() {
00164     static uint8_t stringIinterfaceDescriptor[] = {
00165         0x08,               //bLength
00166         STRING_DESCRIPTOR,  //bDescriptorType 0x03
00167         'H',0,'I',0,'D',0,  //bString iInterface - HID
00168     };
00169     return stringIinterfaceDescriptor;
00170 }
00171 
00172 uint8_t * USBHID::stringIproductDesc() {
00173     static uint8_t stringIproductDescriptor[] = {
00174         0x16,                                                       //bLength
00175         STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
00176         'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
00177     };
00178     return stringIproductDescriptor;
00179 }
00180 
00181 
00182 
00183 uint8_t * USBHID::reportDesc() {
00184     static uint8_t reportDescriptor[] = {
00185         0x06, LSB(0xFFAB), MSB(0xFFAB),
00186         0x0A, LSB(0x0200), MSB(0x0200),
00187         0xA1, 0x01,         // Collection 0x01
00188         0x75, 0x08,         // report size = 8 bits
00189         0x15, 0x00,         // logical minimum = 0
00190         0x26, 0xFF, 0x00,   // logical maximum = 255
00191         0x95, input_length,           // report count
00192         0x09, 0x01,         // usage
00193         0x81, 0x02,         // Input (array)
00194         0x95, output_length,           // report count
00195         0x09, 0x02,         // usage
00196         0x91, 0x02,         // Output (array)
00197         0xC0                // end collection
00198 
00199     };
00200     reportLength = sizeof(reportDescriptor);
00201     return reportDescriptor;
00202 }
00203 
00204 #define DEFAULT_CONFIGURATION (1)
00205 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00206                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
00207                                + (1 * HID_DESCRIPTOR_LENGTH) \
00208                                + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
00209 
00210 uint8_t * USBHID::configurationDesc() {
00211     static uint8_t configurationDescriptor[] = {
00212         CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
00213         CONFIGURATION_DESCRIPTOR,       // bDescriptorType
00214         LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
00215         MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
00216         0x01,                           // bNumInterfaces
00217         DEFAULT_CONFIGURATION,          // bConfigurationValue
00218         0x00,                           // iConfiguration
00219         C_RESERVED | C_SELF_POWERED,    // bmAttributes
00220         C_POWER(0),                     // bMaxPower
00221 
00222         INTERFACE_DESCRIPTOR_LENGTH,    // bLength
00223         INTERFACE_DESCRIPTOR,           // bDescriptorType
00224         0x00,                           // bInterfaceNumber
00225         0x00,                           // bAlternateSetting
00226         0x02,                           // bNumEndpoints
00227         HID_CLASS,                      // bInterfaceClass
00228         HID_SUBCLASS_NONE,              // bInterfaceSubClass
00229         HID_PROTOCOL_NONE,              // bInterfaceProtocol
00230         0x00,                           // iInterface
00231 
00232         HID_DESCRIPTOR_LENGTH,          // bLength
00233         HID_DESCRIPTOR,                 // bDescriptorType
00234         LSB(HID_VERSION_1_11),          // bcdHID (LSB)
00235         MSB(HID_VERSION_1_11),          // bcdHID (MSB)
00236         0x00,                           // bCountryCode
00237         0x01,                           // bNumDescriptors
00238         REPORT_DESCRIPTOR,              // bDescriptorType
00239         LSB(this->reportDescLength()),  // wDescriptorLength (LSB)
00240         MSB(this->reportDescLength()),  // wDescriptorLength (MSB)
00241 
00242         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00243         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00244         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
00245         E_INTERRUPT,                    // bmAttributes
00246         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00247         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00248         1,                             // bInterval (milliseconds)
00249 
00250         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00251         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00252         PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
00253         E_INTERRUPT,                    // bmAttributes
00254         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00255         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00256         1,                             // bInterval (milliseconds)
00257     };
00258     return configurationDescriptor;
00259 }