RC_Simulator.....By Jafar Qutteineh with mods to connect my Futaba 9C to \'RC Helicopter\' by http://www.alphamacsoftware.com/

Dependencies:   mbed

Committer:
cbayley
Date:
Thu Dec 15 03:24:33 2011 +0000
Revision:
0:65b9d8f621d2
Initial

Who changed what in which revision?

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