Acts a USB HID keyboard, and socket server. Forwards characters from TCP ip socket to keyboard

Dependencies:   mbed EthernetNetIf

Committer:
henryeherman
Date:
Fri Dec 14 01:15:44 2018 +0000
Revision:
1:d866a9d23e49
Parent:
0:beb124b81ef5
init

Who changed what in which revision?

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