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 /* 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 uint8_t * USBHID::stringIproductDesc() { 00190 static uint8_t stringIproductDescriptor[] = { 00191 0x16, //bLength 00192 STRING_DESCRIPTOR, //bDescriptorType 0x03 00193 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device 00194 }; 00195 return stringIproductDescriptor; 00196 } 00197 00198 00199 00200 uint8_t * USBHID::reportDesc() { 00201 static uint8_t reportDescriptor[] = { 00202 USAGE_PAGE(2), LSB(0xFFAB), MSB(0xFFAB), 00203 USAGE(2), LSB(0x0200), MSB(0x0200), 00204 COLLECTION(1), 0x01, // Collection (Application) 00205 00206 REPORT_SIZE(1), 0x08, // 8 bits 00207 LOGICAL_MINIMUM(1), 0x00, 00208 LOGICAL_MAXIMUM(1), 0xFF, 00209 00210 REPORT_COUNT(1), input_length, 00211 USAGE(1), 0x01, 00212 INPUT(1), 0x02, // Data, Var, Abs 00213 00214 REPORT_COUNT(1), output_length, 00215 USAGE(1), 0x02, 00216 OUTPUT(1), 0x02, // Data, Var, Abs 00217 00218 END_COLLECTION(0), 00219 }; 00220 reportLength = sizeof(reportDescriptor); 00221 return reportDescriptor; 00222 } 00223 00224 #define DEFAULT_CONFIGURATION (1) 00225 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00226 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00227 + (1 * HID_DESCRIPTOR_LENGTH) \ 00228 + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) 00229 00230 uint8_t * USBHID::configurationDesc() { 00231 static uint8_t configurationDescriptor[] = { 00232 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength 00233 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00234 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00235 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00236 0x01, // bNumInterfaces 00237 DEFAULT_CONFIGURATION, // bConfigurationValue 00238 0x00, // iConfiguration 00239 C_RESERVED | C_SELF_POWERED, // bmAttributes 00240 C_POWER(0), // bMaxPower 00241 00242 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00243 INTERFACE_DESCRIPTOR, // bDescriptorType 00244 0x00, // bInterfaceNumber 00245 0x00, // bAlternateSetting 00246 0x02, // bNumEndpoints 00247 HID_CLASS, // bInterfaceClass 00248 HID_SUBCLASS_NONE, // bInterfaceSubClass 00249 HID_PROTOCOL_NONE, // bInterfaceProtocol 00250 0x00, // iInterface 00251 00252 HID_DESCRIPTOR_LENGTH, // bLength 00253 HID_DESCRIPTOR, // bDescriptorType 00254 LSB(HID_VERSION_1_11), // bcdHID (LSB) 00255 MSB(HID_VERSION_1_11), // bcdHID (MSB) 00256 0x00, // bCountryCode 00257 0x01, // bNumDescriptors 00258 REPORT_DESCRIPTOR, // bDescriptorType 00259 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) 00260 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) 00261 00262 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00263 ENDPOINT_DESCRIPTOR, // bDescriptorType 00264 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00265 E_INTERRUPT, // bmAttributes 00266 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00267 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00268 1, // bInterval (milliseconds) 00269 00270 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00271 ENDPOINT_DESCRIPTOR, // bDescriptorType 00272 PHY_TO_DESC(EPINT_OUT), // 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 return configurationDescriptor; 00279 }
Generated on Thu Jul 14 2022 14:36:24 by
