USBMOUSE

Dependents:   ESD_Project_USBMouse

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHID.cpp Source File

USBHID.cpp

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