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 0x06, LSB(0xFFAB), MSB(0xFFAB), 00203 0x0A, LSB(0x0200), MSB(0x0200), 00204 0xA1, 0x01, // Collection 0x01 00205 0x75, 0x08, // report size = 8 bits 00206 0x15, 0x00, // logical minimum = 0 00207 0x26, 0xFF, 0x00, // logical maximum = 255 00208 0x95, input_length, // report count 00209 0x09, 0x01, // usage 00210 0x81, 0x02, // Input (array) 00211 0x95, output_length,// report count 00212 0x09, 0x02, // usage 00213 0x91, 0x02, // Output (array) 00214 0xC0 // end collection 00215 00216 }; 00217 reportLength = sizeof(reportDescriptor); 00218 return reportDescriptor; 00219 } 00220 00221 #define DEFAULT_CONFIGURATION (1) 00222 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00223 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00224 + (1 * HID_DESCRIPTOR_LENGTH) \ 00225 + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) 00226 00227 uint8_t * USBHID::configurationDesc() { 00228 static uint8_t configurationDescriptor[] = { 00229 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength 00230 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00231 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00232 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00233 0x01, // bNumInterfaces 00234 DEFAULT_CONFIGURATION, // bConfigurationValue 00235 0x00, // iConfiguration 00236 C_RESERVED | C_SELF_POWERED, // bmAttributes 00237 C_POWER(0), // bMaxPower 00238 00239 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00240 INTERFACE_DESCRIPTOR, // bDescriptorType 00241 0x00, // bInterfaceNumber 00242 0x00, // bAlternateSetting 00243 0x02, // bNumEndpoints 00244 HID_CLASS, // bInterfaceClass 00245 HID_SUBCLASS_NONE, // bInterfaceSubClass 00246 HID_PROTOCOL_NONE, // bInterfaceProtocol 00247 0x00, // iInterface 00248 00249 HID_DESCRIPTOR_LENGTH, // bLength 00250 HID_DESCRIPTOR, // bDescriptorType 00251 LSB(HID_VERSION_1_11), // bcdHID (LSB) 00252 MSB(HID_VERSION_1_11), // bcdHID (MSB) 00253 0x00, // bCountryCode 00254 0x01, // bNumDescriptors 00255 REPORT_DESCRIPTOR, // bDescriptorType 00256 (uint8_t)(LSB(this->reportDescLength())), // wDescriptorLength (LSB) 00257 (uint8_t)(MSB(this->reportDescLength())), // wDescriptorLength (MSB) 00258 00259 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00260 ENDPOINT_DESCRIPTOR, // bDescriptorType 00261 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00262 E_INTERRUPT, // bmAttributes 00263 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00264 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00265 1, // bInterval (milliseconds) 00266 00267 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00268 ENDPOINT_DESCRIPTOR, // bDescriptorType 00269 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress 00270 E_INTERRUPT, // bmAttributes 00271 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00272 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00273 1, // bInterval (milliseconds) 00274 }; 00275 return configurationDescriptor; 00276 }
Generated on Tue Jul 12 2022 17:34:59 by
