Justin S / USBHostXpad

Dependents:   N64_Output_XPAD

Fork of USBHostXpad by Suga koubou

Committer:
Ownasaurus
Date:
Mon Dec 12 01:07:42 2016 +0000
Revision:
6:954ecd99709c
Parent:
5:e0ed758abbdb
Child:
7:45cde92b7d9a
Added XBoxOne wired controller support

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 6:954ecd99709c 71 serial = 0;
Ownasaurus 5:e0ed758abbdb 72 wait_ms(100);
okini3939 2:2749f4e649db 73 led(LED_OFF);
Ownasaurus 6:954ecd99709c 74
okini3939 0:bd0f6bf72a8b 75 dev_connected = true;
okini3939 0:bd0f6bf72a8b 76 return true;
okini3939 0:bd0f6bf72a8b 77 }
okini3939 0:bd0f6bf72a8b 78
okini3939 1:5bb153989f33 79 }
okini3939 1:5bb153989f33 80 }
okini3939 0:bd0f6bf72a8b 81 init();
okini3939 0:bd0f6bf72a8b 82 return false;
okini3939 0:bd0f6bf72a8b 83 }
okini3939 0:bd0f6bf72a8b 84
okini3939 0:bd0f6bf72a8b 85 void USBHostXpad::rxHandler() {
okini3939 0:bd0f6bf72a8b 86 int len_listen = int_in->getSize();
okini3939 0:bd0f6bf72a8b 87 int len = int_in->getLengthTransferred();
okini3939 0:bd0f6bf72a8b 88
okini3939 3:53ce7778a155 89 if (dev_type == TYPE_XBOX) {
okini3939 3:53ce7778a155 90 parseMessage();
Ownasaurus 6:954ecd99709c 91 }
Ownasaurus 6:954ecd99709c 92 else if(dev_type == TYPE_XBOXONE) {
Ownasaurus 6:954ecd99709c 93 if(report[0] == 0x02) // auth
Ownasaurus 6:954ecd99709c 94 {
Ownasaurus 6:954ecd99709c 95 if(report[1] == 0x20) // request
Ownasaurus 6:954ecd99709c 96 {
Ownasaurus 6:954ecd99709c 97 start();
Ownasaurus 6:954ecd99709c 98 dev_started = true;
Ownasaurus 6:954ecd99709c 99 //return true;
Ownasaurus 6:954ecd99709c 100 }
Ownasaurus 6:954ecd99709c 101 }
Ownasaurus 6:954ecd99709c 102 else if(report[0] == 0x03)
Ownasaurus 6:954ecd99709c 103 {
Ownasaurus 6:954ecd99709c 104 // heartbeat
Ownasaurus 6:954ecd99709c 105 }
Ownasaurus 6:954ecd99709c 106 else if(report[0] == 0x07)
Ownasaurus 6:954ecd99709c 107 {
Ownasaurus 6:954ecd99709c 108 // guide button
Ownasaurus 6:954ecd99709c 109 }
Ownasaurus 6:954ecd99709c 110 else if(report[0] == 0x20)
Ownasaurus 6:954ecd99709c 111 {
Ownasaurus 6:954ecd99709c 112 // buttons update
Ownasaurus 6:954ecd99709c 113 parseMessage();
Ownasaurus 6:954ecd99709c 114 }
Ownasaurus 6:954ecd99709c 115 else if(report[0] == 0x01)
Ownasaurus 6:954ecd99709c 116 {
Ownasaurus 6:954ecd99709c 117 // error packet?
Ownasaurus 6:954ecd99709c 118 }
okini3939 3:53ce7778a155 119 } else
okini3939 3:53ce7778a155 120 if (report[0] == 0x08) {
Ownasaurus 5:e0ed758abbdb 121 if (report[1] == 0x80 || /*x360 headset status*/report[1] == 0x80) {
okini3939 3:53ce7778a155 122 // Connection Status Messages
okini3939 3:53ce7778a155 123 start();
okini3939 3:53ce7778a155 124 } else
okini3939 3:53ce7778a155 125 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 126 // Disconnected Status Messages
okini3939 3:53ce7778a155 127 dev_started = false;
okini3939 3:53ce7778a155 128 }
okini3939 0:bd0f6bf72a8b 129 } else
Ownasaurus 5:e0ed758abbdb 130 if (report[0] == 0x01) { // X360 led
Ownasaurus 5:e0ed758abbdb 131 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 132 } else
Ownasaurus 5:e0ed758abbdb 133 if (report[0] == 0x02) { // X360 unknown
Ownasaurus 5:e0ed758abbdb 134 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 135 } else
Ownasaurus 5:e0ed758abbdb 136 if (report[0] == 0x03) { // X360 rumble
Ownasaurus 5:e0ed758abbdb 137 ; // no need to do anything?
Ownasaurus 5:e0ed758abbdb 138 } else
okini3939 3:53ce7778a155 139 if (report[0] == 0x00) {
okini3939 3:53ce7778a155 140 if ((report[1] == 0x14) ||
okini3939 3:53ce7778a155 141 (report[1] == 0x01 && report[2] == 0x00 && report[3] == 0xf0)) {
okini3939 3:53ce7778a155 142 // Event data
okini3939 3:53ce7778a155 143 parseMessage();
okini3939 3:53ce7778a155 144 } else
okini3939 3:53ce7778a155 145 if (report[1] == 0x0f) {
okini3939 3:53ce7778a155 146 // On connection
okini3939 3:53ce7778a155 147 led(LED1_ON);
okini3939 3:53ce7778a155 148 start();
okini3939 3:53ce7778a155 149 dev_started = true;
okini3939 3:53ce7778a155 150 } else
okini3939 3:53ce7778a155 151 if (report[1] == 0x00) {
okini3939 3:53ce7778a155 152 if (report[3] == 0x13) {
okini3939 3:53ce7778a155 153 // Battery charge level
okini3939 3:53ce7778a155 154 battery = report[4];
okini3939 3:53ce7778a155 155 } else
okini3939 3:53ce7778a155 156 if (report[3] == 0xf0) {
okini3939 3:53ce7778a155 157 // Device low power mode (HID updates will stop until controller inputs change)
okini3939 4:4254192898a9 158 // restart();
okini3939 3:53ce7778a155 159 }
okini3939 3:53ce7778a155 160 } else
okini3939 3:53ce7778a155 161 if (report[1] == 0xf8) {
okini3939 3:53ce7778a155 162 // Status Messages ?
okini3939 3:53ce7778a155 163 }
okini3939 3:53ce7778a155 164 } else {
okini3939 1:5bb153989f33 165 // Unknown
okini3939 1:5bb153989f33 166 USB_INFO("rxHandler len:%d data:%02x %02x %02x %02x", len, report[0], report[1], report[2], report[3]);
okini3939 0:bd0f6bf72a8b 167 }
okini3939 0:bd0f6bf72a8b 168
okini3939 3:53ce7778a155 169 if (dev) {
okini3939 3:53ce7778a155 170 host->interruptRead(dev, int_in, report, len_listen, false);
okini3939 0:bd0f6bf72a8b 171 }
okini3939 0:bd0f6bf72a8b 172 }
okini3939 0:bd0f6bf72a8b 173
okini3939 0:bd0f6bf72a8b 174 /*virtual*/ void USBHostXpad::setVidPid(uint16_t vid, uint16_t pid)
okini3939 0:bd0f6bf72a8b 175 {
okini3939 0:bd0f6bf72a8b 176 // we don't check VID/PID for MSD driver
okini3939 3:53ce7778a155 177 if (vid == 0x045e && (pid == 0x0202 || pid == 0x0285 || pid == 0x0287 || pid == 0x0289)) {
okini3939 3:53ce7778a155 178 dev_type = TYPE_XBOX;
okini3939 3:53ce7778a155 179 } else
Ownasaurus 5:e0ed758abbdb 180 if ((vid == 0x045e && pid == 0x028e) || /*my afterglow addition!*/(vid == 0x0e6f && pid == 0x0213)) {
okini3939 3:53ce7778a155 181 dev_type = TYPE_XBOX360;
okini3939 3:53ce7778a155 182 } else
okini3939 3:53ce7778a155 183 if (vid == 0x045e && pid == 0x0719) {
okini3939 3:53ce7778a155 184 dev_type = TYPE_XBOX360W;
Ownasaurus 6:954ecd99709c 185 } else
Ownasaurus 6:954ecd99709c 186 if (vid == 0x045e && (pid == 0x02ea || pid == 0x02e3 || pid == 0x02d1 || pid == 0x02dd)) { // also includes XBOX ONE ELITE
Ownasaurus 6:954ecd99709c 187 dev_type = TYPE_XBOXONE;
okini3939 3:53ce7778a155 188 }
okini3939 3:53ce7778a155 189 USB_INFO("setVidPid vid:%04x pid:%04x xbox:%d", vid, pid, dev_type);
okini3939 0:bd0f6bf72a8b 190 }
okini3939 0:bd0f6bf72a8b 191
okini3939 0:bd0f6bf72a8b 192 /*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 193 {
okini3939 0:bd0f6bf72a8b 194 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 195 if ((xpad_intf == -1) && (intf_class == 0x58) && (intf_subclass == 0x42) && (intf_protocol == 0x00)) {
okini3939 3:53ce7778a155 196 xpad_intf = intf_nb; // XBOX ?
okini3939 3:53ce7778a155 197 return true;
okini3939 3:53ce7778a155 198 }
okini3939 3:53ce7778a155 199 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x81)) {
okini3939 3:53ce7778a155 200 xpad_intf = intf_nb; // XBOX360W
okini3939 0:bd0f6bf72a8b 201 return true;
okini3939 0:bd0f6bf72a8b 202 }
Ownasaurus 5:e0ed758abbdb 203 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x01)) {
Ownasaurus 5:e0ed758abbdb 204 xpad_intf = intf_nb; // XBOX360 WIRED AFTERGLOW
Ownasaurus 5:e0ed758abbdb 205 return true;
Ownasaurus 5:e0ed758abbdb 206 }
Ownasaurus 6:954ecd99709c 207 if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x47) && (intf_protocol == 0xd0)) {
Ownasaurus 6:954ecd99709c 208 xpad_intf = intf_nb; // XBOXONE WIRED
Ownasaurus 6:954ecd99709c 209 return true;
Ownasaurus 6:954ecd99709c 210 }
okini3939 0:bd0f6bf72a8b 211 return false;
okini3939 0:bd0f6bf72a8b 212 }
okini3939 0:bd0f6bf72a8b 213
okini3939 0:bd0f6bf72a8b 214 /*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 215 {
okini3939 0:bd0f6bf72a8b 216 USB_INFO("useEndpoint nb:%d type:%d dir:%d", intf_nb, type, dir);
okini3939 0:bd0f6bf72a8b 217 if (intf_nb == xpad_intf) {
okini3939 0:bd0f6bf72a8b 218 if (type == INTERRUPT_ENDPOINT) {
okini3939 0:bd0f6bf72a8b 219 nb_ep ++;
okini3939 3:53ce7778a155 220 if (nb_ep == 2) {
okini3939 0:bd0f6bf72a8b 221 xpad_device_found = true;
okini3939 3:53ce7778a155 222 }
okini3939 0:bd0f6bf72a8b 223 return true;
okini3939 0:bd0f6bf72a8b 224 }
okini3939 0:bd0f6bf72a8b 225 }
okini3939 0:bd0f6bf72a8b 226 return false;
okini3939 0:bd0f6bf72a8b 227 }
okini3939 0:bd0f6bf72a8b 228
okini3939 3:53ce7778a155 229
okini3939 3:53ce7778a155 230 void USBHostXpad::parseMessage()
okini3939 0:bd0f6bf72a8b 231 {
okini3939 3:53ce7778a155 232 uint8_t *data = report;
okini3939 3:53ce7778a155 233
okini3939 3:53ce7778a155 234 switch (dev_type) {
okini3939 3:53ce7778a155 235 case TYPE_XBOX:
okini3939 3:53ce7778a155 236 buttons = ((uint32_t)report[3] << 8) | report[2];
okini3939 3:53ce7778a155 237 if (report[4]) buttons |= XPAD_PAD_A;
okini3939 3:53ce7778a155 238 if (report[5]) buttons |= XPAD_PAD_B;
okini3939 3:53ce7778a155 239 if (report[6]) buttons |= XPAD_PAD_X;
okini3939 3:53ce7778a155 240 if (report[7]) buttons |= XPAD_PAD_Y;
okini3939 3:53ce7778a155 241 trigger_l = data[10];
okini3939 3:53ce7778a155 242 trigger_r = data[11];
okini3939 3:53ce7778a155 243
okini3939 3:53ce7778a155 244 stick_lx = ((int16_t)report[13] << 8) | report[12];
okini3939 3:53ce7778a155 245 stick_ly = ((int16_t)report[15] << 8) | report[14];
okini3939 3:53ce7778a155 246 stick_rx = ((int16_t)report[17] << 8) | report[16];
okini3939 3:53ce7778a155 247 stick_ry = ((int16_t)report[19] << 8) | report[18];
okini3939 3:53ce7778a155 248 break;
okini3939 3:53ce7778a155 249 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 250 data += 4;
okini3939 3:53ce7778a155 251 case TYPE_XBOX360:
okini3939 3:53ce7778a155 252 buttons = ((uint32_t)data[3] << 8) | data[2];
okini3939 3:53ce7778a155 253 trigger_l = data[4];
okini3939 3:53ce7778a155 254 trigger_r = data[5];
okini3939 3:53ce7778a155 255
okini3939 3:53ce7778a155 256 stick_lx = ((int16_t)data[7] << 8) | data[6];
okini3939 3:53ce7778a155 257 stick_ly = ((int16_t)data[9] << 8) | data[8];
okini3939 3:53ce7778a155 258 stick_rx = ((int16_t)data[11] << 8) | data[10];
okini3939 3:53ce7778a155 259 stick_ry = ((int16_t)data[13] << 8) | data[12];
okini3939 3:53ce7778a155 260 break;
Ownasaurus 6:954ecd99709c 261 case TYPE_XBOXONE:
Ownasaurus 6:954ecd99709c 262 buttons = 0;
Ownasaurus 6:954ecd99709c 263 buttons = (report[4] & 0x0C) << 2; // correctly place start and back
Ownasaurus 6:954ecd99709c 264 buttons |= (report[4] & 0xF0) << 8; // correctly place AXYB
Ownasaurus 6:954ecd99709c 265 buttons |= report[5] & 0x0F; // correctly place DPad
Ownasaurus 6:954ecd99709c 266 buttons |= (report[5] & 0x30) << 4; // correctly place bumpers
Ownasaurus 6:954ecd99709c 267
Ownasaurus 6:954ecd99709c 268 //TODO: FIX TRIGGERS, PROBABLY OVERFLOWING
Ownasaurus 6:954ecd99709c 269 trigger_l = ((uint32_t)report[7] << 8) | report[6]; //6 and 7
Ownasaurus 6:954ecd99709c 270 trigger_r = ((uint32_t)report[9] << 8) | report[8]; // 8 and 9
Ownasaurus 6:954ecd99709c 271
Ownasaurus 6:954ecd99709c 272 stick_lx = ((int16_t)data[11] << 8) | data[10];
Ownasaurus 6:954ecd99709c 273 stick_ly = ((int16_t)data[13] << 8) | data[12];
Ownasaurus 6:954ecd99709c 274 stick_rx = ((int16_t)data[15] << 8) | data[14];
Ownasaurus 6:954ecd99709c 275 stick_ry = ((int16_t)data[17] << 8) | data[16];
Ownasaurus 6:954ecd99709c 276
Ownasaurus 6:954ecd99709c 277 break;
okini3939 3:53ce7778a155 278 default:
okini3939 2:2749f4e649db 279 return;
okini3939 2:2749f4e649db 280 }
Ownasaurus 5:e0ed758abbdb 281
okini3939 3:53ce7778a155 282 if (onUpdate) {
okini3939 3:53ce7778a155 283 (*onUpdate)(buttons, stick_lx, stick_ly, stick_rx, stick_ry, trigger_l, trigger_r);
okini3939 3:53ce7778a155 284 }
okini3939 0:bd0f6bf72a8b 285 }
okini3939 0:bd0f6bf72a8b 286
okini3939 3:53ce7778a155 287 bool USBHostXpad::restart ()
okini3939 0:bd0f6bf72a8b 288 {
okini3939 1:5bb153989f33 289 unsigned char odata[32];
okini3939 1:5bb153989f33 290 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 291 odata[0] = 0x08;
okini3939 3:53ce7778a155 292 odata[2] = 0x0f;
okini3939 3:53ce7778a155 293 odata[3] = 0xc0;
okini3939 3:53ce7778a155 294 if (dev) {
okini3939 3:53ce7778a155 295 for (int i = 0; i < 4; i ++) {
okini3939 3:53ce7778a155 296 host->interruptWrite(dev, int_out, odata, 12);
okini3939 1:5bb153989f33 297 }
okini3939 3:53ce7778a155 298 }
okini3939 0:bd0f6bf72a8b 299 return true;
okini3939 0:bd0f6bf72a8b 300 }
okini3939 0:bd0f6bf72a8b 301
okini3939 3:53ce7778a155 302 int USBHostXpad::read (PAD pad)
okini3939 3:53ce7778a155 303 {
okini3939 3:53ce7778a155 304 switch (pad) {
okini3939 3:53ce7778a155 305 case XPAD_BUTTONS:
okini3939 3:53ce7778a155 306 return buttons;
okini3939 2:2749f4e649db 307 case XPAD_STICK_LX:
okini3939 2:2749f4e649db 308 return stick_lx;
okini3939 2:2749f4e649db 309 case XPAD_STICK_LY:
okini3939 2:2749f4e649db 310 return stick_ly;
okini3939 2:2749f4e649db 311 case XPAD_STICK_RX:
okini3939 2:2749f4e649db 312 return stick_rx;
okini3939 2:2749f4e649db 313 case XPAD_STICK_RY:
okini3939 2:2749f4e649db 314 return stick_ry;
okini3939 2:2749f4e649db 315 case XPAD_TRIGGER_L:
okini3939 2:2749f4e649db 316 return trigger_l;
okini3939 2:2749f4e649db 317 case XPAD_TRIGGER_R:
okini3939 2:2749f4e649db 318 return trigger_r;
okini3939 3:53ce7778a155 319 case XPAD_BATTERY:
okini3939 3:53ce7778a155 320 return battery;
okini3939 2:2749f4e649db 321 default:
okini3939 3:53ce7778a155 322 return (buttons & pad) ? 1 : 0;
okini3939 3:53ce7778a155 323 }
okini3939 3:53ce7778a155 324 }
okini3939 3:53ce7778a155 325
okini3939 3:53ce7778a155 326 bool USBHostXpad::start()
okini3939 3:53ce7778a155 327 {
Ownasaurus 6:954ecd99709c 328 if(dev_type == TYPE_XBOXONE)
Ownasaurus 6:954ecd99709c 329 {
Ownasaurus 6:954ecd99709c 330 unsigned char odata[32];
Ownasaurus 6:954ecd99709c 331 memset(odata, 0, sizeof(odata));
Ownasaurus 6:954ecd99709c 332 odata[0] = 0x05;
Ownasaurus 6:954ecd99709c 333 odata[1] = 0x20;
Ownasaurus 6:954ecd99709c 334 odata[2] = serial++;
Ownasaurus 6:954ecd99709c 335 odata[3] = 0x09;
Ownasaurus 6:954ecd99709c 336 odata[4] = 0x06;
Ownasaurus 6:954ecd99709c 337 odata[11] = 0x55;
Ownasaurus 6:954ecd99709c 338 odata[12] = 0x53;
Ownasaurus 6:954ecd99709c 339 if (dev) {
Ownasaurus 6:954ecd99709c 340 if (host->interruptWrite(dev, int_out, odata, 13) != USB_TYPE_OK) {
Ownasaurus 6:954ecd99709c 341 return false;
Ownasaurus 6:954ecd99709c 342 }
Ownasaurus 6:954ecd99709c 343 }
Ownasaurus 6:954ecd99709c 344
Ownasaurus 6:954ecd99709c 345 memset(odata, 0, sizeof(odata));
Ownasaurus 6:954ecd99709c 346 odata[0] = 0x05;
Ownasaurus 6:954ecd99709c 347 odata[1] = 0x20;
Ownasaurus 6:954ecd99709c 348 odata[2] = serial++;
Ownasaurus 6:954ecd99709c 349 odata[3] = 0x01;
Ownasaurus 6:954ecd99709c 350 odata[4] = 0x00;
Ownasaurus 6:954ecd99709c 351 if (dev) {
Ownasaurus 6:954ecd99709c 352 if (host->interruptWrite(dev, int_out, odata, 5) != USB_TYPE_OK) {
Ownasaurus 6:954ecd99709c 353 return false;
Ownasaurus 6:954ecd99709c 354 }
Ownasaurus 6:954ecd99709c 355 }
Ownasaurus 6:954ecd99709c 356 return true;
Ownasaurus 6:954ecd99709c 357 }
Ownasaurus 6:954ecd99709c 358
Ownasaurus 6:954ecd99709c 359 // other controller init
okini3939 3:53ce7778a155 360 unsigned char odata[32];
okini3939 3:53ce7778a155 361 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 362 odata[3] = 0x40;
okini3939 3:53ce7778a155 363 if (dev) {
okini3939 3:53ce7778a155 364 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 3:53ce7778a155 365 return false;
okini3939 3:53ce7778a155 366 }
okini3939 2:2749f4e649db 367 }
okini3939 3:53ce7778a155 368 return true;
okini3939 3:53ce7778a155 369 }
okini3939 3:53ce7778a155 370
okini3939 3:53ce7778a155 371 bool USBHostXpad::stop()
okini3939 3:53ce7778a155 372 {
okini3939 3:53ce7778a155 373 unsigned char odata[32];
okini3939 3:53ce7778a155 374 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 375 odata[2] = 0x08;
okini3939 3:53ce7778a155 376 odata[3] = 0xc0;
okini3939 3:53ce7778a155 377 if (dev) {
okini3939 3:53ce7778a155 378 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 3:53ce7778a155 379 return false;
okini3939 3:53ce7778a155 380 }
okini3939 3:53ce7778a155 381 }
okini3939 3:53ce7778a155 382 return true;
okini3939 2:2749f4e649db 383 }
okini3939 2:2749f4e649db 384
okini3939 2:2749f4e649db 385 bool USBHostXpad::led(LED cmd)
okini3939 0:bd0f6bf72a8b 386 {
okini3939 0:bd0f6bf72a8b 387 unsigned char odata[32];
okini3939 1:5bb153989f33 388 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 389 switch (dev_type) {
okini3939 3:53ce7778a155 390 case TYPE_XBOX:
okini3939 3:53ce7778a155 391 return true;
okini3939 3:53ce7778a155 392 case TYPE_XBOX360:
okini3939 3:53ce7778a155 393 odata[0] = 0x01;
okini3939 3:53ce7778a155 394 odata[1] = 0x03;
okini3939 3:53ce7778a155 395 odata[2] = cmd;
okini3939 3:53ce7778a155 396 break;
okini3939 3:53ce7778a155 397 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 398 odata[2] = 0x08;
okini3939 3:53ce7778a155 399 odata[3] = 0x40 + (cmd % 0x0e);
okini3939 3:53ce7778a155 400 break;
Ownasaurus 6:954ecd99709c 401 case TYPE_XBOXONE:
Ownasaurus 6:954ecd99709c 402 return true; // no LEDs to change
okini3939 3:53ce7778a155 403 default:
okini3939 3:53ce7778a155 404 return false;
okini3939 3:53ce7778a155 405 }
okini3939 3:53ce7778a155 406 if (dev) {
okini3939 3:53ce7778a155 407 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 408 return false;
okini3939 3:53ce7778a155 409 }
okini3939 3:53ce7778a155 410 }
okini3939 1:5bb153989f33 411 return true;
okini3939 1:5bb153989f33 412 }
okini3939 0:bd0f6bf72a8b 413
okini3939 1:5bb153989f33 414 bool USBHostXpad::rumble(uint8_t large, uint8_t small)
okini3939 1:5bb153989f33 415 {
okini3939 1:5bb153989f33 416 unsigned char odata[32];
okini3939 1:5bb153989f33 417 memset(odata, 0, sizeof(odata));
okini3939 3:53ce7778a155 418 switch (dev_type) {
okini3939 3:53ce7778a155 419 case TYPE_XBOX:
okini3939 3:53ce7778a155 420 odata[1] = 0x06;
okini3939 3:53ce7778a155 421 odata[3] = small;
okini3939 3:53ce7778a155 422 odata[5] = large;
okini3939 3:53ce7778a155 423 break;
okini3939 3:53ce7778a155 424 case TYPE_XBOX360:
okini3939 3:53ce7778a155 425 odata[1] = 0x08;
okini3939 3:53ce7778a155 426 odata[3] = large;
okini3939 3:53ce7778a155 427 odata[4] = small;
okini3939 3:53ce7778a155 428 break;
okini3939 3:53ce7778a155 429 case TYPE_XBOX360W:
okini3939 3:53ce7778a155 430 odata[1] = 0x01;
okini3939 3:53ce7778a155 431 odata[2] = 0x0f;
okini3939 3:53ce7778a155 432 odata[3] = 0xc0;
okini3939 3:53ce7778a155 433 odata[5] = large;
okini3939 3:53ce7778a155 434 odata[6] = small;
okini3939 3:53ce7778a155 435 break;
Ownasaurus 6:954ecd99709c 436 case TYPE_XBOXONE:
Ownasaurus 6:954ecd99709c 437 return true;
okini3939 3:53ce7778a155 438 default:
okini3939 3:53ce7778a155 439 return false;
okini3939 3:53ce7778a155 440 }
okini3939 3:53ce7778a155 441 if (dev) {
okini3939 3:53ce7778a155 442 if (host->interruptWrite(dev, int_out, odata, 12) != USB_TYPE_OK) {
okini3939 1:5bb153989f33 443 return false;
okini3939 3:53ce7778a155 444 }
okini3939 3:53ce7778a155 445 }
okini3939 0:bd0f6bf72a8b 446 return true;
okini3939 0:bd0f6bf72a8b 447 }
okini3939 0:bd0f6bf72a8b 448
okini3939 0:bd0f6bf72a8b 449 #endif
okini3939 0:bd0f6bf72a8b 450