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 //////// for PS3 magic bytes 00024 unsigned char magic_init_bytes[] = {0x21, 0x26, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00}; // PS3 will request these bytes as a class type report 0x0300 00025 //////// 00026 00027 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) 00028 { 00029 output_length = output_report_length; 00030 input_length = input_report_length; 00031 if(connect) { 00032 USBDevice::connect(); 00033 } 00034 } 00035 00036 00037 bool USBHID::send(HID_REPORT *report) 00038 { 00039 return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE); 00040 } 00041 00042 bool USBHID::sendNB(HID_REPORT *report) 00043 { 00044 return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE); 00045 } 00046 00047 00048 bool USBHID::read(HID_REPORT *report) 00049 { 00050 uint32_t bytesRead = 0; 00051 bool result; 00052 result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE); 00053 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE)) 00054 return false; 00055 report->length = bytesRead; 00056 return result; 00057 } 00058 00059 00060 bool USBHID::readNB(HID_REPORT *report) 00061 { 00062 uint32_t bytesRead = 0; 00063 bool result; 00064 result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE); 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 00130 default: 00131 break; 00132 } 00133 } 00134 00135 // Process class-specific requests 00136 00137 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) 00138 { 00139 switch (transfer->setup.bRequest) 00140 { 00141 case SET_REPORT: 00142 // First byte will be used for report ID 00143 outputReport.data[0] = transfer->setup.wValue & 0xff; 00144 outputReport.length = transfer->setup.wLength + 1; 00145 00146 transfer->remaining = sizeof(outputReport.data) - 1; 00147 transfer->ptr = &outputReport.data[1]; 00148 transfer->direction = HOST_TO_DEVICE; 00149 transfer->notify = true; 00150 success = true; 00151 //////// for PS3 magic bytes 00152 case GET_REPORT: 00153 switch (transfer->setup.wValue & 0xffff) 00154 { 00155 case 0x0300: //vendor specific request 00156 00157 transfer->ptr = (unsigned char*)magic_init_bytes; 00158 transfer->remaining = sizeof(magic_init_bytes); 00159 transfer->direction = DEVICE_TO_HOST; 00160 success = true; 00161 00162 break; 00163 default: 00164 break; 00165 } 00166 break; 00167 //////// 00168 00169 default: 00170 break; 00171 } 00172 } 00173 00174 return success; 00175 } 00176 00177 00178 #define DEFAULT_CONFIGURATION (1) 00179 00180 00181 // Called in ISR context 00182 // Set configuration. Return false if the 00183 // configuration is not supported 00184 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) { 00185 if (configuration != DEFAULT_CONFIGURATION) { 00186 return false; 00187 } 00188 00189 // Configure endpoints > 0 00190 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); 00191 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT); 00192 00193 // We activate the endpoint to be able to recceive data 00194 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); 00195 return true; 00196 } 00197 00198 00199 uint8_t * USBHID::stringIinterfaceDesc() { 00200 static uint8_t stringIinterfaceDescriptor[] = { 00201 0x08, //bLength 00202 STRING_DESCRIPTOR, //bDescriptorType 0x03 00203 'H',0,'I',0,'D',0, //bString iInterface - HID 00204 }; 00205 return stringIinterfaceDescriptor; 00206 } 00207 00208 uint8_t * USBHID::stringIproductDesc() { 00209 static uint8_t stringIproductDescriptor[] = { 00210 0x16, //bLength 00211 STRING_DESCRIPTOR, //bDescriptorType 0x03 00212 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device 00213 }; 00214 return stringIproductDescriptor; 00215 } 00216 00217 00218 00219 uint8_t * USBHID::reportDesc() { 00220 static uint8_t reportDescriptor[] = { 00221 0x06, LSB(0xFFAB), MSB(0xFFAB), 00222 0x0A, LSB(0x0200), MSB(0x0200), 00223 0xA1, 0x01, // Collection 0x01 00224 0x75, 0x08, // report size = 8 bits 00225 0x15, 0x00, // logical minimum = 0 00226 0x26, 0xFF, 0x00, // logical maximum = 255 00227 0x95, input_length, // report count 00228 0x09, 0x01, // usage 00229 0x81, 0x02, // Input (array) 00230 0x95, output_length, // report count 00231 0x09, 0x02, // usage 00232 0x91, 0x02, // Output (array) 00233 0xC0 // end collection 00234 00235 }; 00236 reportLength = sizeof(reportDescriptor); 00237 return reportDescriptor; 00238 } 00239 00240 #define DEFAULT_CONFIGURATION (1) 00241 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00242 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00243 + (1 * HID_DESCRIPTOR_LENGTH) \ 00244 + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) 00245 00246 uint8_t * USBHID::configurationDesc() { 00247 static uint8_t configurationDescriptor[] = { 00248 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength 00249 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00250 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00251 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00252 0x01, // bNumInterfaces 00253 DEFAULT_CONFIGURATION, // bConfigurationValue 00254 0x00, // iConfiguration 00255 C_RESERVED | C_SELF_POWERED, // bmAttributes 00256 C_POWER(0), // bMaxPower 00257 00258 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00259 INTERFACE_DESCRIPTOR, // bDescriptorType 00260 0x00, // bInterfaceNumber 00261 0x00, // bAlternateSetting 00262 0x02, // bNumEndpoints 00263 HID_CLASS, // bInterfaceClass 00264 HID_SUBCLASS_NONE, // bInterfaceSubClass 00265 HID_PROTOCOL_NONE, // bInterfaceProtocol 00266 0x00, // iInterface 00267 00268 HID_DESCRIPTOR_LENGTH, // bLength 00269 HID_DESCRIPTOR, // bDescriptorType 00270 LSB(HID_VERSION_1_11), // bcdHID (LSB) 00271 MSB(HID_VERSION_1_11), // bcdHID (MSB) 00272 0x00, // bCountryCode 00273 0x01, // bNumDescriptors 00274 REPORT_DESCRIPTOR, // bDescriptorType 00275 LSB(this->reportDescLength()), // wDescriptorLength (LSB) 00276 MSB(this->reportDescLength()), // wDescriptorLength (MSB) 00277 00278 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00279 ENDPOINT_DESCRIPTOR, // bDescriptorType 00280 PHY_TO_DESC(EPINT_IN), // 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 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00287 ENDPOINT_DESCRIPTOR, // bDescriptorType 00288 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress 00289 E_INTERRUPT, // bmAttributes 00290 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00291 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00292 1, // bInterval (milliseconds) 00293 }; 00294 return configurationDescriptor; 00295 }
Generated on Wed Jul 13 2022 03:25:45 by
1.7.2
