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