kekw
Dependencies: mbed C12832_lcd MMA7660
usbhid.cpp
00001 /* usbhid.cpp */ 00002 /* USB HID class device */ 00003 /* Copyright (c) Phil Wright 2008 */ 00004 00005 #include "mbed.h" 00006 #include "usbhid.h" 00007 #include "asciihid.h" 00008 00009 /* Endpoint packet sizes */ 00010 #define MAX_PACKET_SIZE_EP1 (64) 00011 00012 /* HID Class */ 00013 #define HID_CLASS (3) 00014 #define HID_SUBCLASS_NONE (0) 00015 #define HID_PROTOCOL_NONE (0) 00016 #define HID_DESCRIPTOR (33) 00017 #define REPORT_DESCRIPTOR (34) 00018 00019 /* Class requests */ 00020 #define GET_REPORT (0x1) 00021 #define GET_IDLE (0x2) 00022 #define SET_REPORT (0x9) 00023 #define SET_IDLE (0xa) 00024 00025 /* Descriptors */ 00026 unsigned char deviceDescriptor[] = { 00027 0x12, /* bLength */ 00028 DEVICE_DESCRIPTOR, /* bDescriptorType */ 00029 0x00, /* bcdUSB (LSB) */ 00030 0x02, /* bcdUSB (MSB) */ 00031 0x00, /* bDeviceClass */ 00032 0x00, /* bDeviceSubClass */ 00033 0x00, /* bDeviceprotocol */ 00034 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */ 00035 0x28, /* idVendor (LSB) */ 00036 0x0d, /* idVendor (MSB) */ 00037 0x05, /* idProduct (LSB) */ 00038 0x02, /* idProduct (MSB) */ 00039 0x00, /* bcdDevice (LSB) */ 00040 0x00, /* bcdDevice (MSB) */ 00041 0x00, /* iManufacturer */ 00042 0x00, /* iProduct */ 00043 0x00, /* iSerialNumber */ 00044 0x01 /* bNumConfigurations */ 00045 }; 00046 00047 unsigned char configurationDescriptor[] = { 00048 0x09, /* bLength */ 00049 CONFIGURATION_DESCRIPTOR, /* bDescriptorType */ 00050 0x09+0x09+0x09+0x07, /* wTotalLength (LSB) */ 00051 0x00, /* wTotalLength (MSB) */ 00052 0x01, /* bNumInterfaces */ 00053 0x01, /* bConfigurationValue */ 00054 0x00, /* iConfiguration */ 00055 0xc0, /* bmAttributes */ 00056 0x00, /* bMaxPower */ 00057 00058 0x09, /* bLength */ 00059 INTERFACE_DESCRIPTOR, /* bDescriptorType */ 00060 0x00, /* bInterfaceNumber */ 00061 0x00, /* bAlternateSetting */ 00062 0x01, /* bNumEndpoints */ 00063 HID_CLASS, /* bInterfaceClass */ 00064 HID_SUBCLASS_NONE, /* bInterfaceSubClass */ 00065 HID_PROTOCOL_NONE, /* bInterfaceProtocol */ 00066 0x00, /* iInterface */ 00067 00068 0x09, /* bLength */ 00069 HID_DESCRIPTOR, /* bDescriptorType */ 00070 0x11, /* bcdHID (LSB) */ 00071 0x01, /* bcdHID (MSB) */ 00072 0x00, /* bCountryCode */ 00073 0x01, /* bNumDescriptors */ 00074 REPORT_DESCRIPTOR, /* bDescriptorType */ 00075 0x79, /* wDescriptorLength (LSB) */ 00076 0x00, /* wDescriptorLength (MSB) */ 00077 00078 0x07, /* bLength */ 00079 ENDPOINT_DESCRIPTOR, /* bDescriptorType */ 00080 0x81, /* bEndpointAddress */ 00081 0x03, /* bmAttributes */ 00082 MAX_PACKET_SIZE_EP1, /* wMaxPacketSize (LSB) */ 00083 0x00, /* wMaxPacketSize (MSB) */ 00084 0x0a, /* bInterval */ 00085 }; 00086 00087 /* HID Class Report Descriptor */ 00088 /* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes of data as per HID Class standard */ 00089 00090 /* Main items */ 00091 #define INPUT(size) (0x80 | size) 00092 #define OUTPUT(size) (0x90 | size) 00093 #define FEATURE(size) (0xb0 | size) 00094 #define COLLECTION(size) (0xa0 | size) 00095 #define END_COLLECTION(size) (0xc0 | size) 00096 00097 /* Global items */ 00098 #define USAGE_PAGE(size) (0x04 | size) 00099 #define LOGICAL_MIN(size) (0x14 | size) 00100 #define LOGICAL_MAX(size) (0x24 | size) 00101 #define PHYSICAL_MIN(size) (0x34 | size) 00102 #define PHYSICAL_MAX(size) (0x44 | size) 00103 #define UNIT_EXPONENT(size) (0x54 | size) 00104 #define UNIT(size) (0x64 | size) 00105 #define REPORT_SIZE(size) (0x74 | size) 00106 #define REPORT_ID(size) (0x84 | size) 00107 #define REPORT_COUNT(size) (0x94 | size) 00108 #define PUSH(size) (0xa4 | size) 00109 #define POP(size) (0xb4 | size) 00110 00111 /* Local items */ 00112 #define USAGE(size) (0x08 | size) 00113 #define USAGE_MIN(size) (0x18 | size) 00114 #define USAGE_MAX(size) (0x28 | size) 00115 #define DESIGNATOR_INDEX(size) (0x38 | size) 00116 #define DESIGNATOR_MIN(size) (0x48 | size) 00117 #define DESIGNATOR_MAX(size) (0x58 | size) 00118 #define STRING_INDEX(size) (0x78 | size) 00119 #define STRING_MIN(size) (0x88 | size) 00120 #define STRING_MAX(size) (0x98 | size) 00121 #define DELIMITER(size) (0xa8 | size) 00122 00123 #define REPORT_ID_KEYBOARD (1) 00124 #define REPORT_ID_MOUSE (2) 00125 00126 #define MAX_REPORT_SIZE (8) 00127 00128 unsigned char reportDescriptor[] = { 00129 /* Keyboard */ 00130 USAGE_PAGE(1), 0x01, 00131 USAGE(1), 0x06, 00132 COLLECTION(1), 0x01, 00133 REPORT_ID(1), REPORT_ID_KEYBOARD, 00134 USAGE_PAGE(1), 0x07, 00135 USAGE_MIN(1), 0xE0, 00136 USAGE_MAX(1), 0xE7, 00137 LOGICAL_MIN(1), 0x00, 00138 LOGICAL_MAX(1), 0x01, 00139 REPORT_SIZE(1), 0x01, 00140 REPORT_COUNT(1), 0x08, 00141 INPUT(1), 0x02, 00142 REPORT_COUNT(1), 0x01, 00143 REPORT_SIZE(1), 0x08, 00144 INPUT(1), 0x01, 00145 REPORT_COUNT(1), 0x05, 00146 REPORT_SIZE(1), 0x01, 00147 USAGE_PAGE(1), 0x08, 00148 USAGE_MIN(1), 0x01, 00149 USAGE_MAX(1), 0x05, 00150 OUTPUT(1), 0x02, 00151 REPORT_COUNT(1), 0x01, 00152 REPORT_SIZE(1), 0x03, 00153 OUTPUT(1), 0x01, 00154 REPORT_COUNT(1), 0x06, 00155 REPORT_SIZE(1), 0x08, 00156 LOGICAL_MIN(1), 0x00, 00157 LOGICAL_MAX(2), 0xff, 0x00, 00158 USAGE_PAGE(1), 0x07, 00159 USAGE_MIN(1), 0x00, 00160 USAGE_MAX(2), 0xff, 0x00, 00161 INPUT(1), 0x00, 00162 END_COLLECTION(0), 00163 00164 /* Mouse */ 00165 USAGE_PAGE(1), 0x01, 00166 USAGE(1), 0x02, 00167 COLLECTION(1), 0x01, 00168 USAGE(1), 0x01, 00169 COLLECTION(1), 0x00, 00170 REPORT_ID(1), REPORT_ID_MOUSE, 00171 REPORT_COUNT(1), 0x03, 00172 REPORT_SIZE(1), 0x01, 00173 USAGE_PAGE(1), 0x09, 00174 USAGE_MIN(1), 0x1, 00175 USAGE_MAX(1), 0x3, 00176 LOGICAL_MIN(1), 0x00, 00177 LOGICAL_MAX(1), 0x01, 00178 INPUT(1), 0x02, 00179 REPORT_COUNT(1), 0x01, 00180 REPORT_SIZE(1), 0x05, 00181 INPUT(1), 0x01, 00182 REPORT_COUNT(1), 0x03, 00183 REPORT_SIZE(1), 0x08, 00184 USAGE_PAGE(1), 0x01, 00185 USAGE(1), 0x30, 00186 USAGE(1), 0x31, 00187 USAGE(1), 0x38, 00188 LOGICAL_MIN(1), 0x81, 00189 LOGICAL_MAX(1), 0x7f, 00190 INPUT(1), 0x06, 00191 END_COLLECTION(0), 00192 END_COLLECTION(0), 00193 }; 00194 00195 volatile bool complete; 00196 volatile bool configured; 00197 unsigned char outputReport[MAX_REPORT_SIZE]; 00198 00199 usbhid::usbhid() 00200 { 00201 configured = false; 00202 connect(); 00203 } 00204 00205 void usbhid::deviceEventReset() 00206 { 00207 configured = false; 00208 00209 /* Must call base class */ 00210 usbdevice::deviceEventReset(); 00211 } 00212 00213 bool usbhid::requestSetConfiguration(void) 00214 { 00215 bool result; 00216 00217 /* Configure IN interrupt endpoint */ 00218 realiseEndpoint(EP1IN, MAX_PACKET_SIZE_EP1); 00219 enableEndpointEvent(EP1IN); 00220 00221 /* Must call base class */ 00222 result = usbdevice::requestSetConfiguration(); 00223 00224 if (result) 00225 { 00226 /* Now configured */ 00227 configured = true; 00228 } 00229 00230 return result; 00231 } 00232 00233 bool usbhid::requestGetDescriptor(void) 00234 { 00235 bool success = false; 00236 00237 switch (DESCRIPTOR_TYPE(transfer.setup.wValue)) 00238 { 00239 case DEVICE_DESCRIPTOR: 00240 transfer.remaining = sizeof(deviceDescriptor); 00241 transfer.ptr = deviceDescriptor; 00242 transfer.direction = DEVICE_TO_HOST; 00243 success = true; 00244 break; 00245 case CONFIGURATION_DESCRIPTOR: 00246 transfer.remaining = sizeof(configurationDescriptor); 00247 transfer.ptr = configurationDescriptor; 00248 transfer.direction = DEVICE_TO_HOST; 00249 success = true; 00250 break; 00251 case STRING_DESCRIPTOR: 00252 case INTERFACE_DESCRIPTOR: 00253 case ENDPOINT_DESCRIPTOR: 00254 /* TODO: Support is optional, not implemented here */ 00255 break; 00256 case HID_DESCRIPTOR: 00257 transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */ 00258 transfer.ptr = &configurationDescriptor[18]; 00259 transfer.direction = DEVICE_TO_HOST; 00260 success = true; 00261 break; 00262 case REPORT_DESCRIPTOR: 00263 transfer.remaining = sizeof(reportDescriptor); 00264 transfer.ptr = reportDescriptor; 00265 transfer.direction = DEVICE_TO_HOST; 00266 success = true; 00267 break; 00268 default: 00269 break; 00270 } 00271 00272 return success; 00273 } 00274 00275 bool usbhid::requestSetup(void) 00276 { 00277 /* Process class requests */ 00278 bool success = false; 00279 00280 if (transfer.setup.bmRequestType.Type == CLASS_TYPE) 00281 { 00282 switch (transfer.setup.bRequest) 00283 { 00284 case SET_REPORT: 00285 switch (transfer.setup.wValue & 0xff) 00286 { 00287 case REPORT_ID_KEYBOARD: 00288 /* TODO: LED state */ 00289 transfer.remaining = sizeof(outputReport); 00290 transfer.ptr = outputReport; 00291 transfer.direction = HOST_TO_DEVICE; 00292 success = true; 00293 break; 00294 default: 00295 break; 00296 } 00297 break; 00298 default: 00299 break; 00300 } 00301 } 00302 00303 if (success) 00304 { 00305 /* We've handled this request */ 00306 return true; 00307 } 00308 00309 return usbdevice::requestSetup(); 00310 } 00311 00312 bool usbhid::sendInputReport(unsigned char id, unsigned char *data, unsigned char size) 00313 { 00314 /* Send an Input Report */ 00315 /* If data is NULL an all zero report is sent */ 00316 00317 static unsigned char report[MAX_REPORT_SIZE+1]; /* +1 for report ID */ 00318 unsigned char i; 00319 00320 if (size > MAX_REPORT_SIZE) 00321 { 00322 return false; 00323 } 00324 00325 /* Add report ID */ 00326 report[0]=id; 00327 00328 /* Add report data */ 00329 if (data != NULL) 00330 { 00331 for (i=0; i<size; i++) 00332 { 00333 report[i+1] = *data++; 00334 } 00335 } 00336 else 00337 { 00338 for (i=0; i<size; i++) 00339 { 00340 report[i+1] = 0; 00341 } 00342 } 00343 00344 /* Block if not configured */ 00345 while (!configured); 00346 00347 /* Send report */ 00348 complete = false; 00349 disableEvents(); 00350 endpointWrite(EP1IN, report, size+1); /* +1 for report ID */ 00351 enableEvents(); 00352 00353 /* Wait for completion */ 00354 while(!complete && configured); 00355 return true; 00356 } 00357 00358 void usbhid::endpointEventEP1In(void) 00359 { 00360 complete = true; 00361 } 00362 00363 bool usbhid::keyboard(char c) 00364 { 00365 /* Send a simulated keyboard keypress. Returns true if successful. */ 00366 unsigned char report[8]={0,0,0,0,0,0,0,0}; 00367 00368 report[0] = keymap[c].modifier; 00369 report[2] = keymap[c].usage; 00370 00371 /* Key down */ 00372 if (!sendInputReport(REPORT_ID_KEYBOARD, report, 8)) 00373 { 00374 return false; 00375 } 00376 00377 /* Key up */ 00378 if (!sendInputReport(REPORT_ID_KEYBOARD, NULL, 8)) 00379 { 00380 return false; 00381 } 00382 00383 return true; 00384 } 00385 00386 bool usbhid::keyboard(char *string) 00387 { 00388 /* Send a string of characters. Returns true if successful. */ 00389 do { 00390 if (!keyboard(*string++)) 00391 { 00392 return false; 00393 } 00394 } while (*string != '\0'); 00395 00396 return true; 00397 } 00398 00399 bool usbhid::mouse(signed char x, signed char y, unsigned char buttons, signed char wheel) 00400 { 00401 /* Send a simulated mouse event. Returns true if successful. */ 00402 unsigned char report[4]={0,0,0,0}; 00403 00404 report[0] = buttons; 00405 report[1] = x; 00406 report[2] = y; 00407 report[3] = wheel; 00408 00409 if (!sendInputReport(REPORT_ID_MOUSE, report, 4)) 00410 { 00411 return false; 00412 } 00413 00414 return true; 00415 }
Generated on Wed Jul 20 2022 10:46:19 by 1.7.2