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 = (uint8_t*)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 const uint8_t * USBHID::stringIinterfaceDesc() { 00181 static const 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 const uint8_t * USBHID::stringIproductDesc() { 00190 static const 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 const uint8_t * USBHID::reportDesc() { 00201 uint8_t reportDescriptorTemp[] = { 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 MBED_ASSERT(sizeof(reportDescriptorTemp) == sizeof(reportDescriptor)); 00222 memcpy(reportDescriptor, reportDescriptorTemp, sizeof(reportDescriptor)); 00223 return reportDescriptor; 00224 } 00225 00226 #define DEFAULT_CONFIGURATION (1) 00227 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00228 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00229 + (1 * HID_DESCRIPTOR_LENGTH) \ 00230 + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) 00231 00232 const uint8_t * USBHID::configurationDesc() { 00233 uint8_t configurationDescriptorTemp[] = { 00234 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength 00235 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00236 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00237 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00238 0x01, // bNumInterfaces 00239 DEFAULT_CONFIGURATION, // bConfigurationValue 00240 0x00, // iConfiguration 00241 C_RESERVED | C_SELF_POWERED, // bmAttributes 00242 C_POWER(0), // bMaxPower 00243 00244 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00245 INTERFACE_DESCRIPTOR, // bDescriptorType 00246 0x00, // bInterfaceNumber 00247 0x00, // bAlternateSetting 00248 0x02, // bNumEndpoints 00249 HID_CLASS, // bInterfaceClass 00250 HID_SUBCLASS_NONE, // bInterfaceSubClass 00251 HID_PROTOCOL_NONE, // bInterfaceProtocol 00252 0x00, // iInterface 00253 00254 HID_DESCRIPTOR_LENGTH, // bLength 00255 HID_DESCRIPTOR, // bDescriptorType 00256 LSB(HID_VERSION_1_11), // bcdHID (LSB) 00257 MSB(HID_VERSION_1_11), // bcdHID (MSB) 00258 0x00, // bCountryCode 00259 0x01, // bNumDescriptors 00260 REPORT_DESCRIPTOR, // bDescriptorType 00261 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) 00262 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) 00263 00264 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00265 ENDPOINT_DESCRIPTOR, // bDescriptorType 00266 PHY_TO_DESC(EPINT_IN), // 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 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00273 ENDPOINT_DESCRIPTOR, // bDescriptorType 00274 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress 00275 E_INTERRUPT, // bmAttributes 00276 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00277 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00278 1, // bInterval (milliseconds) 00279 }; 00280 MBED_ASSERT(sizeof(configurationDescriptorTemp) == sizeof(configurationDescriptor)); 00281 memcpy(configurationDescriptor, configurationDescriptorTemp, sizeof(configurationDescriptor)); 00282 return configurationDescriptor; 00283 }
Generated on Tue Jul 12 2022 14:25:16 by
