USBMouse Example

Dependencies:   mbed

Committer:
simon
Date:
Wed Apr 07 13:42:47 2010 +0000
Revision:
1:eb68149218fd

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 1:eb68149218fd 1 /* usbhid.cpp */
simon 1:eb68149218fd 2 /* USB HID class device */
simon 1:eb68149218fd 3 /* Copyright (c) Phil Wright 2008 */
simon 1:eb68149218fd 4
simon 1:eb68149218fd 5 #include "mbed.h"
simon 1:eb68149218fd 6 #include "usbhid.h"
simon 1:eb68149218fd 7 #include "asciihid.h"
simon 1:eb68149218fd 8
simon 1:eb68149218fd 9 /* Endpoint packet sizes */
simon 1:eb68149218fd 10 #define MAX_PACKET_SIZE_EP1 (64)
simon 1:eb68149218fd 11
simon 1:eb68149218fd 12 /* HID Class */
simon 1:eb68149218fd 13 #define HID_CLASS (3)
simon 1:eb68149218fd 14 #define HID_SUBCLASS_NONE (0)
simon 1:eb68149218fd 15 #define HID_PROTOCOL_NONE (0)
simon 1:eb68149218fd 16 #define HID_DESCRIPTOR (33)
simon 1:eb68149218fd 17 #define REPORT_DESCRIPTOR (34)
simon 1:eb68149218fd 18
simon 1:eb68149218fd 19 /* Class requests */
simon 1:eb68149218fd 20 #define GET_REPORT (0x1)
simon 1:eb68149218fd 21 #define GET_IDLE (0x2)
simon 1:eb68149218fd 22 #define SET_REPORT (0x9)
simon 1:eb68149218fd 23 #define SET_IDLE (0xa)
simon 1:eb68149218fd 24
simon 1:eb68149218fd 25 /* Descriptors */
simon 1:eb68149218fd 26 unsigned char deviceDescriptor[] = {
simon 1:eb68149218fd 27 0x12, /* bLength */
simon 1:eb68149218fd 28 DEVICE_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 29 0x00, /* bcdUSB (LSB) */
simon 1:eb68149218fd 30 0x02, /* bcdUSB (MSB) */
simon 1:eb68149218fd 31 0x00, /* bDeviceClass */
simon 1:eb68149218fd 32 0x00, /* bDeviceSubClass */
simon 1:eb68149218fd 33 0x00, /* bDeviceprotocol */
simon 1:eb68149218fd 34 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
simon 1:eb68149218fd 35 0x28, /* idVendor (LSB) */
simon 1:eb68149218fd 36 0x0d, /* idVendor (MSB) */
simon 1:eb68149218fd 37 0x05, /* idProduct (LSB) */
simon 1:eb68149218fd 38 0x02, /* idProduct (MSB) */
simon 1:eb68149218fd 39 0x00, /* bcdDevice (LSB) */
simon 1:eb68149218fd 40 0x00, /* bcdDevice (MSB) */
simon 1:eb68149218fd 41 0x00, /* iManufacturer */
simon 1:eb68149218fd 42 0x00, /* iProduct */
simon 1:eb68149218fd 43 0x00, /* iSerialNumber */
simon 1:eb68149218fd 44 0x01 /* bNumConfigurations */
simon 1:eb68149218fd 45 };
simon 1:eb68149218fd 46
simon 1:eb68149218fd 47 unsigned char configurationDescriptor[] = {
simon 1:eb68149218fd 48 0x09, /* bLength */
simon 1:eb68149218fd 49 CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 50 0x09+0x09+0x09+0x07, /* wTotalLength (LSB) */
simon 1:eb68149218fd 51 0x00, /* wTotalLength (MSB) */
simon 1:eb68149218fd 52 0x01, /* bNumInterfaces */
simon 1:eb68149218fd 53 0x01, /* bConfigurationValue */
simon 1:eb68149218fd 54 0x00, /* iConfiguration */
simon 1:eb68149218fd 55 0xc0, /* bmAttributes */
simon 1:eb68149218fd 56 0x00, /* bMaxPower */
simon 1:eb68149218fd 57
simon 1:eb68149218fd 58 0x09, /* bLength */
simon 1:eb68149218fd 59 INTERFACE_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 60 0x00, /* bInterfaceNumber */
simon 1:eb68149218fd 61 0x00, /* bAlternateSetting */
simon 1:eb68149218fd 62 0x01, /* bNumEndpoints */
simon 1:eb68149218fd 63 HID_CLASS, /* bInterfaceClass */
simon 1:eb68149218fd 64 HID_SUBCLASS_NONE, /* bInterfaceSubClass */
simon 1:eb68149218fd 65 HID_PROTOCOL_NONE, /* bInterfaceProtocol */
simon 1:eb68149218fd 66 0x00, /* iInterface */
simon 1:eb68149218fd 67
simon 1:eb68149218fd 68 0x09, /* bLength */
simon 1:eb68149218fd 69 HID_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 70 0x11, /* bcdHID (LSB) */
simon 1:eb68149218fd 71 0x01, /* bcdHID (MSB) */
simon 1:eb68149218fd 72 0x00, /* bCountryCode */
simon 1:eb68149218fd 73 0x01, /* bNumDescriptors */
simon 1:eb68149218fd 74 REPORT_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 75 0x79, /* wDescriptorLength (LSB) */
simon 1:eb68149218fd 76 0x00, /* wDescriptorLength (MSB) */
simon 1:eb68149218fd 77
simon 1:eb68149218fd 78 0x07, /* bLength */
simon 1:eb68149218fd 79 ENDPOINT_DESCRIPTOR, /* bDescriptorType */
simon 1:eb68149218fd 80 0x81, /* bEndpointAddress */
simon 1:eb68149218fd 81 0x03, /* bmAttributes */
simon 1:eb68149218fd 82 MAX_PACKET_SIZE_EP1, /* wMaxPacketSize (LSB) */
simon 1:eb68149218fd 83 0x00, /* wMaxPacketSize (MSB) */
simon 1:eb68149218fd 84 0x0a, /* bInterval */
simon 1:eb68149218fd 85 };
simon 1:eb68149218fd 86
simon 1:eb68149218fd 87 /* HID Class Report Descriptor */
simon 1:eb68149218fd 88 /* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes of data as per HID Class standard */
simon 1:eb68149218fd 89
simon 1:eb68149218fd 90 /* Main items */
simon 1:eb68149218fd 91 #define INPUT(size) (0x80 | size)
simon 1:eb68149218fd 92 #define OUTPUT(size) (0x90 | size)
simon 1:eb68149218fd 93 #define FEATURE(size) (0xb0 | size)
simon 1:eb68149218fd 94 #define COLLECTION(size) (0xa0 | size)
simon 1:eb68149218fd 95 #define END_COLLECTION(size) (0xc0 | size)
simon 1:eb68149218fd 96
simon 1:eb68149218fd 97 /* Global items */
simon 1:eb68149218fd 98 #define USAGE_PAGE(size) (0x04 | size)
simon 1:eb68149218fd 99 #define LOGICAL_MIN(size) (0x14 | size)
simon 1:eb68149218fd 100 #define LOGICAL_MAX(size) (0x24 | size)
simon 1:eb68149218fd 101 #define PHYSICAL_MIN(size) (0x34 | size)
simon 1:eb68149218fd 102 #define PHYSICAL_MAX(size) (0x44 | size)
simon 1:eb68149218fd 103 #define UNIT_EXPONENT(size) (0x54 | size)
simon 1:eb68149218fd 104 #define UNIT(size) (0x64 | size)
simon 1:eb68149218fd 105 #define REPORT_SIZE(size) (0x74 | size)
simon 1:eb68149218fd 106 #define REPORT_ID(size) (0x84 | size)
simon 1:eb68149218fd 107 #define REPORT_COUNT(size) (0x94 | size)
simon 1:eb68149218fd 108 #define PUSH(size) (0xa4 | size)
simon 1:eb68149218fd 109 #define POP(size) (0xb4 | size)
simon 1:eb68149218fd 110
simon 1:eb68149218fd 111 /* Local items */
simon 1:eb68149218fd 112 #define USAGE(size) (0x08 | size)
simon 1:eb68149218fd 113 #define USAGE_MIN(size) (0x18 | size)
simon 1:eb68149218fd 114 #define USAGE_MAX(size) (0x28 | size)
simon 1:eb68149218fd 115 #define DESIGNATOR_INDEX(size) (0x38 | size)
simon 1:eb68149218fd 116 #define DESIGNATOR_MIN(size) (0x48 | size)
simon 1:eb68149218fd 117 #define DESIGNATOR_MAX(size) (0x58 | size)
simon 1:eb68149218fd 118 #define STRING_INDEX(size) (0x78 | size)
simon 1:eb68149218fd 119 #define STRING_MIN(size) (0x88 | size)
simon 1:eb68149218fd 120 #define STRING_MAX(size) (0x98 | size)
simon 1:eb68149218fd 121 #define DELIMITER(size) (0xa8 | size)
simon 1:eb68149218fd 122
simon 1:eb68149218fd 123 #define REPORT_ID_KEYBOARD (1)
simon 1:eb68149218fd 124 #define REPORT_ID_MOUSE (2)
simon 1:eb68149218fd 125
simon 1:eb68149218fd 126 #define MAX_REPORT_SIZE (8)
simon 1:eb68149218fd 127
simon 1:eb68149218fd 128 unsigned char reportDescriptor[] = {
simon 1:eb68149218fd 129 /* Keyboard */
simon 1:eb68149218fd 130 USAGE_PAGE(1), 0x01,
simon 1:eb68149218fd 131 USAGE(1), 0x06,
simon 1:eb68149218fd 132 COLLECTION(1), 0x01,
simon 1:eb68149218fd 133 REPORT_ID(1), REPORT_ID_KEYBOARD,
simon 1:eb68149218fd 134 USAGE_PAGE(1), 0x07,
simon 1:eb68149218fd 135 USAGE_MIN(1), 0xE0,
simon 1:eb68149218fd 136 USAGE_MAX(1), 0xE7,
simon 1:eb68149218fd 137 LOGICAL_MIN(1), 0x00,
simon 1:eb68149218fd 138 LOGICAL_MAX(1), 0x01,
simon 1:eb68149218fd 139 REPORT_SIZE(1), 0x01,
simon 1:eb68149218fd 140 REPORT_COUNT(1), 0x08,
simon 1:eb68149218fd 141 INPUT(1), 0x02,
simon 1:eb68149218fd 142 REPORT_COUNT(1), 0x01,
simon 1:eb68149218fd 143 REPORT_SIZE(1), 0x08,
simon 1:eb68149218fd 144 INPUT(1), 0x01,
simon 1:eb68149218fd 145 REPORT_COUNT(1), 0x05,
simon 1:eb68149218fd 146 REPORT_SIZE(1), 0x01,
simon 1:eb68149218fd 147 USAGE_PAGE(1), 0x08,
simon 1:eb68149218fd 148 USAGE_MIN(1), 0x01,
simon 1:eb68149218fd 149 USAGE_MAX(1), 0x05,
simon 1:eb68149218fd 150 OUTPUT(1), 0x02,
simon 1:eb68149218fd 151 REPORT_COUNT(1), 0x01,
simon 1:eb68149218fd 152 REPORT_SIZE(1), 0x03,
simon 1:eb68149218fd 153 OUTPUT(1), 0x01,
simon 1:eb68149218fd 154 REPORT_COUNT(1), 0x06,
simon 1:eb68149218fd 155 REPORT_SIZE(1), 0x08,
simon 1:eb68149218fd 156 LOGICAL_MIN(1), 0x00,
simon 1:eb68149218fd 157 LOGICAL_MAX(2), 0xff, 0x00,
simon 1:eb68149218fd 158 USAGE_PAGE(1), 0x07,
simon 1:eb68149218fd 159 USAGE_MIN(1), 0x00,
simon 1:eb68149218fd 160 USAGE_MAX(2), 0xff, 0x00,
simon 1:eb68149218fd 161 INPUT(1), 0x00,
simon 1:eb68149218fd 162 END_COLLECTION(0),
simon 1:eb68149218fd 163
simon 1:eb68149218fd 164 /* Mouse */
simon 1:eb68149218fd 165 USAGE_PAGE(1), 0x01,
simon 1:eb68149218fd 166 USAGE(1), 0x02,
simon 1:eb68149218fd 167 COLLECTION(1), 0x01,
simon 1:eb68149218fd 168 USAGE(1), 0x01,
simon 1:eb68149218fd 169 COLLECTION(1), 0x00,
simon 1:eb68149218fd 170 REPORT_ID(1), REPORT_ID_MOUSE,
simon 1:eb68149218fd 171 REPORT_COUNT(1), 0x03,
simon 1:eb68149218fd 172 REPORT_SIZE(1), 0x01,
simon 1:eb68149218fd 173 USAGE_PAGE(1), 0x09,
simon 1:eb68149218fd 174 USAGE_MIN(1), 0x1,
simon 1:eb68149218fd 175 USAGE_MAX(1), 0x3,
simon 1:eb68149218fd 176 LOGICAL_MIN(1), 0x00,
simon 1:eb68149218fd 177 LOGICAL_MAX(1), 0x01,
simon 1:eb68149218fd 178 INPUT(1), 0x02,
simon 1:eb68149218fd 179 REPORT_COUNT(1), 0x01,
simon 1:eb68149218fd 180 REPORT_SIZE(1), 0x05,
simon 1:eb68149218fd 181 INPUT(1), 0x01,
simon 1:eb68149218fd 182 REPORT_COUNT(1), 0x03,
simon 1:eb68149218fd 183 REPORT_SIZE(1), 0x08,
simon 1:eb68149218fd 184 USAGE_PAGE(1), 0x01,
simon 1:eb68149218fd 185 USAGE(1), 0x30,
simon 1:eb68149218fd 186 USAGE(1), 0x31,
simon 1:eb68149218fd 187 USAGE(1), 0x38,
simon 1:eb68149218fd 188 LOGICAL_MIN(1), 0x81,
simon 1:eb68149218fd 189 LOGICAL_MAX(1), 0x7f,
simon 1:eb68149218fd 190 INPUT(1), 0x06,
simon 1:eb68149218fd 191 END_COLLECTION(0),
simon 1:eb68149218fd 192 END_COLLECTION(0),
simon 1:eb68149218fd 193 };
simon 1:eb68149218fd 194
simon 1:eb68149218fd 195 volatile bool complete;
simon 1:eb68149218fd 196 volatile bool configured;
simon 1:eb68149218fd 197 unsigned char outputReport[MAX_REPORT_SIZE];
simon 1:eb68149218fd 198
simon 1:eb68149218fd 199 usbhid::usbhid()
simon 1:eb68149218fd 200 {
simon 1:eb68149218fd 201 configured = false;
simon 1:eb68149218fd 202 connect();
simon 1:eb68149218fd 203 }
simon 1:eb68149218fd 204
simon 1:eb68149218fd 205 void usbhid::deviceEventReset()
simon 1:eb68149218fd 206 {
simon 1:eb68149218fd 207 configured = false;
simon 1:eb68149218fd 208
simon 1:eb68149218fd 209 /* Must call base class */
simon 1:eb68149218fd 210 usbdevice::deviceEventReset();
simon 1:eb68149218fd 211 }
simon 1:eb68149218fd 212
simon 1:eb68149218fd 213 bool usbhid::requestSetConfiguration(void)
simon 1:eb68149218fd 214 {
simon 1:eb68149218fd 215 bool result;
simon 1:eb68149218fd 216
simon 1:eb68149218fd 217 /* Configure IN interrupt endpoint */
simon 1:eb68149218fd 218 realiseEndpoint(EP1IN, MAX_PACKET_SIZE_EP1);
simon 1:eb68149218fd 219 enableEndpointEvent(EP1IN);
simon 1:eb68149218fd 220
simon 1:eb68149218fd 221 /* Must call base class */
simon 1:eb68149218fd 222 result = usbdevice::requestSetConfiguration();
simon 1:eb68149218fd 223
simon 1:eb68149218fd 224 if (result)
simon 1:eb68149218fd 225 {
simon 1:eb68149218fd 226 /* Now configured */
simon 1:eb68149218fd 227 configured = true;
simon 1:eb68149218fd 228 }
simon 1:eb68149218fd 229
simon 1:eb68149218fd 230 return result;
simon 1:eb68149218fd 231 }
simon 1:eb68149218fd 232
simon 1:eb68149218fd 233 bool usbhid::requestGetDescriptor(void)
simon 1:eb68149218fd 234 {
simon 1:eb68149218fd 235 bool success = false;
simon 1:eb68149218fd 236
simon 1:eb68149218fd 237 switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
simon 1:eb68149218fd 238 {
simon 1:eb68149218fd 239 case DEVICE_DESCRIPTOR:
simon 1:eb68149218fd 240 transfer.remaining = sizeof(deviceDescriptor);
simon 1:eb68149218fd 241 transfer.ptr = deviceDescriptor;
simon 1:eb68149218fd 242 transfer.direction = DEVICE_TO_HOST;
simon 1:eb68149218fd 243 success = true;
simon 1:eb68149218fd 244 break;
simon 1:eb68149218fd 245 case CONFIGURATION_DESCRIPTOR:
simon 1:eb68149218fd 246 transfer.remaining = sizeof(configurationDescriptor);
simon 1:eb68149218fd 247 transfer.ptr = configurationDescriptor;
simon 1:eb68149218fd 248 transfer.direction = DEVICE_TO_HOST;
simon 1:eb68149218fd 249 success = true;
simon 1:eb68149218fd 250 break;
simon 1:eb68149218fd 251 case STRING_DESCRIPTOR:
simon 1:eb68149218fd 252 case INTERFACE_DESCRIPTOR:
simon 1:eb68149218fd 253 case ENDPOINT_DESCRIPTOR:
simon 1:eb68149218fd 254 /* TODO: Support is optional, not implemented here */
simon 1:eb68149218fd 255 break;
simon 1:eb68149218fd 256 case HID_DESCRIPTOR:
simon 1:eb68149218fd 257 transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */
simon 1:eb68149218fd 258 transfer.ptr = &configurationDescriptor[18];
simon 1:eb68149218fd 259 transfer.direction = DEVICE_TO_HOST;
simon 1:eb68149218fd 260 success = true;
simon 1:eb68149218fd 261 break;
simon 1:eb68149218fd 262 case REPORT_DESCRIPTOR:
simon 1:eb68149218fd 263 transfer.remaining = sizeof(reportDescriptor);
simon 1:eb68149218fd 264 transfer.ptr = reportDescriptor;
simon 1:eb68149218fd 265 transfer.direction = DEVICE_TO_HOST;
simon 1:eb68149218fd 266 success = true;
simon 1:eb68149218fd 267 break;
simon 1:eb68149218fd 268 default:
simon 1:eb68149218fd 269 break;
simon 1:eb68149218fd 270 }
simon 1:eb68149218fd 271
simon 1:eb68149218fd 272 return success;
simon 1:eb68149218fd 273 }
simon 1:eb68149218fd 274
simon 1:eb68149218fd 275 bool usbhid::requestSetup(void)
simon 1:eb68149218fd 276 {
simon 1:eb68149218fd 277 /* Process class requests */
simon 1:eb68149218fd 278 bool success = false;
simon 1:eb68149218fd 279
simon 1:eb68149218fd 280 if (transfer.setup.bmRequestType.Type == CLASS_TYPE)
simon 1:eb68149218fd 281 {
simon 1:eb68149218fd 282 switch (transfer.setup.bRequest)
simon 1:eb68149218fd 283 {
simon 1:eb68149218fd 284 case SET_REPORT:
simon 1:eb68149218fd 285 switch (transfer.setup.wValue & 0xff)
simon 1:eb68149218fd 286 {
simon 1:eb68149218fd 287 case REPORT_ID_KEYBOARD:
simon 1:eb68149218fd 288 /* TODO: LED state */
simon 1:eb68149218fd 289 transfer.remaining = sizeof(outputReport);
simon 1:eb68149218fd 290 transfer.ptr = outputReport;
simon 1:eb68149218fd 291 transfer.direction = HOST_TO_DEVICE;
simon 1:eb68149218fd 292 success = true;
simon 1:eb68149218fd 293 break;
simon 1:eb68149218fd 294 default:
simon 1:eb68149218fd 295 break;
simon 1:eb68149218fd 296 }
simon 1:eb68149218fd 297 break;
simon 1:eb68149218fd 298 default:
simon 1:eb68149218fd 299 break;
simon 1:eb68149218fd 300 }
simon 1:eb68149218fd 301 }
simon 1:eb68149218fd 302
simon 1:eb68149218fd 303 if (success)
simon 1:eb68149218fd 304 {
simon 1:eb68149218fd 305 /* We've handled this request */
simon 1:eb68149218fd 306 return true;
simon 1:eb68149218fd 307 }
simon 1:eb68149218fd 308
simon 1:eb68149218fd 309 return usbdevice::requestSetup();
simon 1:eb68149218fd 310 }
simon 1:eb68149218fd 311
simon 1:eb68149218fd 312 bool usbhid::sendInputReport(unsigned char id, unsigned char *data, unsigned char size)
simon 1:eb68149218fd 313 {
simon 1:eb68149218fd 314 /* Send an Input Report */
simon 1:eb68149218fd 315 /* If data is NULL an all zero report is sent */
simon 1:eb68149218fd 316
simon 1:eb68149218fd 317 static unsigned char report[MAX_REPORT_SIZE+1]; /* +1 for report ID */
simon 1:eb68149218fd 318 unsigned char i;
simon 1:eb68149218fd 319
simon 1:eb68149218fd 320 if (size > MAX_REPORT_SIZE)
simon 1:eb68149218fd 321 {
simon 1:eb68149218fd 322 return false;
simon 1:eb68149218fd 323 }
simon 1:eb68149218fd 324
simon 1:eb68149218fd 325 /* Add report ID */
simon 1:eb68149218fd 326 report[0]=id;
simon 1:eb68149218fd 327
simon 1:eb68149218fd 328 /* Add report data */
simon 1:eb68149218fd 329 if (data != NULL)
simon 1:eb68149218fd 330 {
simon 1:eb68149218fd 331 for (i=0; i<size; i++)
simon 1:eb68149218fd 332 {
simon 1:eb68149218fd 333 report[i+1] = *data++;
simon 1:eb68149218fd 334 }
simon 1:eb68149218fd 335 }
simon 1:eb68149218fd 336 else
simon 1:eb68149218fd 337 {
simon 1:eb68149218fd 338 for (i=0; i<size; i++)
simon 1:eb68149218fd 339 {
simon 1:eb68149218fd 340 report[i+1] = 0;
simon 1:eb68149218fd 341 }
simon 1:eb68149218fd 342 }
simon 1:eb68149218fd 343
simon 1:eb68149218fd 344 /* Block if not configured */
simon 1:eb68149218fd 345 while (!configured);
simon 1:eb68149218fd 346
simon 1:eb68149218fd 347 /* Send report */
simon 1:eb68149218fd 348 complete = false;
simon 1:eb68149218fd 349 disableEvents();
simon 1:eb68149218fd 350 endpointWrite(EP1IN, report, size+1); /* +1 for report ID */
simon 1:eb68149218fd 351 enableEvents();
simon 1:eb68149218fd 352
simon 1:eb68149218fd 353 /* Wait for completion */
simon 1:eb68149218fd 354 while(!complete && configured);
simon 1:eb68149218fd 355 return true;
simon 1:eb68149218fd 356 }
simon 1:eb68149218fd 357
simon 1:eb68149218fd 358 void usbhid::endpointEventEP1In(void)
simon 1:eb68149218fd 359 {
simon 1:eb68149218fd 360 complete = true;
simon 1:eb68149218fd 361 }
simon 1:eb68149218fd 362
simon 1:eb68149218fd 363 bool usbhid::keyboard(char c)
simon 1:eb68149218fd 364 {
simon 1:eb68149218fd 365 /* Send a simulated keyboard keypress. Returns true if successful. */
simon 1:eb68149218fd 366 unsigned char report[8]={0,0,0,0,0,0,0,0};
simon 1:eb68149218fd 367
simon 1:eb68149218fd 368 report[0] = keymap[c].modifier;
simon 1:eb68149218fd 369 report[2] = keymap[c].usage;
simon 1:eb68149218fd 370
simon 1:eb68149218fd 371 /* Key down */
simon 1:eb68149218fd 372 if (!sendInputReport(REPORT_ID_KEYBOARD, report, 8))
simon 1:eb68149218fd 373 {
simon 1:eb68149218fd 374 return false;
simon 1:eb68149218fd 375 }
simon 1:eb68149218fd 376
simon 1:eb68149218fd 377 /* Key up */
simon 1:eb68149218fd 378 if (!sendInputReport(REPORT_ID_KEYBOARD, NULL, 8))
simon 1:eb68149218fd 379 {
simon 1:eb68149218fd 380 return false;
simon 1:eb68149218fd 381 }
simon 1:eb68149218fd 382
simon 1:eb68149218fd 383 return true;
simon 1:eb68149218fd 384 }
simon 1:eb68149218fd 385
simon 1:eb68149218fd 386 bool usbhid::keyboard(char *string)
simon 1:eb68149218fd 387 {
simon 1:eb68149218fd 388 /* Send a string of characters. Returns true if successful. */
simon 1:eb68149218fd 389 do {
simon 1:eb68149218fd 390 if (!keyboard(*string++))
simon 1:eb68149218fd 391 {
simon 1:eb68149218fd 392 return false;
simon 1:eb68149218fd 393 }
simon 1:eb68149218fd 394 } while (*string != '\0');
simon 1:eb68149218fd 395
simon 1:eb68149218fd 396 return true;
simon 1:eb68149218fd 397 }
simon 1:eb68149218fd 398
simon 1:eb68149218fd 399 bool usbhid::mouse(signed char x, signed char y, unsigned char buttons, signed char wheel)
simon 1:eb68149218fd 400 {
simon 1:eb68149218fd 401 /* Send a simulated mouse event. Returns true if successful. */
simon 1:eb68149218fd 402 unsigned char report[4]={0,0,0,0};
simon 1:eb68149218fd 403
simon 1:eb68149218fd 404 report[0] = buttons;
simon 1:eb68149218fd 405 report[1] = x;
simon 1:eb68149218fd 406 report[2] = y;
simon 1:eb68149218fd 407 report[3] = wheel;
simon 1:eb68149218fd 408
simon 1:eb68149218fd 409 if (!sendInputReport(REPORT_ID_MOUSE, report, 4))
simon 1:eb68149218fd 410 {
simon 1:eb68149218fd 411 return false;
simon 1:eb68149218fd 412 }
simon 1:eb68149218fd 413
simon 1:eb68149218fd 414 return true;
simon 1:eb68149218fd 415 }