Jafar Qutteineh / Mbed 2 deprecated RC_Simulator

Dependencies:   mbed

Committer:
j3sq
Date:
Sat Jul 02 17:27:05 2011 +0000
Revision:
0:3dbb22992c94
Revision 0.0 (This is just a demonstration)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3sq 0:3dbb22992c94 1 /* usbhid.cpp */
j3sq 0:3dbb22992c94 2 /* USB HID class device */
j3sq 0:3dbb22992c94 3 /* Copyright (c) Phil Wright 2008 */
j3sq 0:3dbb22992c94 4
j3sq 0:3dbb22992c94 5 /* modified by Shinichiro Oba <http://mbed.org/users/bricklife/> */
j3sq 0:3dbb22992c94 6
j3sq 0:3dbb22992c94 7 #include "mbed.h"
j3sq 0:3dbb22992c94 8 #include "usbhid.h"
j3sq 0:3dbb22992c94 9 #include "asciihid.h"
j3sq 0:3dbb22992c94 10
j3sq 0:3dbb22992c94 11 /* Endpoint packet sizes */
j3sq 0:3dbb22992c94 12 #define MAX_PACKET_SIZE_EP1 (64)
j3sq 0:3dbb22992c94 13
j3sq 0:3dbb22992c94 14 /* HID Class */
j3sq 0:3dbb22992c94 15 #define HID_CLASS (3)
j3sq 0:3dbb22992c94 16 #define HID_SUBCLASS_NONE (0)
j3sq 0:3dbb22992c94 17 #define HID_PROTOCOL_NONE (0)
j3sq 0:3dbb22992c94 18 #define HID_DESCRIPTOR (33)
j3sq 0:3dbb22992c94 19 #define REPORT_DESCRIPTOR (34)
j3sq 0:3dbb22992c94 20
j3sq 0:3dbb22992c94 21 /* Class requests */
j3sq 0:3dbb22992c94 22 #define GET_REPORT (0x1)
j3sq 0:3dbb22992c94 23 #define GET_IDLE (0x2)
j3sq 0:3dbb22992c94 24 #define SET_REPORT (0x9)
j3sq 0:3dbb22992c94 25 #define SET_IDLE (0xa)
j3sq 0:3dbb22992c94 26
j3sq 0:3dbb22992c94 27 /* Descriptors */
j3sq 0:3dbb22992c94 28 unsigned char deviceDescriptor[] = {
j3sq 0:3dbb22992c94 29 0x12, /* bLength */
j3sq 0:3dbb22992c94 30 DEVICE_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 31 0x00, /* bcdUSB (LSB) */
j3sq 0:3dbb22992c94 32 0x02, /* bcdUSB (MSB) */
j3sq 0:3dbb22992c94 33 0x00, /* bDeviceClass */
j3sq 0:3dbb22992c94 34 0x00, /* bDeviceSubClass */
j3sq 0:3dbb22992c94 35 0x00, /* bDeviceprotocol */
j3sq 0:3dbb22992c94 36 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
j3sq 0:3dbb22992c94 37 0x28, /* idVendor (LSB) */
j3sq 0:3dbb22992c94 38 0x0d, /* idVendor (MSB) */
j3sq 0:3dbb22992c94 39 0x05, /* idProduct (LSB) */
j3sq 0:3dbb22992c94 40 0x02, /* idProduct (MSB) */
j3sq 0:3dbb22992c94 41 0x00, /* bcdDevice (LSB) */
j3sq 0:3dbb22992c94 42 0x00, /* bcdDevice (MSB) */
j3sq 0:3dbb22992c94 43 0x00, /* iManufacturer */
j3sq 0:3dbb22992c94 44 0x00, /* iProduct */
j3sq 0:3dbb22992c94 45 0x00, /* iSerialNumber */
j3sq 0:3dbb22992c94 46 0x01 /* bNumConfigurations */
j3sq 0:3dbb22992c94 47 };
j3sq 0:3dbb22992c94 48
j3sq 0:3dbb22992c94 49 unsigned char configurationDescriptor[] = {
j3sq 0:3dbb22992c94 50 0x09, /* bLength */
j3sq 0:3dbb22992c94 51 CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 52 0x09+0x09+0x09+0x07, /* wTotalLength (LSB) */
j3sq 0:3dbb22992c94 53 0x00, /* wTotalLength (MSB) */
j3sq 0:3dbb22992c94 54 0x01, /* bNumInterfaces */
j3sq 0:3dbb22992c94 55 0x01, /* bConfigurationValue */
j3sq 0:3dbb22992c94 56 0x00, /* iConfiguration */
j3sq 0:3dbb22992c94 57 0xc0, /* bmAttributes */
j3sq 0:3dbb22992c94 58 0x00, /* bMaxPower */
j3sq 0:3dbb22992c94 59
j3sq 0:3dbb22992c94 60 0x09, /* bLength */
j3sq 0:3dbb22992c94 61 INTERFACE_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 62 0x00, /* bInterfaceNumber */
j3sq 0:3dbb22992c94 63 0x00, /* bAlternateSetting */
j3sq 0:3dbb22992c94 64 0x01, /* bNumEndpoints */
j3sq 0:3dbb22992c94 65 HID_CLASS, /* bInterfaceClass */
j3sq 0:3dbb22992c94 66 HID_SUBCLASS_NONE, /* bInterfaceSubClass */
j3sq 0:3dbb22992c94 67 HID_PROTOCOL_NONE, /* bInterfaceProtocol */
j3sq 0:3dbb22992c94 68 0x00, /* iInterface */
j3sq 0:3dbb22992c94 69
j3sq 0:3dbb22992c94 70 0x09, /* bLength */
j3sq 0:3dbb22992c94 71 HID_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 72 0x11, /* bcdHID (LSB) */
j3sq 0:3dbb22992c94 73 0x01, /* bcdHID (MSB) */
j3sq 0:3dbb22992c94 74 0x00, /* bCountryCode */
j3sq 0:3dbb22992c94 75 0x01, /* bNumDescriptors */
j3sq 0:3dbb22992c94 76 REPORT_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 77 0x79, /* wDescriptorLength (LSB) */
j3sq 0:3dbb22992c94 78 0x00, /* wDescriptorLength (MSB) */
j3sq 0:3dbb22992c94 79
j3sq 0:3dbb22992c94 80 0x07, /* bLength */
j3sq 0:3dbb22992c94 81 ENDPOINT_DESCRIPTOR, /* bDescriptorType */
j3sq 0:3dbb22992c94 82 0x81, /* bEndpointAddress */
j3sq 0:3dbb22992c94 83 0x03, /* bmAttributes */
j3sq 0:3dbb22992c94 84 MAX_PACKET_SIZE_EP1, /* wMaxPacketSize (LSB) */
j3sq 0:3dbb22992c94 85 0x00, /* wMaxPacketSize (MSB) */
j3sq 0:3dbb22992c94 86 0x0a, /* bInterval */
j3sq 0:3dbb22992c94 87 };
j3sq 0:3dbb22992c94 88
j3sq 0:3dbb22992c94 89 /* HID Class Report Descriptor */
j3sq 0:3dbb22992c94 90 /* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes of data as per HID Class standard */
j3sq 0:3dbb22992c94 91
j3sq 0:3dbb22992c94 92 /* Main items */
j3sq 0:3dbb22992c94 93 #define INPUT(size) (0x80 | size)
j3sq 0:3dbb22992c94 94 #define OUTPUT(size) (0x90 | size)
j3sq 0:3dbb22992c94 95 #define FEATURE(size) (0xb0 | size)
j3sq 0:3dbb22992c94 96 #define COLLECTION(size) (0xa0 | size)
j3sq 0:3dbb22992c94 97 #define END_COLLECTION(size) (0xc0 | size)
j3sq 0:3dbb22992c94 98
j3sq 0:3dbb22992c94 99 /* Global items */
j3sq 0:3dbb22992c94 100 #define USAGE_PAGE(size) (0x04 | size)
j3sq 0:3dbb22992c94 101 #define LOGICAL_MIN(size) (0x14 | size)
j3sq 0:3dbb22992c94 102 #define LOGICAL_MAX(size) (0x24 | size)
j3sq 0:3dbb22992c94 103 #define PHYSICAL_MIN(size) (0x34 | size)
j3sq 0:3dbb22992c94 104 #define PHYSICAL_MAX(size) (0x44 | size)
j3sq 0:3dbb22992c94 105 #define UNIT_EXPONENT(size) (0x54 | size)
j3sq 0:3dbb22992c94 106 #define UNIT(size) (0x64 | size)
j3sq 0:3dbb22992c94 107 #define REPORT_SIZE(size) (0x74 | size)
j3sq 0:3dbb22992c94 108 #define REPORT_ID(size) (0x84 | size)
j3sq 0:3dbb22992c94 109 #define REPORT_COUNT(size) (0x94 | size)
j3sq 0:3dbb22992c94 110 #define PUSH(size) (0xa4 | size)
j3sq 0:3dbb22992c94 111 #define POP(size) (0xb4 | size)
j3sq 0:3dbb22992c94 112
j3sq 0:3dbb22992c94 113 /* Local items */
j3sq 0:3dbb22992c94 114 #define USAGE(size) (0x08 | size)
j3sq 0:3dbb22992c94 115 #define USAGE_MIN(size) (0x18 | size)
j3sq 0:3dbb22992c94 116 #define USAGE_MAX(size) (0x28 | size)
j3sq 0:3dbb22992c94 117 #define DESIGNATOR_INDEX(size) (0x38 | size)
j3sq 0:3dbb22992c94 118 #define DESIGNATOR_MIN(size) (0x48 | size)
j3sq 0:3dbb22992c94 119 #define DESIGNATOR_MAX(size) (0x58 | size)
j3sq 0:3dbb22992c94 120 #define STRING_INDEX(size) (0x78 | size)
j3sq 0:3dbb22992c94 121 #define STRING_MIN(size) (0x88 | size)
j3sq 0:3dbb22992c94 122 #define STRING_MAX(size) (0x98 | size)
j3sq 0:3dbb22992c94 123 #define DELIMITER(size) (0xa8 | size)
j3sq 0:3dbb22992c94 124
j3sq 0:3dbb22992c94 125 #define REPORT_ID_KEYBOARD (1)
j3sq 0:3dbb22992c94 126 #define REPORT_ID_MOUSE (2)
j3sq 0:3dbb22992c94 127
j3sq 0:3dbb22992c94 128 #define MAX_REPORT_SIZE (8)
j3sq 0:3dbb22992c94 129
j3sq 0:3dbb22992c94 130 unsigned char reportDescriptor[] = {
j3sq 0:3dbb22992c94 131 /* Keyboard */
j3sq 0:3dbb22992c94 132 USAGE_PAGE(1), 0x01,
j3sq 0:3dbb22992c94 133 USAGE(1), 0x06,
j3sq 0:3dbb22992c94 134 COLLECTION(1), 0x01,
j3sq 0:3dbb22992c94 135 REPORT_ID(1), REPORT_ID_KEYBOARD,
j3sq 0:3dbb22992c94 136 USAGE_PAGE(1), 0x07,
j3sq 0:3dbb22992c94 137 USAGE_MIN(1), 0xE0,
j3sq 0:3dbb22992c94 138 USAGE_MAX(1), 0xE7,
j3sq 0:3dbb22992c94 139 LOGICAL_MIN(1), 0x00,
j3sq 0:3dbb22992c94 140 LOGICAL_MAX(1), 0x01,
j3sq 0:3dbb22992c94 141 REPORT_SIZE(1), 0x01,
j3sq 0:3dbb22992c94 142 REPORT_COUNT(1), 0x08,
j3sq 0:3dbb22992c94 143 INPUT(1), 0x02,
j3sq 0:3dbb22992c94 144 REPORT_COUNT(1), 0x01,
j3sq 0:3dbb22992c94 145 REPORT_SIZE(1), 0x08,
j3sq 0:3dbb22992c94 146 INPUT(1), 0x01,
j3sq 0:3dbb22992c94 147 REPORT_COUNT(1), 0x05,
j3sq 0:3dbb22992c94 148 REPORT_SIZE(1), 0x01,
j3sq 0:3dbb22992c94 149 USAGE_PAGE(1), 0x08,
j3sq 0:3dbb22992c94 150 USAGE_MIN(1), 0x01,
j3sq 0:3dbb22992c94 151 USAGE_MAX(1), 0x05,
j3sq 0:3dbb22992c94 152 OUTPUT(1), 0x02,
j3sq 0:3dbb22992c94 153 REPORT_COUNT(1), 0x01,
j3sq 0:3dbb22992c94 154 REPORT_SIZE(1), 0x03,
j3sq 0:3dbb22992c94 155 OUTPUT(1), 0x01,
j3sq 0:3dbb22992c94 156 REPORT_COUNT(1), 0x06,
j3sq 0:3dbb22992c94 157 REPORT_SIZE(1), 0x08,
j3sq 0:3dbb22992c94 158 LOGICAL_MIN(1), 0x00,
j3sq 0:3dbb22992c94 159 LOGICAL_MAX(2), 0xff, 0x00,
j3sq 0:3dbb22992c94 160 USAGE_PAGE(1), 0x07,
j3sq 0:3dbb22992c94 161 USAGE_MIN(1), 0x00,
j3sq 0:3dbb22992c94 162 USAGE_MAX(2), 0xff, 0x00,
j3sq 0:3dbb22992c94 163 INPUT(1), 0x00,
j3sq 0:3dbb22992c94 164 END_COLLECTION(0),
j3sq 0:3dbb22992c94 165
j3sq 0:3dbb22992c94 166 /* Mouse */
j3sq 0:3dbb22992c94 167 USAGE_PAGE(1), 0x01,
j3sq 0:3dbb22992c94 168 USAGE(1), 0x02,
j3sq 0:3dbb22992c94 169 COLLECTION(1), 0x01,
j3sq 0:3dbb22992c94 170 USAGE(1), 0x01,
j3sq 0:3dbb22992c94 171 COLLECTION(1), 0x00,
j3sq 0:3dbb22992c94 172 REPORT_ID(1), REPORT_ID_MOUSE,
j3sq 0:3dbb22992c94 173 REPORT_COUNT(1), 0x03,
j3sq 0:3dbb22992c94 174 REPORT_SIZE(1), 0x01,
j3sq 0:3dbb22992c94 175 USAGE_PAGE(1), 0x09,
j3sq 0:3dbb22992c94 176 USAGE_MIN(1), 0x1,
j3sq 0:3dbb22992c94 177 USAGE_MAX(1), 0x3,
j3sq 0:3dbb22992c94 178 LOGICAL_MIN(1), 0x00,
j3sq 0:3dbb22992c94 179 LOGICAL_MAX(1), 0x01,
j3sq 0:3dbb22992c94 180 INPUT(1), 0x02,
j3sq 0:3dbb22992c94 181 REPORT_COUNT(1), 0x01,
j3sq 0:3dbb22992c94 182 REPORT_SIZE(1), 0x05,
j3sq 0:3dbb22992c94 183 INPUT(1), 0x01,
j3sq 0:3dbb22992c94 184 REPORT_COUNT(1), 0x03,
j3sq 0:3dbb22992c94 185 REPORT_SIZE(1), 0x08,
j3sq 0:3dbb22992c94 186 USAGE_PAGE(1), 0x01,
j3sq 0:3dbb22992c94 187 USAGE(1), 0x30,
j3sq 0:3dbb22992c94 188 USAGE(1), 0x31,
j3sq 0:3dbb22992c94 189 USAGE(1), 0x38,
j3sq 0:3dbb22992c94 190 LOGICAL_MIN(1), 0x81,
j3sq 0:3dbb22992c94 191 LOGICAL_MAX(1), 0x7f,
j3sq 0:3dbb22992c94 192 INPUT(1), 0x06,
j3sq 0:3dbb22992c94 193 END_COLLECTION(0),
j3sq 0:3dbb22992c94 194 END_COLLECTION(0),
j3sq 0:3dbb22992c94 195 };
j3sq 0:3dbb22992c94 196
j3sq 0:3dbb22992c94 197 volatile bool complete;
j3sq 0:3dbb22992c94 198 volatile bool configured;
j3sq 0:3dbb22992c94 199 unsigned char outputReport[MAX_REPORT_SIZE];
j3sq 0:3dbb22992c94 200 DigitalOut errorLED (LED1);
j3sq 0:3dbb22992c94 201 DigitalOut okLED (LED2);
j3sq 0:3dbb22992c94 202
j3sq 0:3dbb22992c94 203 usbhid::usbhid() {
j3sq 0:3dbb22992c94 204 configured = false;
j3sq 0:3dbb22992c94 205 connect();
j3sq 0:3dbb22992c94 206
j3sq 0:3dbb22992c94 207 }
j3sq 0:3dbb22992c94 208
j3sq 0:3dbb22992c94 209 void usbhid::deviceEventReset() {
j3sq 0:3dbb22992c94 210 configured = false;
j3sq 0:3dbb22992c94 211
j3sq 0:3dbb22992c94 212 /* Must call base class */
j3sq 0:3dbb22992c94 213 usbdevice::deviceEventReset();
j3sq 0:3dbb22992c94 214 }
j3sq 0:3dbb22992c94 215
j3sq 0:3dbb22992c94 216 bool usbhid::requestSetConfiguration(void) {
j3sq 0:3dbb22992c94 217 bool result;
j3sq 0:3dbb22992c94 218
j3sq 0:3dbb22992c94 219 /* Configure IN interrupt endpoint */
j3sq 0:3dbb22992c94 220 realiseEndpoint(EP1IN, MAX_PACKET_SIZE_EP1);
j3sq 0:3dbb22992c94 221 enableEndpointEvent(EP1IN);
j3sq 0:3dbb22992c94 222
j3sq 0:3dbb22992c94 223 /* Must call base class */
j3sq 0:3dbb22992c94 224 result = usbdevice::requestSetConfiguration();
j3sq 0:3dbb22992c94 225
j3sq 0:3dbb22992c94 226 if (result) {
j3sq 0:3dbb22992c94 227 /* Now configured */
j3sq 0:3dbb22992c94 228 configured = true;
j3sq 0:3dbb22992c94 229 }
j3sq 0:3dbb22992c94 230
j3sq 0:3dbb22992c94 231 return result;
j3sq 0:3dbb22992c94 232 }
j3sq 0:3dbb22992c94 233
j3sq 0:3dbb22992c94 234 bool usbhid::requestGetDescriptor(void) {
j3sq 0:3dbb22992c94 235 bool success = false;
j3sq 0:3dbb22992c94 236
j3sq 0:3dbb22992c94 237 switch (DESCRIPTOR_TYPE(transfer.setup.wValue)) {
j3sq 0:3dbb22992c94 238 case DEVICE_DESCRIPTOR:
j3sq 0:3dbb22992c94 239 transfer.remaining = sizeof(deviceDescriptor);
j3sq 0:3dbb22992c94 240 transfer.ptr = deviceDescriptor;
j3sq 0:3dbb22992c94 241 transfer.direction = DEVICE_TO_HOST;
j3sq 0:3dbb22992c94 242 success = true;
j3sq 0:3dbb22992c94 243 break;
j3sq 0:3dbb22992c94 244 case CONFIGURATION_DESCRIPTOR:
j3sq 0:3dbb22992c94 245 transfer.remaining = sizeof(configurationDescriptor);
j3sq 0:3dbb22992c94 246 transfer.ptr = configurationDescriptor;
j3sq 0:3dbb22992c94 247 transfer.direction = DEVICE_TO_HOST;
j3sq 0:3dbb22992c94 248 success = true;
j3sq 0:3dbb22992c94 249 break;
j3sq 0:3dbb22992c94 250 case STRING_DESCRIPTOR:
j3sq 0:3dbb22992c94 251 case INTERFACE_DESCRIPTOR:
j3sq 0:3dbb22992c94 252 case ENDPOINT_DESCRIPTOR:
j3sq 0:3dbb22992c94 253 /* TODO: Support is optional, not implemented here */
j3sq 0:3dbb22992c94 254 break;
j3sq 0:3dbb22992c94 255 case HID_DESCRIPTOR:
j3sq 0:3dbb22992c94 256 transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */
j3sq 0:3dbb22992c94 257 transfer.ptr = &configurationDescriptor[18];
j3sq 0:3dbb22992c94 258 transfer.direction = DEVICE_TO_HOST;
j3sq 0:3dbb22992c94 259 success = true;
j3sq 0:3dbb22992c94 260 break;
j3sq 0:3dbb22992c94 261 case REPORT_DESCRIPTOR:
j3sq 0:3dbb22992c94 262 transfer.remaining = sizeof(reportDescriptor);
j3sq 0:3dbb22992c94 263 transfer.ptr = reportDescriptor;
j3sq 0:3dbb22992c94 264 transfer.direction = DEVICE_TO_HOST;
j3sq 0:3dbb22992c94 265 success = true;
j3sq 0:3dbb22992c94 266 break;
j3sq 0:3dbb22992c94 267 default:
j3sq 0:3dbb22992c94 268 break;
j3sq 0:3dbb22992c94 269 }
j3sq 0:3dbb22992c94 270
j3sq 0:3dbb22992c94 271 return success;
j3sq 0:3dbb22992c94 272 }
j3sq 0:3dbb22992c94 273
j3sq 0:3dbb22992c94 274 bool usbhid::requestSetup(void) {
j3sq 0:3dbb22992c94 275 /* Process class requests */
j3sq 0:3dbb22992c94 276 bool success = false;
j3sq 0:3dbb22992c94 277
j3sq 0:3dbb22992c94 278 if (transfer.setup.bmRequestType.Type == CLASS_TYPE) {
j3sq 0:3dbb22992c94 279 switch (transfer.setup.bRequest) {
j3sq 0:3dbb22992c94 280 case SET_REPORT:
j3sq 0:3dbb22992c94 281 switch (transfer.setup.wValue & 0xff) {
j3sq 0:3dbb22992c94 282 case REPORT_ID_KEYBOARD:
j3sq 0:3dbb22992c94 283 /* TODO: LED state */
j3sq 0:3dbb22992c94 284 transfer.remaining = sizeof(outputReport);
j3sq 0:3dbb22992c94 285 transfer.ptr = outputReport;
j3sq 0:3dbb22992c94 286 transfer.direction = HOST_TO_DEVICE;
j3sq 0:3dbb22992c94 287 success = true;
j3sq 0:3dbb22992c94 288 break;
j3sq 0:3dbb22992c94 289 default:
j3sq 0:3dbb22992c94 290 break;
j3sq 0:3dbb22992c94 291 }
j3sq 0:3dbb22992c94 292 break;
j3sq 0:3dbb22992c94 293 default:
j3sq 0:3dbb22992c94 294 break;
j3sq 0:3dbb22992c94 295 }
j3sq 0:3dbb22992c94 296 }
j3sq 0:3dbb22992c94 297
j3sq 0:3dbb22992c94 298 if (success) {
j3sq 0:3dbb22992c94 299 /* We've handled this request */
j3sq 0:3dbb22992c94 300 return true;
j3sq 0:3dbb22992c94 301 }
j3sq 0:3dbb22992c94 302
j3sq 0:3dbb22992c94 303 return usbdevice::requestSetup();
j3sq 0:3dbb22992c94 304 }
j3sq 0:3dbb22992c94 305
j3sq 0:3dbb22992c94 306 bool usbhid::sendInputReport(unsigned char id, unsigned char *data, unsigned char size) {
j3sq 0:3dbb22992c94 307 /* Send an Input Report */
j3sq 0:3dbb22992c94 308 /* If data is NULL an all zero report is sent */
j3sq 0:3dbb22992c94 309
j3sq 0:3dbb22992c94 310 static unsigned char report[MAX_REPORT_SIZE+1]; /* +1 for report ID */
j3sq 0:3dbb22992c94 311 unsigned char i;
j3sq 0:3dbb22992c94 312
j3sq 0:3dbb22992c94 313 if (size > MAX_REPORT_SIZE) {
j3sq 0:3dbb22992c94 314 return false;
j3sq 0:3dbb22992c94 315 }
j3sq 0:3dbb22992c94 316
j3sq 0:3dbb22992c94 317 /* Add report ID */
j3sq 0:3dbb22992c94 318 report[0]=id;
j3sq 0:3dbb22992c94 319
j3sq 0:3dbb22992c94 320 /* Add report data */
j3sq 0:3dbb22992c94 321 if (data != NULL) {
j3sq 0:3dbb22992c94 322 for (i=0; i<size; i++) {
j3sq 0:3dbb22992c94 323 report[i+1] = *data++;
j3sq 0:3dbb22992c94 324 }
j3sq 0:3dbb22992c94 325 } else {
j3sq 0:3dbb22992c94 326 for (i=0; i<size; i++) {
j3sq 0:3dbb22992c94 327 report[i+1] = 0;
j3sq 0:3dbb22992c94 328 }
j3sq 0:3dbb22992c94 329 }
j3sq 0:3dbb22992c94 330
j3sq 0:3dbb22992c94 331 /* Block if not configured */
j3sq 0:3dbb22992c94 332 while (!configured);
j3sq 0:3dbb22992c94 333
j3sq 0:3dbb22992c94 334 /* Send report */
j3sq 0:3dbb22992c94 335 complete = false;
j3sq 0:3dbb22992c94 336 disableEvents();
j3sq 0:3dbb22992c94 337 endpointWrite(EP1IN, report, size+1); /* +1 for report ID */
j3sq 0:3dbb22992c94 338 enableEvents();
j3sq 0:3dbb22992c94 339
j3sq 0:3dbb22992c94 340 /* Wait for completion */
j3sq 0:3dbb22992c94 341 while (!complete && configured);
j3sq 0:3dbb22992c94 342 return true;
j3sq 0:3dbb22992c94 343 }
j3sq 0:3dbb22992c94 344
j3sq 0:3dbb22992c94 345 void usbhid::endpointEventEP1In(void) {
j3sq 0:3dbb22992c94 346 complete = true;
j3sq 0:3dbb22992c94 347 }
j3sq 0:3dbb22992c94 348
j3sq 0:3dbb22992c94 349 bool usbhid::keyboard(char c) {
j3sq 0:3dbb22992c94 350 /* Send a simulated keyboard keypress. Returns true if successful. */
j3sq 0:3dbb22992c94 351 unsigned char report[8]={0,0,0,0,0,0,0,0};
j3sq 0:3dbb22992c94 352
j3sq 0:3dbb22992c94 353 report[0] = keymap[c].modifier;
j3sq 0:3dbb22992c94 354 report[2] = keymap[c].usage;
j3sq 0:3dbb22992c94 355
j3sq 0:3dbb22992c94 356 /* Key down */
j3sq 0:3dbb22992c94 357 if (!sendInputReport(REPORT_ID_KEYBOARD, report, 8)) {
j3sq 0:3dbb22992c94 358 return false;
j3sq 0:3dbb22992c94 359 }
j3sq 0:3dbb22992c94 360
j3sq 0:3dbb22992c94 361 /* Key up */
j3sq 0:3dbb22992c94 362 if (!sendInputReport(REPORT_ID_KEYBOARD, NULL, 8)) {
j3sq 0:3dbb22992c94 363 return false;
j3sq 0:3dbb22992c94 364 }
j3sq 0:3dbb22992c94 365
j3sq 0:3dbb22992c94 366 return true;
j3sq 0:3dbb22992c94 367 }
j3sq 0:3dbb22992c94 368
j3sq 0:3dbb22992c94 369 bool usbhid::keyboard(char *string) {
j3sq 0:3dbb22992c94 370 /* Send a string of characters. Returns true if successful. */
j3sq 0:3dbb22992c94 371 do {
j3sq 0:3dbb22992c94 372 if (!keyboard(*string++)) {
j3sq 0:3dbb22992c94 373 return false;
j3sq 0:3dbb22992c94 374 }
j3sq 0:3dbb22992c94 375 } while (*string != '\0');
j3sq 0:3dbb22992c94 376
j3sq 0:3dbb22992c94 377 return true;
j3sq 0:3dbb22992c94 378 }
j3sq 0:3dbb22992c94 379
j3sq 0:3dbb22992c94 380 bool usbhid::mouse(signed char x, signed char y, unsigned char buttons, signed char wheel) {
j3sq 0:3dbb22992c94 381 /* Send a simulated mouse event. Returns true if successful. */
j3sq 0:3dbb22992c94 382 unsigned char report[4]={0,0,0,0};
j3sq 0:3dbb22992c94 383
j3sq 0:3dbb22992c94 384 report[0] = buttons;
j3sq 0:3dbb22992c94 385 report[1] = x;
j3sq 0:3dbb22992c94 386 report[2] = y;
j3sq 0:3dbb22992c94 387 report[3] = wheel;
j3sq 0:3dbb22992c94 388
j3sq 0:3dbb22992c94 389 if (!sendInputReport(REPORT_ID_MOUSE, report, 4)) {
j3sq 0:3dbb22992c94 390 return false;
j3sq 0:3dbb22992c94 391 }
j3sq 0:3dbb22992c94 392
j3sq 0:3dbb22992c94 393 return true;
j3sq 0:3dbb22992c94 394 }
j3sq 0:3dbb22992c94 395
j3sq 0:3dbb22992c94 396
j3sq 0:3dbb22992c94 397 //
j3sq 0:3dbb22992c94 398 // USBJoystick
j3sq 0:3dbb22992c94 399 // Edit for different configurations (channels)
j3sq 0:3dbb22992c94 400
j3sq 0:3dbb22992c94 401 unsigned char reportDescriptorJoystick[] = {
j3sq 0:3dbb22992c94 402 USAGE_PAGE(1), 0x01, //Generic Desktop
j3sq 0:3dbb22992c94 403 USAGE(1), 0x04, //Joystiq
j3sq 0:3dbb22992c94 404 COLLECTION(1), 0x01, //Application
j3sq 0:3dbb22992c94 405 USAGE(1), 0x01,//Pointer
j3sq 0:3dbb22992c94 406 COLLECTION(1), 0x00,//Physical
j3sq 0:3dbb22992c94 407
j3sq 0:3dbb22992c94 408 USAGE_PAGE(1), 0x09,//Buttons
j3sq 0:3dbb22992c94 409 USAGE_MIN(1), 0x01,//Button 1
j3sq 0:3dbb22992c94 410 USAGE_MAX(1), 0x02,//Button 12 .....Changed here
j3sq 0:3dbb22992c94 411 LOGICAL_MIN(1), 0x00,//00
j3sq 0:3dbb22992c94 412 LOGICAL_MAX(1), 0x01,//01
j3sq 0:3dbb22992c94 413 PHYSICAL_MIN(1), 0x00,//00
j3sq 0:3dbb22992c94 414 PHYSICAL_MAX(1), 0x01,//01
j3sq 0:3dbb22992c94 415 REPORT_SIZE(1), 0x01,// 1 Bit size
j3sq 0:3dbb22992c94 416 REPORT_COUNT(1), 0x02,// 2 report
j3sq 0:3dbb22992c94 417 INPUT(1), 0x02,// Data , Var , Abs
j3sq 0:3dbb22992c94 418
j3sq 0:3dbb22992c94 419 REPORT_SIZE(1), 0x06,// 6 padding bits
j3sq 0:3dbb22992c94 420 REPORT_COUNT(1), 0x01,
j3sq 0:3dbb22992c94 421 INPUT(1), 0x03,// cnst , Vsr , Abs
j3sq 0:3dbb22992c94 422
j3sq 0:3dbb22992c94 423 //USAGE_PAGE(1), 0x01, //Generic Desktop
j3sq 0:3dbb22992c94 424 //USAGE(1), 0x39,// Hat switch
j3sq 0:3dbb22992c94 425 //LOGICAL_MIN(1), 0x00,// 00
j3sq 0:3dbb22992c94 426 //LOGICAL_MAX(1), 0x07,//07
j3sq 0:3dbb22992c94 427 //PHYSICAL_MIN(1), 0x00,//00
j3sq 0:3dbb22992c94 428 //PHYSICAL_MAX(2), 0x3B, 0x01,//315
j3sq 0:3dbb22992c94 429 //UNIT(1), 0x14,//English Rotation : Angular Position
j3sq 0:3dbb22992c94 430 //REPORT_SIZE(1), 0x04,//04
j3sq 0:3dbb22992c94 431 //REPORT_COUNT(1), 0x01,//01
j3sq 0:3dbb22992c94 432 //INPUT(1), 0x42,//Data, Var, Abs, Null
j3sq 0:3dbb22992c94 433
j3sq 0:3dbb22992c94 434 0x05, 0x02, // USAGE_PAGE (Simulation Controls)
j3sq 0:3dbb22992c94 435 0x09, 0xbb, // USAGE (Throttle)
j3sq 0:3dbb22992c94 436 0x09, 0xba, // USAGE (rudder)
j3sq 0:3dbb22992c94 437 0x15, 0x00, // LOGICAL_MINIMUM (0)
j3sq 0:3dbb22992c94 438 0x26, 0xff,0x00, // LOGICAL_MAXIMUM (255)
j3sq 0:3dbb22992c94 439 0x75, 0x08, // REPORT_SIZE (8)
j3sq 0:3dbb22992c94 440 0x95, 0x02, // REPORT_COUNT (2)
j3sq 0:3dbb22992c94 441 0x81, 0x02, // INPUT (Data,Var,Abs)
j3sq 0:3dbb22992c94 442
j3sq 0:3dbb22992c94 443 USAGE_PAGE(1), 0x01,//Generic Desktop
j3sq 0:3dbb22992c94 444 USAGE(1), 0x30,//x
j3sq 0:3dbb22992c94 445 USAGE(1), 0x31,//y
j3sq 0:3dbb22992c94 446 LOGICAL_MIN(1), 0x00,//00
j3sq 0:3dbb22992c94 447 LOGICAL_MAX(2), 0xff, 0x00,//255
j3sq 0:3dbb22992c94 448 PHYSICAL_MIN(1), 0x00,//00
j3sq 0:3dbb22992c94 449 PHYSICAL_MAX(2), 0xff, 0x00,//255
j3sq 0:3dbb22992c94 450 UNIT(2), 0x00, 0x00,//None 2 bytes
j3sq 0:3dbb22992c94 451 REPORT_SIZE(1), 0x08,//8 bits
j3sq 0:3dbb22992c94 452 REPORT_COUNT(1), 0x02,//2 reports (channels)
j3sq 0:3dbb22992c94 453 INPUT(1), 0x02,//Data, Var , Abs
j3sq 0:3dbb22992c94 454
j3sq 0:3dbb22992c94 455 END_COLLECTION(0),
j3sq 0:3dbb22992c94 456 END_COLLECTION(0),
j3sq 0:3dbb22992c94 457 };
j3sq 0:3dbb22992c94 458
j3sq 0:3dbb22992c94 459 USBJoystick::USBJoystick() {
j3sq 0:3dbb22992c94 460 int reportDescriptorSize = sizeof(reportDescriptorJoystick);
j3sq 0:3dbb22992c94 461 configurationDescriptor[25] = reportDescriptorSize & 0xff;
j3sq 0:3dbb22992c94 462 configurationDescriptor[26] = (reportDescriptorSize >> 8) & 0xff;
j3sq 0:3dbb22992c94 463
j3sq 0:3dbb22992c94 464 }
j3sq 0:3dbb22992c94 465
j3sq 0:3dbb22992c94 466 bool USBJoystick::requestGetDescriptor(void) {
j3sq 0:3dbb22992c94 467
j3sq 0:3dbb22992c94 468 bool success = false;
j3sq 0:3dbb22992c94 469
j3sq 0:3dbb22992c94 470 switch (DESCRIPTOR_TYPE(transfer.setup.wValue)) {
j3sq 0:3dbb22992c94 471 case REPORT_DESCRIPTOR:
j3sq 0:3dbb22992c94 472 transfer.remaining = sizeof(reportDescriptorJoystick);
j3sq 0:3dbb22992c94 473 transfer.ptr = reportDescriptorJoystick;
j3sq 0:3dbb22992c94 474 transfer.direction = DEVICE_TO_HOST;
j3sq 0:3dbb22992c94 475 success = true;
j3sq 0:3dbb22992c94 476 break;
j3sq 0:3dbb22992c94 477 default:
j3sq 0:3dbb22992c94 478 success = usbhid::requestGetDescriptor();
j3sq 0:3dbb22992c94 479 break;
j3sq 0:3dbb22992c94 480 }
j3sq 0:3dbb22992c94 481
j3sq 0:3dbb22992c94 482 return success;
j3sq 0:3dbb22992c94 483 }
j3sq 0:3dbb22992c94 484
j3sq 0:3dbb22992c94 485 bool USBJoystick::sendInputReport(unsigned char *data, unsigned char size) {
j3sq 0:3dbb22992c94 486 /* Send an Input Report */
j3sq 0:3dbb22992c94 487 /* If data is NULL an all zero report is sent */
j3sq 0:3dbb22992c94 488
j3sq 0:3dbb22992c94 489 static unsigned char report[MAX_REPORT_SIZE];
j3sq 0:3dbb22992c94 490 unsigned char i;
j3sq 0:3dbb22992c94 491
j3sq 0:3dbb22992c94 492 if (size > MAX_REPORT_SIZE) {
j3sq 0:3dbb22992c94 493 return false;
j3sq 0:3dbb22992c94 494 }
j3sq 0:3dbb22992c94 495
j3sq 0:3dbb22992c94 496 /* Add report data */
j3sq 0:3dbb22992c94 497 if (data != NULL) {
j3sq 0:3dbb22992c94 498 for (i=0; i<size; i++) {
j3sq 0:3dbb22992c94 499 report[i] = *data++;
j3sq 0:3dbb22992c94 500 }
j3sq 0:3dbb22992c94 501 } else {
j3sq 0:3dbb22992c94 502 for (i=0; i<size; i++) {
j3sq 0:3dbb22992c94 503 report[i] = 0;
j3sq 0:3dbb22992c94 504 }
j3sq 0:3dbb22992c94 505 }
j3sq 0:3dbb22992c94 506
j3sq 0:3dbb22992c94 507 /* Block if not configured */
j3sq 0:3dbb22992c94 508 while (!configured) {
j3sq 0:3dbb22992c94 509 //errorLED=1; delete here
j3sq 0:3dbb22992c94 510 }
j3sq 0:3dbb22992c94 511 //okLED=1; delete here
j3sq 0:3dbb22992c94 512 /* Send report */
j3sq 0:3dbb22992c94 513 complete = false;
j3sq 0:3dbb22992c94 514 disableEvents();
j3sq 0:3dbb22992c94 515 endpointWrite(EP1IN, report, size);
j3sq 0:3dbb22992c94 516 enableEvents();
j3sq 0:3dbb22992c94 517
j3sq 0:3dbb22992c94 518 /* Wait for completion */
j3sq 0:3dbb22992c94 519 while (!complete && configured);
j3sq 0:3dbb22992c94 520 return true;
j3sq 0:3dbb22992c94 521 }
j3sq 0:3dbb22992c94 522
j3sq 0:3dbb22992c94 523 bool USBJoystick::joystick(unsigned char throttle, unsigned char rudder, unsigned char x, unsigned char y, bool button1, bool button2) {
j3sq 0:3dbb22992c94 524
j3sq 0:3dbb22992c94 525 unsigned char report[6] = {0, 0, 0, 0, 0,0};
j3sq 0:3dbb22992c94 526 unsigned char buttons=0x00;
j3sq 0:3dbb22992c94 527
j3sq 0:3dbb22992c94 528 if (button1) buttons= buttons | 0x01;
j3sq 0:3dbb22992c94 529 if (button2) buttons= buttons | 0x02;
j3sq 0:3dbb22992c94 530 report[0] = buttons;//Buttons
j3sq 0:3dbb22992c94 531 report[1] = throttle; //Throttle
j3sq 0:3dbb22992c94 532 report[2] = rudder; //Rudder
j3sq 0:3dbb22992c94 533 report[3] = x; //X
j3sq 0:3dbb22992c94 534 report[4] = y;//Y
j3sq 0:3dbb22992c94 535
j3sq 0:3dbb22992c94 536
j3sq 0:3dbb22992c94 537
j3sq 0:3dbb22992c94 538 if (!sendInputReport(report, 5)) {
j3sq 0:3dbb22992c94 539
j3sq 0:3dbb22992c94 540 return false;
j3sq 0:3dbb22992c94 541
j3sq 0:3dbb22992c94 542 }
j3sq 0:3dbb22992c94 543 // okLED=1;.....Delete here
j3sq 0:3dbb22992c94 544 return true;
j3sq 0:3dbb22992c94 545 }
j3sq 0:3dbb22992c94 546