Xbox 360 Wireless Controller for Windows library. sample: http://mbed.org/users/okini3939/code/USBHostXpad_HelloWorld/

Dependents:   x4180_Tank Totaleprogramma Handmatig Totaleprogramma1

Fork of USBHostXpad by Suga koubou

Committer:
hotwheelharry
Date:
Wed Nov 26 22:51:48 2014 +0000
Revision:
5:bbbbd88de858
Parent:
4:4254192898a9
turn off debug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:bd0f6bf72a8b 1 /*
okini3939 0:bd0f6bf72a8b 2 * Xbox 360 Wireless Controller for Windows library
okini3939 0:bd0f6bf72a8b 3 * for mbed USBHost library
okini3939 0:bd0f6bf72a8b 4 * Copyright (c) 2013 Hiroshi Suga
okini3939 0:bd0f6bf72a8b 5 *
okini3939 0:bd0f6bf72a8b 6 * VID=0x045e PID=0x0719
okini3939 0:bd0f6bf72a8b 7 *
okini3939 1:5bb153989f33 8 * Reference:
okini3939 3:53ce7778a155 9 * https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL
okini3939 3:53ce7778a155 10 * http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller
okini3939 0:bd0f6bf72a8b 11 */
okini3939 0:bd0f6bf72a8b 12
okini3939 0:bd0f6bf72a8b 13 #include "USBHostXpad.h"
okini3939 0:bd0f6bf72a8b 14
okini3939 0:bd0f6bf72a8b 15 #if 1 or USBHOST_XPAD
okini3939 0:bd0f6bf72a8b 16
okini3939 0:bd0f6bf72a8b 17 #include "dbg.h"
okini3939 0:bd0f6bf72a8b 18
okini3939 0:bd0f6bf72a8b 19 #define DEVICE_TO_HOST 0x80
okini3939 0:bd0f6bf72a8b 20 #define HOST_TO_DEVICE 0x00
okini3939 0:bd0f6bf72a8b 21
okini3939 0:bd0f6bf72a8b 22 USBHostXpad::USBHostXpad()
okini3939 0:bd0f6bf72a8b 23 {
okini3939 0:bd0f6bf72a8b 24 host = USBHost::getHostInst();
okini3939 0:bd0f6bf72a8b 25 init();
okini3939 0:bd0f6bf72a8b 26 }
okini3939 0:bd0f6bf72a8b 27
okini3939 0:bd0f6bf72a8b 28 void USBHostXpad::init() {
okini3939 0:bd0f6bf72a8b 29 dev_connected = false;
okini3939 0:bd0f6bf72a8b 30 dev = NULL;
okini3939 0:bd0f6bf72a8b 31 int_in = NULL;
okini3939 0:bd0f6bf72a8b 32 int_out = NULL;
okini3939 0:bd0f6bf72a8b 33 xpad_intf = -1;
okini3939 0:bd0f6bf72a8b 34 xpad_device_found = false;
okini3939 0:bd0f6bf72a8b 35 nb_ep = 0;
okini3939 3:53ce7778a155 36 dev_type = TYPE_UNKNOWN;
okini3939 3:53ce7778a155 37 dev_started = false;
okini3939 0:bd0f6bf72a8b 38 }
okini3939 0:bd0f6bf72a8b 39
okini3939 0:bd0f6bf72a8b 40 bool USBHostXpad::connected()
okini3939 0:bd0f6bf72a8b 41 {
okini3939 0:bd0f6bf72a8b 42 return dev_connected;
okini3939 0:bd0f6bf72a8b 43 }
okini3939 0:bd0f6bf72a8b 44
okini3939 0:bd0f6bf72a8b 45 bool USBHostXpad::connect()
okini3939 0:bd0f6bf72a8b 46 {
okini3939 0:bd0f6bf72a8b 47
okini3939 0:bd0f6bf72a8b 48 if (dev_connected) {
okini3939 0:bd0f6bf72a8b 49 return true;
okini3939 0:bd0f6bf72a8b 50 }
okini3939 0:bd0f6bf72a8b 51
okini3939 3:53ce7778a155 52 for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
okini3939 0:bd0f6bf72a8b 53 if ((dev = host->getDevice(i)) != NULL) {
okini3939 0:bd0f6bf72a8b 54
hotwheelharry 5:bbbbd88de858 55 //USB_DBG("Trying to connect MSD device\r\n");
okini3939 0:bd0f6bf72a8b 56
okini3939 3:53ce7778a155 57 if(host->enumerate(dev, this)) break;
okini3939 0:bd0f6bf72a8b 58
okini3939 0:bd0f6bf72a8b 59 if (xpad_device_found) {
okini3939 0:bd0f6bf72a8b 60 int_in = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, IN);
okini3939 0:bd0f6bf72a8b 61 int_out = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, OUT);
okini3939 0:bd0f6bf72a8b 62
okini3939 3:53ce7778a155 63 if (!int_in || !int_out) continue;
okini3939 0:bd0f6bf72a8b 64
okini3939 0:bd0f6bf72a8b 65 USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, xpad_intf);
okini3939 0:bd0f6bf72a8b 66 dev->setName("XPAD", xpad_intf);
okini3939 0:bd0f6bf72a8b 67 host->registerDriver(dev, xpad_intf, this, &USBHostXpad::init);
okini3939 1:5bb153989f33 68 int_in->attach(this, &USBHostXpad::rxHandler);
okini3939 1:5bb153989f33 69 host->interruptRead(dev, int_in, report, int_in->getSize(), false);
okini3939 0:bd0f6bf72a8b 70
okini3939 1:5bb153989f33 71 Thread::wait(100);
okini3939 2:2749f4e649db 72 led(LED_OFF);
okini3939 0:bd0f6bf72a8b 73 dev_connected = true;
okini3939 0:bd0f6bf72a8b 74 return true;
okini3939 0:bd0f6bf72a8b 75 }
okini3939 0:bd0f6bf72a8b 76
okini3939 1:5bb153989f33 77 }
okini3939 1:5bb153989f33 78 }
okini3939 0:bd0f6bf72a8b 79 init();
okini3939 0:bd0f6bf72a8b 80 return false;
okini3939 0:bd0f6bf72a8b 81 }
okini3939 0:bd0f6bf72a8b 82
okini3939 0:bd0f6bf72a8b 83 void USBHostXpad::rxHandler() {
okini3939 0:bd0f6bf72a8b 84 int len_listen = int_in->getSize();
okini3939 0:bd0f6bf72a8b 85 int len = int_in->getLengthTransferred();
okini3939 0:bd0f6bf72a8b 86
okini3939 1:5bb153989f33 87 /*
okini3939 0:bd0f6bf72a8b 88 for (int i = 0; i < len_listen; i ++) {
okini3939 0:bd0f6bf72a8b 89 std::printf(" %02x", report[i]);
okini3939 0:bd0f6bf72a8b 90 }
okini3939 0:bd0f6bf72a8b 91 std::printf("\r\n");
okini3939 1:5bb153989f33 92 */
okini3939 3:53ce7778a155 93 if (dev_type == TYPE_XBOX) {
okini3939 3:53ce7778a155 94 parseMessage();
okini3939 3:53ce7778a155 95 } else
okini3939 3:53ce7778a155 96 if (report[0] == 0x08) {
okini3939 3:53ce7778a155 97 if (report[1] == 0x80) {
okini3939 3:53ce7778a155 98 // Connection Status Messages
okini3939 3:53ce7778a155 99 start();
okini3939 3:53ce7778a155 100 } else
okini3939 3:53ce7778a155 101 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 102 // Disconnected Status Messages
okini3939 3:53ce7778a155 103 dev_started = false;
okini3939 3:53ce7778a155 104 }
okini3939 0:bd0f6bf72a8b 105 } else
okini3939 3:53ce7778a155 106 if (report[0] == 0x00) {
okini3939 3:53ce7778a155 107 if ((report[1] == 0x14) ||
okini3939 3:53ce7778a155 108 (report[1] == 0x01 && report[2] == 0x00 && report[3] == 0xf0)) {
okini3939 3:53ce7778a155 109 // Event data
okini3939 3:53ce7778a155 110 parseMessage();
okini3939 3:53ce7778a155 111 } else
okini3939 3:53ce7778a155 112 if (report[1] == 0x0f) {
okini3939 3:53ce7778a155 113 // On connection
okini3939 3:53ce7778a155 114 led(LED1_ON);
okini3939 3:53ce7778a155 115 start();
okini3939 3:53ce7778a155 116 dev_started = true;
okini3939 3:53ce7778a155 117 } else
okini3939 3:53ce7778a155 118 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 119 if (report[3] == 0x13) {
okini3939 3:53ce7778a155 120 // Battery charge level
okini3939 3:53ce7778a155 121 battery = report[4];
okini3939 3:53ce7778a155 122 } else
okini3939 3:53ce7778a155 123 if (report[3] == 0xf0) {
okini3939 3:53ce7778a155 124 // Device low power mode (HID updates will stop until controller inputs change)
okini3939 4:4254192898a9 125 // restart();
okini3939 3:53ce7778a155 126 }
okini3939 3:53ce7778a155 127 } else
okini3939 3:53ce7778a155 128 if (report[1] == 0xf8) {
okini3939 3:53ce7778a155 129 // Status Messages ?
okini3939 3:53ce7778a155 130 }
okini3939 3:53ce7778a155 131 } else {
okini3939 1:5bb153989f33 132 // Unknown
okini3939 1:5bb153989f33 133 USB_INFO("rxHandler len:%d data:%02x %02x %02x %02x", len, report[0], report[1], report[2], report[3]);
okini3939 0:bd0f6bf72a8b 134 }
okini3939 0:bd0f6bf72a8b 135
okini3939 3:53ce7778a155 136 if (dev) {
okini3939 3:53ce7778a155 137 host->interruptRead(dev, int_in, report, len_listen, false);
okini3939 0:bd0f6bf72a8b 138 }
okini3939 0:bd0f6bf72a8b 139 }
okini3939 0:bd0f6bf72a8b 140
okini3939 0:bd0f6bf72a8b 141 /*virtual*/ void USBHostXpad::setVidPid(uint16_t vid, uint16_t pid)
okini3939 0:bd0f6bf72a8b 142 {
okini3939 0:bd0f6bf72a8b 143 // we don't check VID/PID for MSD driver
okini3939 3:53ce7778a155 144 if (vid == 0x045e && (pid == 0x0202 || pid == 0x0285 || pid == 0x0287 || pid == 0x0289)) {
okini3939 3:53ce7778a155 145 dev_type = TYPE_XBOX;
okini3939 3:53ce7778a155 146 } else
okini3939 3:53ce7778a155 147 if (vid == 0x045e && pid == 0x028e) {
okini3939 3:53ce7778a155 148 dev_type = TYPE_XBOX360;
okini3939 3:53ce7778a155 149 } else
okini3939 3:53ce7778a155 150 if (vid == 0x045e && pid == 0x0719) {
okini3939 3:53ce7778a155 151 dev_type = TYPE_XBOX360W;
okini3939 3:53ce7778a155 152 }
okini3939 3:53ce7778a155 153 USB_INFO("setVidPid vid:%04x pid:%04x xbox:%d", vid, pid, dev_type);
okini3939 0:bd0f6bf72a8b 154 }
okini3939 0:bd0f6bf72a8b 155
okini3939 0:bd0f6bf72a8b 156 /*virtual*/ bool USBHostXpad::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
okini3939 0:bd0f6bf72a8b 157 {
okini3939 0:bd0f6bf72a8b 158 USB_INFO("parseInterface class:%02x subclass:%02x protocol:%02x [nb: %d - intf: %d]", intf_class, intf_subclass, intf_protocol, intf_nb, xpad_intf);
okini3939 3:53ce7778a155 159 if ((xpad_intf == -1) && (intf_class == 0x58) && (intf_subclass == 0x42) && (intf_protocol == 0x00)) {
okini3939 3:53ce7778a155 160 xpad_intf = intf_nb; // XBOX ?
okini3939 3:53ce7778a155 161 return true;
okini3939 3:53ce7778a155 162 }
okini3939 3:53ce7778a155 163 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x81)) {
okini3939 3:53ce7778a155 164 xpad_intf = intf_nb; // XBOX360W
okini3939 0:bd0f6bf72a8b 165 return true;
okini3939 0:bd0f6bf72a8b 166 }
okini3939 0:bd0f6bf72a8b 167 return false;
okini3939 0:bd0f6bf72a8b 168 }
okini3939 0:bd0f6bf72a8b 169
okini3939 0:bd0f6bf72a8b 170 /*virtual*/ bool USBHostXpad::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
okini3939 0:bd0f6bf72a8b 171 {
okini3939 0:bd0f6bf72a8b 172 USB_INFO("useEndpoint nb:%d type:%d dir:%d", intf_nb, type, dir);
okini3939 0:bd0f6bf72a8b 173 if (intf_nb == xpad_intf) {
okini3939 0:bd0f6bf72a8b 174 if (type == INTERRUPT_ENDPOINT) {
okini3939 0:bd0f6bf72a8b 175 nb_ep ++;
okini3939 3:53ce7778a155 176 if (nb_ep == 2) {
okini3939 0:bd0f6bf72a8b 177 xpad_device_found = true;
okini3939 3:53ce7778a155 178 }
okini3939 0:bd0f6bf72a8b 179 return true;
okini3939 0:bd0f6bf72a8b 180 }
okini3939 0:bd0f6bf72a8b 181 }
okini3939 0:bd0f6bf72a8b 182 return false;
okini3939 0:bd0f6bf72a8b 183 }
okini3939 0:bd0f6bf72a8b 184
okini3939 3:53ce7778a155 185
okini3939 3:53ce7778a155 186 void USBHostXpad::parseMessage()
okini3939 0:bd0f6bf72a8b 187 {
okini3939 3:53ce7778a155 188 uint8_t *data = report;
okini3939 3:53ce7778a155 189
okini3939 3:53ce7778a155 190 switch (dev_type) {
okini3939 3:53ce7778a155 191 case TYPE_XBOX:
okini3939 3:53ce7778a155 192 buttons = ((uint32_t)report[3] << 8) | report[2];
okini3939 3:53ce7778a155 193 if (report[4]) buttons |= XPAD_PAD_A;
okini3939 3:53ce7778a155 194 if (report[5]) buttons |= XPAD_PAD_B;
okini3939 3:53ce7778a155 195 if (report[6]) buttons |= XPAD_PAD_X;
okini3939 3:53ce7778a155 196 if (report[7]) buttons |= XPAD_PAD_Y;
okini3939 3:53ce7778a155 197 trigger_l = data[10];
okini3939 3:53ce7778a155 198 trigger_r = data[11];
okini3939 3:53ce7778a155 199
okini3939 3:53ce7778a155 200 stick_lx = ((int16_t)report[13] << 8) | report[12];
okini3939 3:53ce7778a155 201 stick_ly = ((int16_t)report[15] << 8) | report[14];
okini3939 3:53ce7778a155 202 stick_rx = ((int16_t)report[17] << 8) | report[16];
okini3939 3:53ce7778a155 203 stick_ry = ((int16_t)report[19] << 8) | report[18];
okini3939 3:53ce7778a155 204 break;
okini3939 3:53ce7778a155 205 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 206 data += 4;
okini3939 3:53ce7778a155 207 case TYPE_XBOX360:
okini3939 3:53ce7778a155 208 buttons = ((uint32_t)data[3] << 8) | data[2];
okini3939 3:53ce7778a155 209 trigger_l = data[4];
okini3939 3:53ce7778a155 210 trigger_r = data[5];
okini3939 3:53ce7778a155 211
okini3939 3:53ce7778a155 212 stick_lx = ((int16_t)data[7] << 8) | data[6];
okini3939 3:53ce7778a155 213 stick_ly = ((int16_t)data[9] << 8) | data[8];
okini3939 3:53ce7778a155 214 stick_rx = ((int16_t)data[11] << 8) | data[10];
okini3939 3:53ce7778a155 215 stick_ry = ((int16_t)data[13] << 8) | data[12];
okini3939 3:53ce7778a155 216 break;
okini3939 3:53ce7778a155 217 default:
okini3939 2:2749f4e649db 218 return;
okini3939 2:2749f4e649db 219 }
okini3939 3:53ce7778a155 220
okini3939 3:53ce7778a155 221 if (onUpdate) {
okini3939 3:53ce7778a155 222 (*onUpdate)(buttons, stick_lx, stick_ly, stick_rx, stick_ry, trigger_l, trigger_r);
okini3939 3:53ce7778a155 223 }
okini3939 0:bd0f6bf72a8b 224 }
okini3939 0:bd0f6bf72a8b 225
okini3939 3:53ce7778a155 226 bool USBHostXpad::restart ()
okini3939 0:bd0f6bf72a8b 227 {
okini3939 1:5bb153989f33 228 unsigned char odata[32];
okini3939 1:5bb153989f33 229 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 230 odata[0] = 0x08;
okini3939 3:53ce7778a155 231 odata[2] = 0x0f;
okini3939 3:53ce7778a155 232 odata[3] = 0xc0;
okini3939 3:53ce7778a155 233 if (dev) {
okini3939 3:53ce7778a155 234 for (int i = 0; i < 4; i ++) {
okini3939 3:53ce7778a155 235 host->interruptWrite(dev, int_out, odata, 12);
okini3939 1:5bb153989f33 236 }
okini3939 3:53ce7778a155 237 }
okini3939 0:bd0f6bf72a8b 238 return true;
okini3939 0:bd0f6bf72a8b 239 }
okini3939 0:bd0f6bf72a8b 240
okini3939 3:53ce7778a155 241 int USBHostXpad::read (PAD pad)
okini3939 3:53ce7778a155 242 {
okini3939 3:53ce7778a155 243 switch (pad) {
okini3939 3:53ce7778a155 244 case XPAD_BUTTONS:
okini3939 3:53ce7778a155 245 return buttons;
okini3939 2:2749f4e649db 246 case XPAD_STICK_LX:
okini3939 2:2749f4e649db 247 return stick_lx;
okini3939 2:2749f4e649db 248 case XPAD_STICK_LY:
okini3939 2:2749f4e649db 249 return stick_ly;
okini3939 2:2749f4e649db 250 case XPAD_STICK_RX:
okini3939 2:2749f4e649db 251 return stick_rx;
okini3939 2:2749f4e649db 252 case XPAD_STICK_RY:
okini3939 2:2749f4e649db 253 return stick_ry;
okini3939 2:2749f4e649db 254 case XPAD_TRIGGER_L:
okini3939 2:2749f4e649db 255 return trigger_l;
okini3939 2:2749f4e649db 256 case XPAD_TRIGGER_R:
okini3939 2:2749f4e649db 257 return trigger_r;
okini3939 3:53ce7778a155 258 case XPAD_BATTERY:
okini3939 3:53ce7778a155 259 return battery;
okini3939 2:2749f4e649db 260 default:
okini3939 3:53ce7778a155 261 return (buttons & pad) ? 1 : 0;
okini3939 3:53ce7778a155 262 }
okini3939 3:53ce7778a155 263 }
okini3939 3:53ce7778a155 264
okini3939 3:53ce7778a155 265 bool USBHostXpad::start()
okini3939 3:53ce7778a155 266 {
okini3939 3:53ce7778a155 267 unsigned char odata[32];
okini3939 3:53ce7778a155 268 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 269 odata[3] = 0x40;
okini3939 3:53ce7778a155 270 if (dev) {
okini3939 3:53ce7778a155 271 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 3:53ce7778a155 272 return false;
okini3939 3:53ce7778a155 273 }
okini3939 2:2749f4e649db 274 }
okini3939 3:53ce7778a155 275 return true;
okini3939 3:53ce7778a155 276 }
okini3939 3:53ce7778a155 277
okini3939 3:53ce7778a155 278 bool USBHostXpad::stop()
okini3939 3:53ce7778a155 279 {
okini3939 3:53ce7778a155 280 unsigned char odata[32];
okini3939 3:53ce7778a155 281 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 282 odata[2] = 0x08;
okini3939 3:53ce7778a155 283 odata[3] = 0xc0;
okini3939 3:53ce7778a155 284 if (dev) {
okini3939 3:53ce7778a155 285 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 3:53ce7778a155 286 return false;
okini3939 3:53ce7778a155 287 }
okini3939 3:53ce7778a155 288 }
okini3939 3:53ce7778a155 289 return true;
okini3939 2:2749f4e649db 290 }
okini3939 2:2749f4e649db 291
okini3939 2:2749f4e649db 292 bool USBHostXpad::led(LED cmd)
okini3939 0:bd0f6bf72a8b 293 {
okini3939 0:bd0f6bf72a8b 294 unsigned char odata[32];
okini3939 1:5bb153989f33 295 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 296 switch (dev_type) {
okini3939 3:53ce7778a155 297 case TYPE_XBOX:
okini3939 3:53ce7778a155 298 return true;
okini3939 3:53ce7778a155 299 case TYPE_XBOX360:
okini3939 3:53ce7778a155 300 odata[0] = 0x01;
okini3939 3:53ce7778a155 301 odata[1] = 0x03;
okini3939 3:53ce7778a155 302 odata[2] = cmd;
okini3939 3:53ce7778a155 303 break;
okini3939 3:53ce7778a155 304 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 305 odata[2] = 0x08;
okini3939 3:53ce7778a155 306 odata[3] = 0x40 + (cmd % 0x0e);
okini3939 3:53ce7778a155 307 break;
okini3939 3:53ce7778a155 308 default:
okini3939 3:53ce7778a155 309 return false;
okini3939 3:53ce7778a155 310 }
okini3939 3:53ce7778a155 311 if (dev) {
okini3939 3:53ce7778a155 312 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 313 return false;
okini3939 3:53ce7778a155 314 }
okini3939 3:53ce7778a155 315 }
okini3939 1:5bb153989f33 316 return true;
okini3939 1:5bb153989f33 317 }
okini3939 0:bd0f6bf72a8b 318
okini3939 1:5bb153989f33 319 bool USBHostXpad::rumble(uint8_t large, uint8_t small)
okini3939 1:5bb153989f33 320 {
okini3939 1:5bb153989f33 321 unsigned char odata[32];
okini3939 1:5bb153989f33 322 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 323 switch (dev_type) {
okini3939 3:53ce7778a155 324 case TYPE_XBOX:
okini3939 3:53ce7778a155 325 odata[1] = 0x06;
okini3939 3:53ce7778a155 326 odata[3] = small;
okini3939 3:53ce7778a155 327 odata[5] = large;
okini3939 3:53ce7778a155 328 break;
okini3939 3:53ce7778a155 329 case TYPE_XBOX360:
okini3939 3:53ce7778a155 330 odata[1] = 0x08;
okini3939 3:53ce7778a155 331 odata[3] = large;
okini3939 3:53ce7778a155 332 odata[4] = small;
okini3939 3:53ce7778a155 333 break;
okini3939 3:53ce7778a155 334 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 335 odata[1] = 0x01;
okini3939 3:53ce7778a155 336 odata[2] = 0x0f;
okini3939 3:53ce7778a155 337 odata[3] = 0xc0;
okini3939 3:53ce7778a155 338 odata[5] = large;
okini3939 3:53ce7778a155 339 odata[6] = small;
okini3939 3:53ce7778a155 340 break;
okini3939 3:53ce7778a155 341 default:
okini3939 3:53ce7778a155 342 return false;
okini3939 3:53ce7778a155 343 }
okini3939 3:53ce7778a155 344 if (dev) {
okini3939 3:53ce7778a155 345 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 346 return false;
okini3939 3:53ce7778a155 347 }
okini3939 3:53ce7778a155 348 }
okini3939 0:bd0f6bf72a8b 349 return true;
okini3939 0:bd0f6bf72a8b 350 }
okini3939 0:bd0f6bf72a8b 351
okini3939 0:bd0f6bf72a8b 352 #endif
okini3939 0:bd0f6bf72a8b 353