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 // if readEP_NB did not succeed, does not issue a readStart 00063 if (!result) 00064 return false; 00065 report->length = bytesRead; 00066 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE)) 00067 return false; 00068 return result; 00069 } 00070 00071 00072 uint16_t USBHID::reportDescLength() { 00073 reportDesc(); 00074 return reportLength; 00075 } 00076 00077 00078 00079 // 00080 // Route callbacks from lower layers to class(es) 00081 // 00082 00083 00084 // Called in ISR context 00085 // Called by USBDevice on Endpoint0 request 00086 // This is used to handle extensions to standard requests 00087 // and class specific requests 00088 // Return true if class handles this request 00089 bool USBHID::USBCallback_request() { 00090 bool success = false; 00091 CONTROL_TRANSFER * transfer = getTransferPtr(); 00092 uint8_t *hidDescriptor; 00093 00094 // Process additional standard requests 00095 00096 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) 00097 { 00098 switch (transfer->setup.bRequest) 00099 { 00100 case GET_DESCRIPTOR: 00101 switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) 00102 { 00103 case REPORT_DESCRIPTOR: 00104 if ((reportDesc() != NULL) \ 00105 && (reportDescLength() != 0)) 00106 { 00107 transfer->remaining = reportDescLength(); 00108 transfer->ptr = reportDesc(); 00109 transfer->direction = DEVICE_TO_HOST; 00110 success = true; 00111 } 00112 break; 00113 case HID_DESCRIPTOR: 00114 // Find the HID descriptor, after the configuration descriptor 00115 hidDescriptor = findDescriptor(HID_DESCRIPTOR); 00116 if (hidDescriptor != NULL) 00117 { 00118 transfer->remaining = HID_DESCRIPTOR_LENGTH; 00119 transfer->ptr = hidDescriptor; 00120 transfer->direction = DEVICE_TO_HOST; 00121 success = true; 00122 } 00123 break; 00124 00125 default: 00126 break; 00127 } 00128 break; 00129 default: 00130 break; 00131 } 00132 } 00133 00134 // Process class-specific requests 00135 00136 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) 00137 { 00138 switch (transfer->setup.bRequest) 00139 { 00140 case SET_REPORT: 00141 // First byte will be used for report ID 00142 outputReport.data[0] = transfer->setup.wValue & 0xff; 00143 outputReport.length = transfer->setup.wLength + 1; 00144 00145 transfer->remaining = sizeof(outputReport.data) - 1; 00146 transfer->ptr = &outputReport.data[1]; 00147 transfer->direction = HOST_TO_DEVICE; 00148 transfer->notify = true; 00149 success = true; 00150 default: 00151 break; 00152 } 00153 } 00154 00155 return success; 00156 } 00157 00158 00159 #define DEFAULT_CONFIGURATION (1) 00160 00161 00162 // Called in ISR context 00163 // Set configuration. Return false if the 00164 // configuration is not supported 00165 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) { 00166 if (configuration != DEFAULT_CONFIGURATION) { 00167 return false; 00168 } 00169 00170 // Configure endpoints > 0 00171 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); 00172 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT); 00173 00174 // We activate the endpoint to be able to recceive data 00175 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); 00176 return true; 00177 } 00178 00179 00180 uint8_t * USBHID::stringIinterfaceDesc() { 00181 static uint8_t stringIinterfaceDescriptor[] = { 00182 0x08, //bLength 00183 STRING_DESCRIPTOR, //bDescriptorType 0x03 00184 'H',0,'I',0,'D',0, //bString iInterface - HID 00185 }; 00186 return stringIinterfaceDescriptor; 00187 } 00188 00189 //MODTRONIX - had to change following function as mentioned by program description: 00190 //See http://mbed.org/users/dudmuck/code/hid_test/ 00191 //The pre-existing PC GUI checks for product device name of USB device to match a specific string of text. 00192 //After you import this program, you will have your own private copy of USB HID driver. 00193 //Edit the file USBDevice -> USBHID -> USBHID.cpp: 00194 //uint8_t * USBHID::stringIproductDesc() { 00195 // static uint8_t stringIproductDescriptor[] = { 00196 // 0x16, //bLength 00197 // STRING_DESCRIPTOR, //bDescriptorType 0x03 00198 // 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device 00199 // }; 00200 // return stringIproductDescriptor; 00201 //} 00202 uint8_t * USBHID::stringIproductDesc() { 00203 static uint8_t stringIproductDescriptor[] = { 00204 0x18, //bLength 00205 STRING_DESCRIPTOR, //bDescriptorType 0x03 00206 'S',0,'X',0,'1',0,'2',0,'x',0,'x',0,'E',0,'i',0,'g',0,'e',0,'r',0 //bString iProduct - HID device 00207 }; 00208 return stringIproductDescriptor; 00209 } 00210 00211 uint8_t * USBHID::reportDesc() { 00212 static uint8_t reportDescriptor[] = { 00213 0x06, LSB(0xFFAB), MSB(0xFFAB), 00214 0x0A, LSB(0x0200), MSB(0x0200), 00215 0xA1, 0x01, // Collection 0x01 00216 0x75, 0x08, // report size = 8 bits 00217 0x15, 0x00, // logical minimum = 0 00218 0x26, 0xFF, 0x00, // logical maximum = 255 00219 0x95, input_length, // report count 00220 0x09, 0x01, // usage 00221 0x81, 0x02, // Input (array) 00222 0x95, output_length,// report count 00223 0x09, 0x02, // usage 00224 0x91, 0x02, // Output (array) 00225 0xC0 // end collection 00226 00227 }; 00228 reportLength = sizeof(reportDescriptor); 00229 return reportDescriptor; 00230 } 00231 00232 #define DEFAULT_CONFIGURATION (1) 00233 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00234 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00235 + (1 * HID_DESCRIPTOR_LENGTH) \ 00236 + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) 00237 00238 uint8_t * USBHID::configurationDesc() { 00239 static uint8_t configurationDescriptor[] = { 00240 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength 00241 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00242 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00243 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00244 0x01, // bNumInterfaces 00245 DEFAULT_CONFIGURATION, // bConfigurationValue 00246 0x00, // iConfiguration 00247 C_RESERVED | C_SELF_POWERED, // bmAttributes 00248 C_POWER(0), // bMaxPower 00249 00250 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00251 INTERFACE_DESCRIPTOR, // bDescriptorType 00252 0x00, // bInterfaceNumber 00253 0x00, // bAlternateSetting 00254 0x02, // bNumEndpoints 00255 HID_CLASS, // bInterfaceClass 00256 HID_SUBCLASS_NONE, // bInterfaceSubClass 00257 HID_PROTOCOL_NONE, // bInterfaceProtocol 00258 0x00, // iInterface 00259 00260 HID_DESCRIPTOR_LENGTH, // bLength 00261 HID_DESCRIPTOR, // bDescriptorType 00262 LSB(HID_VERSION_1_11), // bcdHID (LSB) 00263 MSB(HID_VERSION_1_11), // bcdHID (MSB) 00264 0x00, // bCountryCode 00265 0x01, // bNumDescriptors 00266 REPORT_DESCRIPTOR, // bDescriptorType 00267 (uint8_t)(LSB(this->reportDescLength())), // wDescriptorLength (LSB) 00268 (uint8_t)(MSB(this->reportDescLength())), // wDescriptorLength (MSB) 00269 00270 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00271 ENDPOINT_DESCRIPTOR, // bDescriptorType 00272 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00273 E_INTERRUPT, // bmAttributes 00274 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00275 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00276 1, // bInterval (milliseconds) 00277 00278 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00279 ENDPOINT_DESCRIPTOR, // bDescriptorType 00280 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress 00281 E_INTERRUPT, // bmAttributes 00282 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00283 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00284 1, // bInterval (milliseconds) 00285 }; 00286 return configurationDescriptor; 00287 }
Generated on Wed Jul 13 2022 18:14:56 by
1.7.2
