A optical beam breaker detector that appears to aPC as a USB keyboard, typing characters when the beam is broken

Dependencies:   mbed

Committer:
chris
Date:
Thu May 12 16:46:53 2011 +0000
Revision:
1:45de28d7be8e
Parent:
0:9d0f47bc66da

        

Who changed what in which revision?

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