USB Mouse by JoyStick

Dependencies:   mbed

Committer:
yueee_yt
Date:
Thu Jun 09 12:23:08 2011 +0000
Revision:
0:006c6d72bb7d

        

Who changed what in which revision?

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