Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Wed Jul 13 2022 13:59:01 by
1.7.2