Xbox 360 Wireless Controller for Windows library. sample: http://mbed.org/users/okini3939/code/USBHostXpad_HelloWorld/
Dependents: USBHostXpad_HelloWorld USBHostXpad_HelloWorld
Xbox 360 Wireless Controller for Windows
Microsoftの XBOX 360 ワイヤレスコントローラーを、パソコン用のUSB接続型レシーバーで mbed に接続して使えるライブラリです。
USB Host 機能を使いますので mbed LPC1768 専用です。
たまに処理が停止する不具合があります。
USBHostXpad.cpp@4:4254192898a9, 2014-02-01 (annotated)
- Committer:
- okini3939
- Date:
- Sat Feb 01 08:12:44 2014 +0000
- Revision:
- 4:4254192898a9
- Parent:
- 3:53ce7778a155
disabled auto restart
Who changed what in which revision?
User | Revision | Line number | New 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 | |
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 |