modified to compile for me

Dependents:   N64_Output_XPAD

Fork of USBHostXpad by Suga koubou

Committer:
Ownasaurus
Date:
Fri Nov 04 21:29:16 2016 +0000
Revision:
5:e0ed758abbdb
Parent:
4:4254192898a9
Child:
6:954ecd99709c
support afterglow wired 360 controller

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
okini3939 0:bd0f6bf72a8b 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
Ownasaurus 5:e0ed758abbdb 65 USB_INFO("New Xpad 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
Ownasaurus 5:e0ed758abbdb 71 wait_ms(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
Ownasaurus 5:e0ed758abbdb 87
Ownasaurus 5:e0ed758abbdb 88 /*for (int i = 0; i < len_listen; i ++) {
okini3939 0:bd0f6bf72a8b 89 std::printf(" %02x", report[i]);
okini3939 0:bd0f6bf72a8b 90 }
Ownasaurus 5:e0ed758abbdb 91 std::printf("\r\n");*/
Ownasaurus 5:e0ed758abbdb 92
Ownasaurus 5:e0ed758abbdb 93
okini3939 3:53ce7778a155 94 if (dev_type == TYPE_XBOX) {
okini3939 3:53ce7778a155 95 parseMessage();
okini3939 3:53ce7778a155 96 } else
okini3939 3:53ce7778a155 97 if (report[0] == 0x08) {
Ownasaurus 5:e0ed758abbdb 98 if (report[1] == 0x80 || /*x360 headset status*/report[1] == 0x80) {
okini3939 3:53ce7778a155 99 // Connection Status Messages
okini3939 3:53ce7778a155 100 start();
okini3939 3:53ce7778a155 101 } else
okini3939 3:53ce7778a155 102 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 103 // Disconnected Status Messages
okini3939 3:53ce7778a155 104 dev_started = false;
okini3939 3:53ce7778a155 105 }
okini3939 0:bd0f6bf72a8b 106 } else
Ownasaurus 5:e0ed758abbdb 107 if (report[0] == 0x01) { // X360 led
Ownasaurus 5:e0ed758abbdb 108 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 109 } else
Ownasaurus 5:e0ed758abbdb 110 if (report[0] == 0x02) { // X360 unknown
Ownasaurus 5:e0ed758abbdb 111 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 112 } else
Ownasaurus 5:e0ed758abbdb 113 if (report[0] == 0x03) { // X360 rumble
Ownasaurus 5:e0ed758abbdb 114 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 115 } else
okini3939 3:53ce7778a155 116 if (report[0] == 0x00) {
okini3939 3:53ce7778a155 117 if ((report[1] == 0x14) ||
okini3939 3:53ce7778a155 118 (report[1] == 0x01 && report[2] == 0x00 && report[3] == 0xf0)) {
okini3939 3:53ce7778a155 119 // Event data
okini3939 3:53ce7778a155 120 parseMessage();
okini3939 3:53ce7778a155 121 } else
okini3939 3:53ce7778a155 122 if (report[1] == 0x0f) {
okini3939 3:53ce7778a155 123 // On connection
okini3939 3:53ce7778a155 124 led(LED1_ON);
okini3939 3:53ce7778a155 125 start();
okini3939 3:53ce7778a155 126 dev_started = true;
okini3939 3:53ce7778a155 127 } else
okini3939 3:53ce7778a155 128 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 129 if (report[3] == 0x13) {
okini3939 3:53ce7778a155 130 // Battery charge level
okini3939 3:53ce7778a155 131 battery = report[4];
okini3939 3:53ce7778a155 132 } else
okini3939 3:53ce7778a155 133 if (report[3] == 0xf0) {
okini3939 3:53ce7778a155 134 // Device low power mode (HID updates will stop until controller inputs change)
okini3939 4:4254192898a9 135 // restart();
okini3939 3:53ce7778a155 136 }
okini3939 3:53ce7778a155 137 } else
okini3939 3:53ce7778a155 138 if (report[1] == 0xf8) {
okini3939 3:53ce7778a155 139 // Status Messages ?
okini3939 3:53ce7778a155 140 }
okini3939 3:53ce7778a155 141 } else {
okini3939 1:5bb153989f33 142 // Unknown
okini3939 1:5bb153989f33 143 USB_INFO("rxHandler len:%d data:%02x %02x %02x %02x", len, report[0], report[1], report[2], report[3]);
okini3939 0:bd0f6bf72a8b 144 }
okini3939 0:bd0f6bf72a8b 145
okini3939 3:53ce7778a155 146 if (dev) {
okini3939 3:53ce7778a155 147 host->interruptRead(dev, int_in, report, len_listen, false);
okini3939 0:bd0f6bf72a8b 148 }
okini3939 0:bd0f6bf72a8b 149 }
okini3939 0:bd0f6bf72a8b 150
okini3939 0:bd0f6bf72a8b 151 /*virtual*/ void USBHostXpad::setVidPid(uint16_t vid, uint16_t pid)
okini3939 0:bd0f6bf72a8b 152 {
okini3939 0:bd0f6bf72a8b 153 // we don't check VID/PID for MSD driver
okini3939 3:53ce7778a155 154 if (vid == 0x045e && (pid == 0x0202 || pid == 0x0285 || pid == 0x0287 || pid == 0x0289)) {
okini3939 3:53ce7778a155 155 dev_type = TYPE_XBOX;
okini3939 3:53ce7778a155 156 } else
Ownasaurus 5:e0ed758abbdb 157 if ((vid == 0x045e && pid == 0x028e) || /*my afterglow addition!*/(vid == 0x0e6f && pid == 0x0213)) {
okini3939 3:53ce7778a155 158 dev_type = TYPE_XBOX360;
okini3939 3:53ce7778a155 159 } else
okini3939 3:53ce7778a155 160 if (vid == 0x045e && pid == 0x0719) {
okini3939 3:53ce7778a155 161 dev_type = TYPE_XBOX360W;
okini3939 3:53ce7778a155 162 }
okini3939 3:53ce7778a155 163 USB_INFO("setVidPid vid:%04x pid:%04x xbox:%d", vid, pid, dev_type);
okini3939 0:bd0f6bf72a8b 164 }
okini3939 0:bd0f6bf72a8b 165
okini3939 0:bd0f6bf72a8b 166 /*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 167 {
okini3939 0:bd0f6bf72a8b 168 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 169 if ((xpad_intf == -1) && (intf_class == 0x58) && (intf_subclass == 0x42) && (intf_protocol == 0x00)) {
okini3939 3:53ce7778a155 170 xpad_intf = intf_nb; // XBOX ?
okini3939 3:53ce7778a155 171 return true;
okini3939 3:53ce7778a155 172 }
okini3939 3:53ce7778a155 173 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x81)) {
okini3939 3:53ce7778a155 174 xpad_intf = intf_nb; // XBOX360W
okini3939 0:bd0f6bf72a8b 175 return true;
okini3939 0:bd0f6bf72a8b 176 }
Ownasaurus 5:e0ed758abbdb 177 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x01)) {
Ownasaurus 5:e0ed758abbdb 178 xpad_intf = intf_nb; // XBOX360 WIRED AFTERGLOW
Ownasaurus 5:e0ed758abbdb 179 return true;
Ownasaurus 5:e0ed758abbdb 180 }
okini3939 0:bd0f6bf72a8b 181 return false;
okini3939 0:bd0f6bf72a8b 182 }
okini3939 0:bd0f6bf72a8b 183
okini3939 0:bd0f6bf72a8b 184 /*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 185 {
okini3939 0:bd0f6bf72a8b 186 USB_INFO("useEndpoint nb:%d type:%d dir:%d", intf_nb, type, dir);
okini3939 0:bd0f6bf72a8b 187 if (intf_nb == xpad_intf) {
okini3939 0:bd0f6bf72a8b 188 if (type == INTERRUPT_ENDPOINT) {
okini3939 0:bd0f6bf72a8b 189 nb_ep ++;
okini3939 3:53ce7778a155 190 if (nb_ep == 2) {
okini3939 0:bd0f6bf72a8b 191 xpad_device_found = true;
okini3939 3:53ce7778a155 192 }
okini3939 0:bd0f6bf72a8b 193 return true;
okini3939 0:bd0f6bf72a8b 194 }
okini3939 0:bd0f6bf72a8b 195 }
okini3939 0:bd0f6bf72a8b 196 return false;
okini3939 0:bd0f6bf72a8b 197 }
okini3939 0:bd0f6bf72a8b 198
okini3939 3:53ce7778a155 199
okini3939 3:53ce7778a155 200 void USBHostXpad::parseMessage()
okini3939 0:bd0f6bf72a8b 201 {
okini3939 3:53ce7778a155 202 uint8_t *data = report;
okini3939 3:53ce7778a155 203
okini3939 3:53ce7778a155 204 switch (dev_type) {
okini3939 3:53ce7778a155 205 case TYPE_XBOX:
okini3939 3:53ce7778a155 206 buttons = ((uint32_t)report[3] << 8) | report[2];
okini3939 3:53ce7778a155 207 if (report[4]) buttons |= XPAD_PAD_A;
okini3939 3:53ce7778a155 208 if (report[5]) buttons |= XPAD_PAD_B;
okini3939 3:53ce7778a155 209 if (report[6]) buttons |= XPAD_PAD_X;
okini3939 3:53ce7778a155 210 if (report[7]) buttons |= XPAD_PAD_Y;
okini3939 3:53ce7778a155 211 trigger_l = data[10];
okini3939 3:53ce7778a155 212 trigger_r = data[11];
okini3939 3:53ce7778a155 213
okini3939 3:53ce7778a155 214 stick_lx = ((int16_t)report[13] << 8) | report[12];
okini3939 3:53ce7778a155 215 stick_ly = ((int16_t)report[15] << 8) | report[14];
okini3939 3:53ce7778a155 216 stick_rx = ((int16_t)report[17] << 8) | report[16];
okini3939 3:53ce7778a155 217 stick_ry = ((int16_t)report[19] << 8) | report[18];
okini3939 3:53ce7778a155 218 break;
okini3939 3:53ce7778a155 219 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 220 data += 4;
okini3939 3:53ce7778a155 221 case TYPE_XBOX360:
okini3939 3:53ce7778a155 222 buttons = ((uint32_t)data[3] << 8) | data[2];
okini3939 3:53ce7778a155 223 trigger_l = data[4];
okini3939 3:53ce7778a155 224 trigger_r = data[5];
okini3939 3:53ce7778a155 225
okini3939 3:53ce7778a155 226 stick_lx = ((int16_t)data[7] << 8) | data[6];
okini3939 3:53ce7778a155 227 stick_ly = ((int16_t)data[9] << 8) | data[8];
okini3939 3:53ce7778a155 228 stick_rx = ((int16_t)data[11] << 8) | data[10];
okini3939 3:53ce7778a155 229 stick_ry = ((int16_t)data[13] << 8) | data[12];
okini3939 3:53ce7778a155 230 break;
okini3939 3:53ce7778a155 231 default:
okini3939 2:2749f4e649db 232 return;
okini3939 2:2749f4e649db 233 }
Ownasaurus 5:e0ed758abbdb 234
okini3939 3:53ce7778a155 235 if (onUpdate) {
okini3939 3:53ce7778a155 236 (*onUpdate)(buttons, stick_lx, stick_ly, stick_rx, stick_ry, trigger_l, trigger_r);
okini3939 3:53ce7778a155 237 }
okini3939 0:bd0f6bf72a8b 238 }
okini3939 0:bd0f6bf72a8b 239
okini3939 3:53ce7778a155 240 bool USBHostXpad::restart ()
okini3939 0:bd0f6bf72a8b 241 {
okini3939 1:5bb153989f33 242 unsigned char odata[32];
okini3939 1:5bb153989f33 243 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 244 odata[0] = 0x08;
okini3939 3:53ce7778a155 245 odata[2] = 0x0f;
okini3939 3:53ce7778a155 246 odata[3] = 0xc0;
okini3939 3:53ce7778a155 247 if (dev) {
okini3939 3:53ce7778a155 248 for (int i = 0; i < 4; i ++) {
okini3939 3:53ce7778a155 249 host->interruptWrite(dev, int_out, odata, 12);
okini3939 1:5bb153989f33 250 }
okini3939 3:53ce7778a155 251 }
okini3939 0:bd0f6bf72a8b 252 return true;
okini3939 0:bd0f6bf72a8b 253 }
okini3939 0:bd0f6bf72a8b 254
okini3939 3:53ce7778a155 255 int USBHostXpad::read (PAD pad)
okini3939 3:53ce7778a155 256 {
okini3939 3:53ce7778a155 257 switch (pad) {
okini3939 3:53ce7778a155 258 case XPAD_BUTTONS:
okini3939 3:53ce7778a155 259 return buttons;
okini3939 2:2749f4e649db 260 case XPAD_STICK_LX:
okini3939 2:2749f4e649db 261 return stick_lx;
okini3939 2:2749f4e649db 262 case XPAD_STICK_LY:
okini3939 2:2749f4e649db 263 return stick_ly;
okini3939 2:2749f4e649db 264 case XPAD_STICK_RX:
okini3939 2:2749f4e649db 265 return stick_rx;
okini3939 2:2749f4e649db 266 case XPAD_STICK_RY:
okini3939 2:2749f4e649db 267 return stick_ry;
okini3939 2:2749f4e649db 268 case XPAD_TRIGGER_L:
okini3939 2:2749f4e649db 269 return trigger_l;
okini3939 2:2749f4e649db 270 case XPAD_TRIGGER_R:
okini3939 2:2749f4e649db 271 return trigger_r;
okini3939 3:53ce7778a155 272 case XPAD_BATTERY:
okini3939 3:53ce7778a155 273 return battery;
okini3939 2:2749f4e649db 274 default:
okini3939 3:53ce7778a155 275 return (buttons & pad) ? 1 : 0;
okini3939 3:53ce7778a155 276 }
okini3939 3:53ce7778a155 277 }
okini3939 3:53ce7778a155 278
okini3939 3:53ce7778a155 279 bool USBHostXpad::start()
okini3939 3:53ce7778a155 280 {
okini3939 3:53ce7778a155 281 unsigned char odata[32];
okini3939 3:53ce7778a155 282 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 283 odata[3] = 0x40;
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 2:2749f4e649db 288 }
okini3939 3:53ce7778a155 289 return true;
okini3939 3:53ce7778a155 290 }
okini3939 3:53ce7778a155 291
okini3939 3:53ce7778a155 292 bool USBHostXpad::stop()
okini3939 3:53ce7778a155 293 {
okini3939 3:53ce7778a155 294 unsigned char odata[32];
okini3939 3:53ce7778a155 295 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 296 odata[2] = 0x08;
okini3939 3:53ce7778a155 297 odata[3] = 0xc0;
okini3939 3:53ce7778a155 298 if (dev) {
okini3939 3:53ce7778a155 299 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 3:53ce7778a155 300 return false;
okini3939 3:53ce7778a155 301 }
okini3939 3:53ce7778a155 302 }
okini3939 3:53ce7778a155 303 return true;
okini3939 2:2749f4e649db 304 }
okini3939 2:2749f4e649db 305
okini3939 2:2749f4e649db 306 bool USBHostXpad::led(LED cmd)
okini3939 0:bd0f6bf72a8b 307 {
okini3939 0:bd0f6bf72a8b 308 unsigned char odata[32];
okini3939 1:5bb153989f33 309 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 310 switch (dev_type) {
okini3939 3:53ce7778a155 311 case TYPE_XBOX:
okini3939 3:53ce7778a155 312 return true;
okini3939 3:53ce7778a155 313 case TYPE_XBOX360:
okini3939 3:53ce7778a155 314 odata[0] = 0x01;
okini3939 3:53ce7778a155 315 odata[1] = 0x03;
okini3939 3:53ce7778a155 316 odata[2] = cmd;
okini3939 3:53ce7778a155 317 break;
okini3939 3:53ce7778a155 318 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 319 odata[2] = 0x08;
okini3939 3:53ce7778a155 320 odata[3] = 0x40 + (cmd % 0x0e);
okini3939 3:53ce7778a155 321 break;
okini3939 3:53ce7778a155 322 default:
okini3939 3:53ce7778a155 323 return false;
okini3939 3:53ce7778a155 324 }
okini3939 3:53ce7778a155 325 if (dev) {
okini3939 3:53ce7778a155 326 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 327 return false;
okini3939 3:53ce7778a155 328 }
okini3939 3:53ce7778a155 329 }
okini3939 1:5bb153989f33 330 return true;
okini3939 1:5bb153989f33 331 }
okini3939 0:bd0f6bf72a8b 332
okini3939 1:5bb153989f33 333 bool USBHostXpad::rumble(uint8_t large, uint8_t small)
okini3939 1:5bb153989f33 334 {
okini3939 1:5bb153989f33 335 unsigned char odata[32];
okini3939 1:5bb153989f33 336 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 337 switch (dev_type) {
okini3939 3:53ce7778a155 338 case TYPE_XBOX:
okini3939 3:53ce7778a155 339 odata[1] = 0x06;
okini3939 3:53ce7778a155 340 odata[3] = small;
okini3939 3:53ce7778a155 341 odata[5] = large;
okini3939 3:53ce7778a155 342 break;
okini3939 3:53ce7778a155 343 case TYPE_XBOX360:
okini3939 3:53ce7778a155 344 odata[1] = 0x08;
okini3939 3:53ce7778a155 345 odata[3] = large;
okini3939 3:53ce7778a155 346 odata[4] = small;
okini3939 3:53ce7778a155 347 break;
okini3939 3:53ce7778a155 348 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 349 odata[1] = 0x01;
okini3939 3:53ce7778a155 350 odata[2] = 0x0f;
okini3939 3:53ce7778a155 351 odata[3] = 0xc0;
okini3939 3:53ce7778a155 352 odata[5] = large;
okini3939 3:53ce7778a155 353 odata[6] = small;
okini3939 3:53ce7778a155 354 break;
okini3939 3:53ce7778a155 355 default:
okini3939 3:53ce7778a155 356 return false;
okini3939 3:53ce7778a155 357 }
okini3939 3:53ce7778a155 358 if (dev) {
okini3939 3:53ce7778a155 359 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 360 return false;
okini3939 3:53ce7778a155 361 }
okini3939 3:53ce7778a155 362 }
okini3939 0:bd0f6bf72a8b 363 return true;
okini3939 0:bd0f6bf72a8b 364 }
okini3939 0:bd0f6bf72a8b 365
okini3939 0:bd0f6bf72a8b 366 #endif
okini3939 0:bd0f6bf72a8b 367