Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Committer:
AjK
Date:
Mon Oct 11 10:34:55 2010 +0000
Revision:
0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:0a841b89d614 1 /****************************************************************************
AjK 0:0a841b89d614 2 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
AjK 0:0a841b89d614 3 *
AjK 0:0a841b89d614 4 * This file is part of the Satellite Observers Workbench (SOWB).
AjK 0:0a841b89d614 5 *
AjK 0:0a841b89d614 6 * SOWB is free software: you can redistribute it and/or modify
AjK 0:0a841b89d614 7 * it under the terms of the GNU General Public License as published by
AjK 0:0a841b89d614 8 * the Free Software Foundation, either version 3 of the License, or
AjK 0:0a841b89d614 9 * (at your option) any later version.
AjK 0:0a841b89d614 10 *
AjK 0:0a841b89d614 11 * SOWB is distributed in the hope that it will be useful,
AjK 0:0a841b89d614 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
AjK 0:0a841b89d614 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
AjK 0:0a841b89d614 14 * GNU General Public License for more details.
AjK 0:0a841b89d614 15 *
AjK 0:0a841b89d614 16 * You should have received a copy of the GNU General Public License
AjK 0:0a841b89d614 17 * along with SOWB. If not, see <http://www.gnu.org/licenses/>.
AjK 0:0a841b89d614 18 *
AjK 0:0a841b89d614 19 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
AjK 0:0a841b89d614 20 *
AjK 0:0a841b89d614 21 ***************************************************************************/
AjK 0:0a841b89d614 22
AjK 0:0a841b89d614 23 #include "sowb.h"
AjK 0:0a841b89d614 24 #include "debug.h"
AjK 0:0a841b89d614 25 #include "usbeh_api.h"
AjK 0:0a841b89d614 26 #include "usbeh_endpoint.h"
AjK 0:0a841b89d614 27 #include "usbeh_device.h"
AjK 0:0a841b89d614 28 #include "usbeh_controller.h"
AjK 0:0a841b89d614 29 #include "xbox360gamepad.h"
AjK 0:0a841b89d614 30
AjK 0:0a841b89d614 31 #include "main.h"
AjK 0:0a841b89d614 32
AjK 0:0a841b89d614 33 /* Define an array of data structures for the buttons. */
AjK 0:0a841b89d614 34 static XBOX360_BUTTON buttons[16];
AjK 0:0a841b89d614 35 static unsigned char button_buffer[16];
AjK 0:0a841b89d614 36 static unsigned char button_buffer_in;
AjK 0:0a841b89d614 37 static unsigned char button_buffer_out;
AjK 0:0a841b89d614 38
AjK 0:0a841b89d614 39 /* Place holders for left and right triggers. */
AjK 0:0a841b89d614 40 static unsigned char trigger_left;
AjK 0:0a841b89d614 41 static unsigned char trigger_right;
AjK 0:0a841b89d614 42
AjK 0:0a841b89d614 43 static XBOX360_STICK stick_left;
AjK 0:0a841b89d614 44 static XBOX360_STICK stick_right;
AjK 0:0a841b89d614 45
AjK 0:0a841b89d614 46 /* A map of wired Xbox 360 controllers.
AjK 0:0a841b89d614 47 Data copied from the Linux xboxdrv project, thx :)
AjK 0:0a841b89d614 48 http://pingus.seul.org/~grumbel/xboxdrv */
AjK 0:0a841b89d614 49 static XBOX360_DEVICE xbox360_devices[] = {
AjK 0:0a841b89d614 50 { 0x045e, 0x028e, "Microsoft Xbox 360 Controller" },
AjK 0:0a841b89d614 51 { 0x0738, 0x4716, "Mad Catz Xbox 360 Controller" },
AjK 0:0a841b89d614 52 { 0x0738, 0x4726, "Mad Catz Xbox 360 Controller" },
AjK 0:0a841b89d614 53 { 0x0738, 0x4740, "Mad Catz Beat Pad" },
AjK 0:0a841b89d614 54 { 0x0738, 0xf738, "Super SFIV FightStick TE S" },
AjK 0:0a841b89d614 55 { 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick" },
AjK 0:0a841b89d614 56 { 0x0f0d, 0x000d, "Hori Fighting Stick Ex2" },
AjK 0:0a841b89d614 57 { 0x0f0d, 0x0016, "Hori Real Arcade Pro Ex" },
AjK 0:0a841b89d614 58 { 0x162e, 0xbeef, "Joytech Neo-Se Take2" },
AjK 0:0a841b89d614 59 { 0x046d, 0xc242, "Logitech ChillStream" },
AjK 0:0a841b89d614 60 { 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360" },
AjK 0:0a841b89d614 61 { 0x0e6f, 0x0201, "Pelican TSZ360 Pad" },
AjK 0:0a841b89d614 62 { 0x0738, 0xb726, "Mad Catz Xbox controller - MW2" }, // Here's one I found that isn't in the Linux distro.
AjK 0:0a841b89d614 63 { 0x0000, 0x0000, "End of list" }
AjK 0:0a841b89d614 64 };
AjK 0:0a841b89d614 65
AjK 0:0a841b89d614 66 /* Although Microsoft has not published any data or specifications
AjK 0:0a841b89d614 67 regarding the Xbox360 gamepad/controller, it's basic makeup is
AjK 0:0a841b89d614 68 well known. Define here the pipes for the interfaces we are
AjK 0:0a841b89d614 69 interested in. */
AjK 0:0a841b89d614 70
AjK 0:0a841b89d614 71 #define XBOX360_GAMEPAD_PIPE_BUFFER_SIZE 32
AjK 0:0a841b89d614 72
AjK 0:0a841b89d614 73 typedef struct {
AjK 0:0a841b89d614 74 USBEH_U08 data_in[XBOX360_GAMEPAD_PIPE_BUFFER_SIZE];
AjK 0:0a841b89d614 75 USBEH_U08 data_out[XBOX360_GAMEPAD_PIPE_BUFFER_SIZE];
AjK 0:0a841b89d614 76 USBEH_U08 ep_number_in;
AjK 0:0a841b89d614 77 USBEH_U08 ep_number_out;
AjK 0:0a841b89d614 78 } XBOX360_PIPE;
AjK 0:0a841b89d614 79
AjK 0:0a841b89d614 80 typedef struct {
AjK 0:0a841b89d614 81 USBEH_U08 data_in[256];
AjK 0:0a841b89d614 82 USBEH_U08 data_out[256];
AjK 0:0a841b89d614 83 USBEH_U08 ep_number_in;
AjK 0:0a841b89d614 84 USBEH_U08 ep_number_out;
AjK 0:0a841b89d614 85 } XBOX360_CONTROL_PIPE;
AjK 0:0a841b89d614 86
AjK 0:0a841b89d614 87 struct _xbox360_gamepad_vendor {
AjK 0:0a841b89d614 88 XBOX360_CONTROL_PIPE pipe[1];
AjK 0:0a841b89d614 89 } IF_VENDOR __attribute__((aligned(256)));
AjK 0:0a841b89d614 90
AjK 0:0a841b89d614 91 struct _xbox360_gamepad_interface0 {
AjK 0:0a841b89d614 92 XBOX360_PIPE pipe[1];
AjK 0:0a841b89d614 93 } IF_ZERO __attribute__((aligned(256)));
AjK 0:0a841b89d614 94
AjK 0:0a841b89d614 95 struct _xbox360_gamepad_interface1 {
AjK 0:0a841b89d614 96 XBOX360_PIPE pipe[2];
AjK 0:0a841b89d614 97 } IF_ONE __attribute__((aligned(256)));
AjK 0:0a841b89d614 98
AjK 0:0a841b89d614 99 struct _xbox360_gamepad_interface2 {
AjK 0:0a841b89d614 100 XBOX360_PIPE pipe[1];
AjK 0:0a841b89d614 101 } IF_TWO __attribute__((aligned(256)));
AjK 0:0a841b89d614 102
AjK 0:0a841b89d614 103 int deviceNumber;
AjK 0:0a841b89d614 104
AjK 0:0a841b89d614 105 int xbox360gamepad_init(void) {
AjK 0:0a841b89d614 106 DEBUG_INIT_START;
AjK 0:0a841b89d614 107 for (int i = 0; i < 16; i++) {
AjK 0:0a841b89d614 108 buttons[i].state = BUTTON_RELEASED;
AjK 0:0a841b89d614 109 buttons[i].count = 0;
AjK 0:0a841b89d614 110 button_buffer[i] = 0xFF;
AjK 0:0a841b89d614 111 usbeh_sof_counter_init(&buttons[i].pressHold, USBEH_SOF_COUNTER_DEC | USBEH_SOF_COUNTER_RELOAD, BUTTON_HOLD_TIME);
AjK 0:0a841b89d614 112 buttons[i].pressHold.userData = i;
AjK 0:0a841b89d614 113 buttons[i].pressHold.callback = xbox360gamepad_button_hold_callback;
AjK 0:0a841b89d614 114 usbeh_sof_counter_register(&buttons[i].pressHold);
AjK 0:0a841b89d614 115 }
AjK 0:0a841b89d614 116 button_buffer_in = 0;
AjK 0:0a841b89d614 117 button_buffer_out = 0;
AjK 0:0a841b89d614 118 trigger_left = 0;
AjK 0:0a841b89d614 119 trigger_right = 0;
AjK 0:0a841b89d614 120 stick_left.x = 0;
AjK 0:0a841b89d614 121 stick_left.y = 0;
AjK 0:0a841b89d614 122 stick_right.x = 0;
AjK 0:0a841b89d614 123 stick_right.y = 0;
AjK 0:0a841b89d614 124 DEBUG_INIT_END;
AjK 0:0a841b89d614 125 return 0;
AjK 0:0a841b89d614 126 }
AjK 0:0a841b89d614 127
AjK 0:0a841b89d614 128 void xbox360gamepad_process(void) {
AjK 0:0a841b89d614 129 // This currently does nothing.
AjK 0:0a841b89d614 130 }
AjK 0:0a841b89d614 131
AjK 0:0a841b89d614 132 void xbox360gamepad_button_press(unsigned char button) {
AjK 0:0a841b89d614 133 button_buffer[button_buffer_in] = button;
AjK 0:0a841b89d614 134 button_buffer_in++;
AjK 0:0a841b89d614 135 button_buffer_in &= 0x0F;
AjK 0:0a841b89d614 136 }
AjK 0:0a841b89d614 137
AjK 0:0a841b89d614 138 char xbox360gamepad_get_button(void) {
AjK 0:0a841b89d614 139 if (button_buffer_in == button_buffer_out) {
AjK 0:0a841b89d614 140 return 0;
AjK 0:0a841b89d614 141 }
AjK 0:0a841b89d614 142
AjK 0:0a841b89d614 143 char button = button_buffer[button_buffer_out];
AjK 0:0a841b89d614 144 button_buffer_out++;
AjK 0:0a841b89d614 145 button_buffer_out &= 0x0F;
AjK 0:0a841b89d614 146 return button;
AjK 0:0a841b89d614 147 }
AjK 0:0a841b89d614 148
AjK 0:0a841b89d614 149 char xbox360gamepad_get_button_preview(void) {
AjK 0:0a841b89d614 150 if (button_buffer_in == button_buffer_out) {
AjK 0:0a841b89d614 151 return 0;
AjK 0:0a841b89d614 152 }
AjK 0:0a841b89d614 153
AjK 0:0a841b89d614 154 char button = button_buffer[button_buffer_out];
AjK 0:0a841b89d614 155 return button;
AjK 0:0a841b89d614 156 }
AjK 0:0a841b89d614 157
AjK 0:0a841b89d614 158 unsigned char xbox360gamepad_get_trigger_left(void) {
AjK 0:0a841b89d614 159 return trigger_left;
AjK 0:0a841b89d614 160 }
AjK 0:0a841b89d614 161
AjK 0:0a841b89d614 162 unsigned char xbox360gamepad_get_trigger_right(void) {
AjK 0:0a841b89d614 163 return trigger_right;
AjK 0:0a841b89d614 164 }
AjK 0:0a841b89d614 165
AjK 0:0a841b89d614 166 XBOX360_STICK * xbox360gamepad_get_stick_left(void) {
AjK 0:0a841b89d614 167 return &stick_left;
AjK 0:0a841b89d614 168 }
AjK 0:0a841b89d614 169
AjK 0:0a841b89d614 170 XBOX360_STICK * xbox360gamepad_get_stick_right(void) {
AjK 0:0a841b89d614 171 return &stick_right;
AjK 0:0a841b89d614 172 }
AjK 0:0a841b89d614 173
AjK 0:0a841b89d614 174 void xbox360gamepad_button_hold_callback(USBEH_SOF_COUNTER *q) {
AjK 0:0a841b89d614 175 int i = (int)q->userData;
AjK 0:0a841b89d614 176 if (buttons[i].state == BUTTON_PRESSED) {
AjK 0:0a841b89d614 177 xbox360gamepad_button_press((char)(i + 1 + 32));
AjK 0:0a841b89d614 178 }
AjK 0:0a841b89d614 179 }
AjK 0:0a841b89d614 180
AjK 0:0a841b89d614 181 /**
AjK 0:0a841b89d614 182 * xbox360gamepad_interface_0_in
AjK 0:0a841b89d614 183 *
AjK 0:0a841b89d614 184 * A callback function to handle interface0 pipe0 data.
AjK 0:0a841b89d614 185 */
AjK 0:0a841b89d614 186 void xbox360gamepad_interface_0_in(int device, int endpoint, int status, USBEH_U08 *data, int len, void *userData) {
AjK 0:0a841b89d614 187 unsigned button_flags;
AjK 0:0a841b89d614 188
AjK 0:0a841b89d614 189 /* Is this a button press report? */
AjK 0:0a841b89d614 190 if(IF_ZERO.pipe[(int)userData].data_in[0] == 0 && IF_ZERO.pipe[(int)userData].data_in[1] == 0x14) {
AjK 0:0a841b89d614 191
AjK 0:0a841b89d614 192 /* Handle the button flags. */
AjK 0:0a841b89d614 193 button_flags = ((IF_ZERO.pipe[(int)userData].data_in[2] & 0xFF) << 8) | (IF_ZERO.pipe[(int)userData].data_in[3] & 0xFF);
AjK 0:0a841b89d614 194 for (int i = 0; i < 16; i++) {
AjK 0:0a841b89d614 195 if ((button_flags & (1 << i)) != 0) {
AjK 0:0a841b89d614 196 if (buttons[i].state == BUTTON_RELEASED) {
AjK 0:0a841b89d614 197 buttons[i].state = BUTTON_PRESSED;
AjK 0:0a841b89d614 198 buttons[i].count++;
AjK 0:0a841b89d614 199 buttons[i].pressHold.flag = 0;
AjK 0:0a841b89d614 200 xbox360gamepad_button_press((char)(i + 1));
AjK 0:0a841b89d614 201 }
AjK 0:0a841b89d614 202 }
AjK 0:0a841b89d614 203 else {
AjK 0:0a841b89d614 204 if (buttons[i].state == BUTTON_PRESSED) {
AjK 0:0a841b89d614 205 buttons[i].state = BUTTON_RELEASED;
AjK 0:0a841b89d614 206 buttons[i].pressHold.flag = 1;
AjK 0:0a841b89d614 207 buttons[i].pressHold.counter = BUTTON_HOLD_TIME;
AjK 0:0a841b89d614 208 buttons[i].count = 0;
AjK 0:0a841b89d614 209 xbox360gamepad_button_press((char)(i + 1 + 16));
AjK 0:0a841b89d614 210 }
AjK 0:0a841b89d614 211 }
AjK 0:0a841b89d614 212 }
AjK 0:0a841b89d614 213
AjK 0:0a841b89d614 214 /* Handle the analogue triggers. */
AjK 0:0a841b89d614 215 trigger_left = (unsigned char)IF_ZERO.pipe[(int)userData].data_in[4];
AjK 0:0a841b89d614 216 trigger_right = (unsigned char)IF_ZERO.pipe[(int)userData].data_in[5];
AjK 0:0a841b89d614 217
AjK 0:0a841b89d614 218 /* Handle the analogue sticks. */
AjK 0:0a841b89d614 219 {
AjK 0:0a841b89d614 220 short x, y;
AjK 0:0a841b89d614 221 x = (short)((IF_ZERO.pipe[(int)userData].data_in[6]) | IF_ZERO.pipe[(int)userData].data_in[7] << 8);
AjK 0:0a841b89d614 222 y = (short)((IF_ZERO.pipe[(int)userData].data_in[8]) | IF_ZERO.pipe[(int)userData].data_in[9] << 8);
AjK 0:0a841b89d614 223 if (x != stick_left.x_previous) {
AjK 0:0a841b89d614 224 stick_left.x_previous = stick_left.x;
AjK 0:0a841b89d614 225 stick_left.x = x;
AjK 0:0a841b89d614 226 }
AjK 0:0a841b89d614 227 if (y != stick_left.y_previous) {
AjK 0:0a841b89d614 228 stick_left.y_previous = stick_left.y;
AjK 0:0a841b89d614 229 stick_left.y = y;
AjK 0:0a841b89d614 230 }
AjK 0:0a841b89d614 231 x = (short)((IF_ZERO.pipe[(int)userData].data_in[10]) | IF_ZERO.pipe[(int)userData].data_in[11] << 8);
AjK 0:0a841b89d614 232 y = (short)((IF_ZERO.pipe[(int)userData].data_in[12]) | IF_ZERO.pipe[(int)userData].data_in[13] << 8);
AjK 0:0a841b89d614 233 if (x != stick_right.x_previous) {
AjK 0:0a841b89d614 234 stick_right.x_previous = stick_right.x;
AjK 0:0a841b89d614 235 stick_right.x = x;
AjK 0:0a841b89d614 236 }
AjK 0:0a841b89d614 237 if (y != stick_right.y_previous) {
AjK 0:0a841b89d614 238 stick_right.y_previous = stick_right.y;
AjK 0:0a841b89d614 239 stick_right.y = y;
AjK 0:0a841b89d614 240 }
AjK 0:0a841b89d614 241 }
AjK 0:0a841b89d614 242 }
AjK 0:0a841b89d614 243 else if(len == 3) {
AjK 0:0a841b89d614 244 /* Chatpad return? */
AjK 0:0a841b89d614 245 #ifdef DEBUG_USB_DRIVER_IF_0
AjK 0:0a841b89d614 246 debug_printf("Got %02x %02x %02x \r\n", buf[0], buf[1], buf[2]);
AjK 0:0a841b89d614 247 #endif
AjK 0:0a841b89d614 248 }
AjK 0:0a841b89d614 249 else {
AjK 0:0a841b89d614 250 #ifdef DEBUG_USB_DRIVER_IF_0
AjK 0:0a841b89d614 251 DEBUG_UNKNOWN_PACKET_IF_0
AjK 0:0a841b89d614 252 #endif
AjK 0:0a841b89d614 253 }
AjK 0:0a841b89d614 254
AjK 0:0a841b89d614 255 /* Schedule another transfer to keep the IN flow of data coming. */
AjK 0:0a841b89d614 256 usbeh_api_interrupt_transfer(device, endpoint, IF_ZERO.pipe[(int)userData].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_0_in, userData);
AjK 0:0a841b89d614 257 }
AjK 0:0a841b89d614 258
AjK 0:0a841b89d614 259 void xbox360gamepad_interface_1_in(int device, int endpoint, int status, USBEH_U08 *data, int len, void *userData) {
AjK 0:0a841b89d614 260 /* We don't currently do anything with Interface:1 */
AjK 0:0a841b89d614 261 #ifdef DEBUG_USB_DRIVER_IF_1
AjK 0:0a841b89d614 262 DEBUG_UNKNOWN_PACKET_IF_1
AjK 0:0a841b89d614 263 #endif
AjK 0:0a841b89d614 264
AjK 0:0a841b89d614 265 /* Schedule another transfer to keep the IN flow of data coming. */
AjK 0:0a841b89d614 266 usbeh_api_interrupt_transfer(device, endpoint, IF_ONE.pipe[(int)userData].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_1_in, userData);
AjK 0:0a841b89d614 267 }
AjK 0:0a841b89d614 268
AjK 0:0a841b89d614 269 void xbox360gamepad_interface_2_in(int device, int endpoint, int status, USBEH_U08 *data, int len, void *userData) {
AjK 0:0a841b89d614 270 /* We don't currently do anything with Interface:2 */
AjK 0:0a841b89d614 271 #ifdef DEBUG_USB_DRIVER_IF_2
AjK 0:0a841b89d614 272 DEBUG_UNKNOWN_PACKET_IF_2
AjK 0:0a841b89d614 273 #endif
AjK 0:0a841b89d614 274
AjK 0:0a841b89d614 275 /* Schedule another transfer to keep the IN flow of data coming. */
AjK 0:0a841b89d614 276 usbeh_api_interrupt_transfer(device, endpoint, IF_TWO.pipe[(int)userData].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_2_in, userData);
AjK 0:0a841b89d614 277 }
AjK 0:0a841b89d614 278
AjK 0:0a841b89d614 279 int xbox360gamepad_add_interface(int device, USBEH_interfaceDescriptor *iface, USBEH_endpointDescriptor *ed) {
AjK 0:0a841b89d614 280
AjK 0:0a841b89d614 281 /* Handle interrupt IN transfers. */
AjK 0:0a841b89d614 282 if ((ed->bmAttributes & 3) != USBEH_ENDPOINT_INTERRUPT) {
AjK 0:0a841b89d614 283 return 0;
AjK 0:0a841b89d614 284 }
AjK 0:0a841b89d614 285
AjK 0:0a841b89d614 286 if (iface->bInterfaceNumber == 0) {
AjK 0:0a841b89d614 287 int pipe = 0;
AjK 0:0a841b89d614 288 if (ed->bEndpointAddress & 0x80) {
AjK 0:0a841b89d614 289 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 290 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 291 #endif
AjK 0:0a841b89d614 292 IF_ZERO.pipe[pipe].ep_number_in = ed->bEndpointAddress;
AjK 0:0a841b89d614 293 usbeh_api_interrupt_transfer(device, ed->bEndpointAddress, IF_ZERO.pipe[0].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_0_in, (void *)pipe);
AjK 0:0a841b89d614 294 }
AjK 0:0a841b89d614 295 else {
AjK 0:0a841b89d614 296 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 297 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 298 #endif
AjK 0:0a841b89d614 299 IF_ZERO.pipe[pipe].ep_number_out = ed->bEndpointAddress;
AjK 0:0a841b89d614 300 }
AjK 0:0a841b89d614 301 }
AjK 0:0a841b89d614 302
AjK 0:0a841b89d614 303 if (iface->bInterfaceNumber == 1) {
AjK 0:0a841b89d614 304 int pipe = (IF_ONE.pipe[0].ep_number_in == 0) ? 0 : 1;
AjK 0:0a841b89d614 305 if (ed->bEndpointAddress & 0x80) {
AjK 0:0a841b89d614 306 IF_ONE.pipe[pipe].ep_number_in = ed->bEndpointAddress;
AjK 0:0a841b89d614 307 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 308 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 309 #endif
AjK 0:0a841b89d614 310 usbeh_api_interrupt_transfer(device, ed->bEndpointAddress, IF_ONE.pipe[pipe].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_1_in, (void *)pipe);
AjK 0:0a841b89d614 311 }
AjK 0:0a841b89d614 312 else {
AjK 0:0a841b89d614 313 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 314 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 315 #endif
AjK 0:0a841b89d614 316 IF_ONE.pipe[pipe].ep_number_out = ed->bEndpointAddress;
AjK 0:0a841b89d614 317 }
AjK 0:0a841b89d614 318 }
AjK 0:0a841b89d614 319
AjK 0:0a841b89d614 320
AjK 0:0a841b89d614 321 if (iface->bInterfaceNumber == 2) {
AjK 0:0a841b89d614 322 int pipe = (IF_TWO.pipe[0].ep_number_in == 0) ? 0 : 1;
AjK 0:0a841b89d614 323 if (ed->bEndpointAddress & 0x80) {
AjK 0:0a841b89d614 324 IF_TWO.pipe[pipe].ep_number_in = ed->bEndpointAddress;
AjK 0:0a841b89d614 325 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 326 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 327 #endif
AjK 0:0a841b89d614 328 usbeh_api_interrupt_transfer(device, ed->bEndpointAddress, IF_TWO.pipe[pipe].data_in, XBOX360_GAMEPAD_PIPE_BUFFER_SIZE, xbox360gamepad_interface_2_in, (void *)pipe);
AjK 0:0a841b89d614 329 }
AjK 0:0a841b89d614 330 else {
AjK 0:0a841b89d614 331 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 332 DEBUG_USB_MSG_ALLOCATION
AjK 0:0a841b89d614 333 #endif
AjK 0:0a841b89d614 334 IF_TWO.pipe[pipe].ep_number_out = ed->bEndpointAddress;
AjK 0:0a841b89d614 335 }
AjK 0:0a841b89d614 336 }
AjK 0:0a841b89d614 337
AjK 0:0a841b89d614 338 return 1;
AjK 0:0a841b89d614 339 }
AjK 0:0a841b89d614 340
AjK 0:0a841b89d614 341 static XBOX360_DEVICE * xbox360gamepad_vendor_product_check(uint16_t vendorId, uint16_t productId) {
AjK 0:0a841b89d614 342 for (int i = 0; xbox360_devices[i].idVendor != 0; i++) {
AjK 0:0a841b89d614 343 if (xbox360_devices[i].idVendor == vendorId && xbox360_devices[i].idProduct == productId) {
AjK 0:0a841b89d614 344 return &xbox360_devices[i];
AjK 0:0a841b89d614 345 }
AjK 0:0a841b89d614 346 }
AjK 0:0a841b89d614 347 return (XBOX360_DEVICE *)NULL;
AjK 0:0a841b89d614 348 }
AjK 0:0a841b89d614 349
AjK 0:0a841b89d614 350 void xbox360gamepad_led(int code) {
AjK 0:0a841b89d614 351 IF_ZERO.pipe[0].data_out[0] = 0x01;
AjK 0:0a841b89d614 352 IF_ZERO.pipe[0].data_out[1] = 0x03;
AjK 0:0a841b89d614 353 IF_ZERO.pipe[0].data_out[2] = code;
AjK 0:0a841b89d614 354 usbeh_api_interrupt_transfer(deviceNumber, IF_ZERO.pipe[0].ep_number_out, IF_ZERO.pipe[0].data_out, 3, NULL, NULL);
AjK 0:0a841b89d614 355 }
AjK 0:0a841b89d614 356
AjK 0:0a841b89d614 357 USBEH_U08 noise[] = "\x0\x8\x0\x0\x0\x0\x0\x0";
AjK 0:0a841b89d614 358
AjK 0:0a841b89d614 359 void xbox360_noise(int device, int endpoint, int status, USBEH_U08 *data, int len, void *userData) {
AjK 0:0a841b89d614 360 usbeh_api_interrupt_transfer(deviceNumber, IF_ZERO.pipe[0].ep_number_out, noise, 8, xbox360_noise, NULL);
AjK 0:0a841b89d614 361 }
AjK 0:0a841b89d614 362
AjK 0:0a841b89d614 363 int xbox360gamepad_onload_callback(int device, USBEH_deviceDescriptor *deviceDesc, USBEH_interfaceDescriptor **interfaceDesc) {
AjK 0:0a841b89d614 364 USBEH_interfaceDescriptor *iface;
AjK 0:0a841b89d614 365 int length, endpoint_count, interfaceCounter = 0;
AjK 0:0a841b89d614 366 USBEH_U08 *start, *end;
AjK 0:0a841b89d614 367
AjK 0:0a841b89d614 368 /* Is this a Microsoft Xbox360 wired Gamepad? */
AjK 0:0a841b89d614 369 XBOX360_DEVICE *xd = xbox360gamepad_vendor_product_check(deviceDesc->idVendor, deviceDesc->idProduct);
AjK 0:0a841b89d614 370 if (!xd) {
AjK 0:0a841b89d614 371 /* If not, don't claim it. */
AjK 0:0a841b89d614 372 return 0;
AjK 0:0a841b89d614 373 }
AjK 0:0a841b89d614 374
AjK 0:0a841b89d614 375 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 376 debug_printf("Found device '%s'\r\n", xd->name);
AjK 0:0a841b89d614 377 #endif
AjK 0:0a841b89d614 378
AjK 0:0a841b89d614 379 /* Save our device number in a global. */
AjK 0:0a841b89d614 380 deviceNumber = device;
AjK 0:0a841b89d614 381
AjK 0:0a841b89d614 382 memset((char *)&IF_VENDOR, 0, sizeof(IF_VENDOR));
AjK 0:0a841b89d614 383 memset((char *)&IF_ZERO, 0, sizeof(IF_ZERO));
AjK 0:0a841b89d614 384 memset((char *)&IF_ONE, 0, sizeof(IF_ONE));
AjK 0:0a841b89d614 385 memset((char *)&IF_TWO, 0, sizeof(IF_TWO));
AjK 0:0a841b89d614 386
AjK 0:0a841b89d614 387 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 388 debug_printf("%s() ACTIVATED for device id = %d\r\n", __FUNCTION__, device);
AjK 0:0a841b89d614 389 debug_printf(" OnLoad VendorId = 0x%04x ProductId = 0x%04x \r\n", deviceDesc->idVendor, deviceDesc->idProduct);
AjK 0:0a841b89d614 390 #endif
AjK 0:0a841b89d614 391
AjK 0:0a841b89d614 392 /* Parse the interface configuration and setup the endpoint handlers. */
AjK 0:0a841b89d614 393 while ((iface = interfaceDesc[interfaceCounter]) != (USBEH_interfaceDescriptor *)NULL) {
AjK 0:0a841b89d614 394 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 395 debug_printf(" interface%d:- \r\n", interfaceCounter);
AjK 0:0a841b89d614 396 debug_printf(" InterfaceClass = %02x \r\n", iface->bInterfaceClass);
AjK 0:0a841b89d614 397 debug_printf(" InterfaceSubClass = %02x \r\n", iface->bInterfaceSubClass);
AjK 0:0a841b89d614 398 debug_printf(" InterfaceProtocol = %02x \r\n", iface->bInterfaceProtocol);
AjK 0:0a841b89d614 399 #endif
AjK 0:0a841b89d614 400 start = (USBEH_U08 *)iface;
AjK 0:0a841b89d614 401 length = start[0];
AjK 0:0a841b89d614 402 end = start + length;
AjK 0:0a841b89d614 403 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 404 debug_printf(" Scanning at start:%08x length:%d end:%08x \r\n", start, length, end);
AjK 0:0a841b89d614 405 #endif
AjK 0:0a841b89d614 406 while (start < end) {
AjK 0:0a841b89d614 407 if (start[1] == USBEH_DESCRIPTOR_TYPE_INTERFACE) {
AjK 0:0a841b89d614 408 USBEH_interfaceDescriptor *id = (USBEH_interfaceDescriptor *)start;
AjK 0:0a841b89d614 409 //int interfaceNumber = (int)id->bInterfaceNumber;
AjK 0:0a841b89d614 410 endpoint_count = (int)id->bNumEndpoints;
AjK 0:0a841b89d614 411 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 412 debug_printf(" found definition for if:%d with %d endpoints.\r\n", interfaceNumber, endpoint_count);
AjK 0:0a841b89d614 413 #endif
AjK 0:0a841b89d614 414 start += start[0];
AjK 0:0a841b89d614 415 while (endpoint_count > 0) {
AjK 0:0a841b89d614 416 if (start[1] == USBEH_DESCRIPTOR_TYPE_ENDPOINT) {
AjK 0:0a841b89d614 417 USBEH_endpointDescriptor *ed = (USBEH_endpointDescriptor *)start;
AjK 0:0a841b89d614 418 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 419 debug_printf(" found endpoint 0x%02X\r\n", ed->bEndpointAddress);
AjK 0:0a841b89d614 420 #endif
AjK 0:0a841b89d614 421 xbox360gamepad_add_interface(device, id, ed);
AjK 0:0a841b89d614 422 endpoint_count--;
AjK 0:0a841b89d614 423 }
AjK 0:0a841b89d614 424 else {
AjK 0:0a841b89d614 425 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 426 debug_printf(" no endpoint for interface, descriptor class: %02X\r\n", start[1]);
AjK 0:0a841b89d614 427 #endif
AjK 0:0a841b89d614 428 }
AjK 0:0a841b89d614 429 start += start[0];
AjK 0:0a841b89d614 430 }
AjK 0:0a841b89d614 431 }
AjK 0:0a841b89d614 432 else {
AjK 0:0a841b89d614 433 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 434 debug_printf(" no IF descr found at %08x\r\n", start);
AjK 0:0a841b89d614 435 #endif
AjK 0:0a841b89d614 436 start += start[0];
AjK 0:0a841b89d614 437 }
AjK 0:0a841b89d614 438 }
AjK 0:0a841b89d614 439
AjK 0:0a841b89d614 440 interfaceCounter++;
AjK 0:0a841b89d614 441 }
AjK 0:0a841b89d614 442
AjK 0:0a841b89d614 443 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 444 debug_printf("Device claimed by %s().\r\n\n", __FUNCTION__);
AjK 0:0a841b89d614 445 #endif
AjK 0:0a841b89d614 446
AjK 0:0a841b89d614 447 /* When the gamepad boots up, the LED ring flashes after it's
AjK 0:0a841b89d614 448 configuration is set. Let's flash the led and go steady. */
AjK 0:0a841b89d614 449 xbox360gamepad_led(LED_1_FLASH_THEN_ON);
AjK 0:0a841b89d614 450
AjK 0:0a841b89d614 451 /* Lets just send "noise" to the headset and see what happens. */
AjK 0:0a841b89d614 452 //usbeh_api_interrupt_transfer(deviceNumber, IF_ZERO.pipe[0].ep_number_out, noise, 8, xbox360_noise, NULL);
AjK 0:0a841b89d614 453
AjK 0:0a841b89d614 454 /* I give up, wtf is it with this chatpad that MS needs to keep so secret? */
AjK 0:0a841b89d614 455 //xbox360_chatpad_init();
AjK 0:0a841b89d614 456
AjK 0:0a841b89d614 457 /* Tell the USB embedded host that we have claimed this device. */
AjK 0:0a841b89d614 458 return 1;
AjK 0:0a841b89d614 459 }
AjK 0:0a841b89d614 460
AjK 0:0a841b89d614 461 #ifdef NEVERCOMPILETHISCODE
AjK 0:0a841b89d614 462 /*
AjK 0:0a841b89d614 463
AjK 0:0a841b89d614 464 UPDATE: Everything below is ABANDONED when I basically figured out from one replay to the next
AjK 0:0a841b89d614 465 that MS use the security channel to "handshake" init the chatpad. Many people believe
AjK 0:0a841b89d614 466 the security device in the gamepad is to "tell the xbox I am a real auth MS gamepad". However,
AjK 0:0a841b89d614 467 as I have discovered, it's "two-way". There also exists the "tell the gamepad that an auth
AjK 0:0a841b89d614 468 Xbox360 is the host" and without that the chatpad will not function. I have no interest in
AjK 0:0a841b89d614 469 trying to crack anyones security chips so no further work will be done on this.
AjK 0:0a841b89d614 470
AjK 0:0a841b89d614 471 Everything below here is related to the chatpad attachment for the Xbox360 gamepad controller.
AjK 0:0a841b89d614 472 Unlike the sticks, triggers and buttons, the chatpad appears to require some sort of initialization
AjK 0:0a841b89d614 473 in order to start running. Since MS have not published any sort of USB protocol specifications
AjK 0:0a841b89d614 474 for their gamepad, what we do here is basically a "replay attack" based on packets sent and received
AjK 0:0a841b89d614 475 between an Xbox and a gamepad with a USB protocol analyser in the middle. A classic man-in-the-middle
AjK 0:0a841b89d614 476 type of attack.
AjK 0:0a841b89d614 477
AjK 0:0a841b89d614 478 Here's the basic sequence we attempt to follow:-
AjK 0:0a841b89d614 479
AjK 0:0a841b89d614 480 1. -> Vendor request IN EP0 (0x01)
AjK 0:0a841b89d614 481 -> SETUP C0 01 00 00 00 00 04 00
AjK 0:0a841b89d614 482 <- IN 80 03 0D 47
AjK 0:0a841b89d614 483 2. -> Vendor request OUT EP0 (0xA9)
AjK 0:0a841b89d614 484 -> 40 A9 0C A3 23 44 00
AjK 0:0a841b89d614 485 <- Expect STALLED no data
AjK 0:0a841b89d614 486 3. -> Vendor request OUT EP0 (0xA9)
AjK 0:0a841b89d614 487 -> 40 A9 44 23 03 7F 00 00
AjK 0:0a841b89d614 488 <- Expect STALLED no data
AjK 0:0a841b89d614 489 4. -> Vendor request OUT EP0 (0xA9)
AjK 0:0a841b89d614 490 -> 40 A9 39 58 32 68 00 00
AjK 0:0a841b89d614 491 <- Expect STALLED no data
AjK 0:0a841b89d614 492 5. <- IN IF:0 EP2 3 bytes 01 03 0E
AjK 0:0a841b89d614 493 6. -> Vendor request IN EP0 (0xA1)
AjK 0:0a841b89d614 494 -> SETUP C0 A1 00 00 16 E4 02 00
AjK 0:0a841b89d614 495 <- IN 01 00
AjK 0:0a841b89d614 496 7. -> OUT IF:0 EP1 3 bytes 01 03 01
AjK 0:0a841b89d614 497 8. -> Vendor request OUT EP0 (0xA1)
AjK 0:0a841b89d614 498 -> SETUP 40 A1 00 00 16 E4 02 00
AjK 0:0a841b89d614 499 -> OUT 09 00
AjK 0:0a841b89d614 500 9. -> Vendor request IN EP0 (0xA1)
AjK 0:0a841b89d614 501 -> SETUP C0 A1 00 00 16 E4 02 00
AjK 0:0a841b89d614 502 -> IN 09 00 (echo previous OUT?)
AjK 0:0a841b89d614 503 10. <- IN IF:0 EP 1 3 bytes 02 03 00
AjK 0:0a841b89d614 504 11. <- IN IF:0 EP 1 3 bytes 03 03 03
AjK 0:0a841b89d614 505 12. <- IN IF:0 EP 1 3 bytes 08 03 00
AjK 0:0a841b89d614 506 13. <- IN IF:0 EP 1 3 bytes 01 03 01
AjK 0:0a841b89d614 507 14. -> Vendor request OUT EP0 (0x00)
AjK 0:0a841b89d614 508 -> SETUP 41 00 1F 00 02 00 00 00
AjK 0:0a841b89d614 509 -> IN No data
AjK 0:0a841b89d614 510 15. -> Vendor request OUT EP0 (0x00)
AjK 0:0a841b89d614 511 -> SETUP 41 00 1E 00 02 00 00 00
AjK 0:0a841b89d614 512 -> IN No data
AjK 0:0a841b89d614 513
AjK 0:0a841b89d614 514 Note that 14. and 15. are 1second apart and repeat continuely
AjK 0:0a841b89d614 515 toggling between 1F and 1E each second.
AjK 0:0a841b89d614 516
AjK 0:0a841b89d614 517 16. <- IN IF:2 EP4 (IF:2 PIPE1) 5 bytes F0 03 00 01 01
AjK 0:0a841b89d614 518 17. -> Vendor request OUT EP0 (0x00)
AjK 0:0a841b89d614 519 -> SETUP 41 00 1B 00 02 00 00 00
AjK 0:0a841b89d614 520 -> IN No data
AjK 0:0a841b89d614 521 18. <- IN IF:2 EP4 (IF:2 PIPE1) 5 bytes F0 03 00 01 01
AjK 0:0a841b89d614 522 19. -> Vendor request OUT EP0 (0x00)
AjK 0:0a841b89d614 523 -> SETUP 41 00 1B 00 02 00 00 00
AjK 0:0a841b89d614 524 -> IN No data
AjK 0:0a841b89d614 525
AjK 0:0a841b89d614 526
AjK 0:0a841b89d614 527 After this we start receiving data from IF:2 PIPE1
AjK 0:0a841b89d614 528
AjK 0:0a841b89d614 529 */
AjK 0:0a841b89d614 530 USBEH_U08 chatpad_trash_buffer[256];
AjK 0:0a841b89d614 531 USBEH_U08 chatpad_toggle;
AjK 0:0a841b89d614 532 USBEH_U08 chatpad_send_toggle;
AjK 0:0a841b89d614 533 USBEH_U08 chatpad_toggle_1Bsent;
AjK 0:0a841b89d614 534 USBEH_SOF_COUNTER chatpad_toggle_timer;
AjK 0:0a841b89d614 535
AjK 0:0a841b89d614 536 void xbox360_chatpad_toggle(int device, int endpoint, int status, USBEH_U08 *data, int len, void *userData) {
AjK 0:0a841b89d614 537 int result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 538 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_INTERFACE,
AjK 0:0a841b89d614 539 0x00,
AjK 0:0a841b89d614 540 (int)userData,
AjK 0:0a841b89d614 541 0x0002,
AjK 0:0a841b89d614 542 chatpad_trash_buffer,
AjK 0:0a841b89d614 543 0,
AjK 0:0a841b89d614 544 xbox360_chatpad_toggle,
AjK 0:0a841b89d614 545 (userData == (void *)0x1E) ? (void *)0x001F : (void *)0x001E);
AjK 0:0a841b89d614 546 //debug.printf("TOGGLE = 0x%x\r\n", -result & 0xf);
AjK 0:0a841b89d614 547 }
AjK 0:0a841b89d614 548
AjK 0:0a841b89d614 549 void xbox360_chatpad_timed_toggle(USBEH_SOF_COUNTER *q) {
AjK 0:0a841b89d614 550 int result;
AjK 0:0a841b89d614 551
AjK 0:0a841b89d614 552 debug_printf("%s() called.\r\n", __FUNCTION__);
AjK 0:0a841b89d614 553
AjK 0:0a841b89d614 554 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 555 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_INTERFACE,
AjK 0:0a841b89d614 556 0x00,
AjK 0:0a841b89d614 557 (int)q->userData == 0x1F ? 0x001F : 0x001E,
AjK 0:0a841b89d614 558 0x0002,
AjK 0:0a841b89d614 559 chatpad_trash_buffer,
AjK 0:0a841b89d614 560 0,
AjK 0:0a841b89d614 561 0, 0);
AjK 0:0a841b89d614 562
AjK 0:0a841b89d614 563 debug_printf("repeat! 1F/E = 0x%x\r\n", -result & 0xf);
AjK 0:0a841b89d614 564
AjK 0:0a841b89d614 565 if (1 && !chatpad_toggle_1Bsent) {
AjK 0:0a841b89d614 566 chatpad_toggle_1Bsent = 1;
AjK 0:0a841b89d614 567
AjK 0:0a841b89d614 568 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 569 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_INTERFACE,
AjK 0:0a841b89d614 570 0x00,
AjK 0:0a841b89d614 571 0x001B,
AjK 0:0a841b89d614 572 0x0002,
AjK 0:0a841b89d614 573 chatpad_trash_buffer,
AjK 0:0a841b89d614 574 0,
AjK 0:0a841b89d614 575 0, 0);
AjK 0:0a841b89d614 576 }
AjK 0:0a841b89d614 577
AjK 0:0a841b89d614 578 debug_printf("repeat! 1B = 0x%x\r\n", -result & 0xf);
AjK 0:0a841b89d614 579
AjK 0:0a841b89d614 580 //usbeh_sof_counter_unregister(&chatpad_toggle_timer);
AjK 0:0a841b89d614 581 //usbeh_sof_counter_init(&chatpad_toggle_timer, USBEH_SOF_COUNTER_DEC | USBEH_SOF_COUNTER_RELOAD, 1700);
AjK 0:0a841b89d614 582 //chatpad_toggle_timer.userData = (int)q->userData == 0x1F ? 0x001F : 0x001E;
AjK 0:0a841b89d614 583 //chatpad_toggle_timer.callback = xbox360_chatpad_timed;
AjK 0:0a841b89d614 584 //chatpad_toggle_timer.flag = 0;
AjK 0:0a841b89d614 585 //usbeh_sof_counter_register(&chatpad_toggle_timer);
AjK 0:0a841b89d614 586
AjK 0:0a841b89d614 587
AjK 0:0a841b89d614 588 }
AjK 0:0a841b89d614 589
AjK 0:0a841b89d614 590 void xbox360_chatpad_init(void) {
AjK 0:0a841b89d614 591 int result;
AjK 0:0a841b89d614 592 USBEH_U08 buffer[256];
AjK 0:0a841b89d614 593 USBEH_U08 data[256];
AjK 0:0a841b89d614 594
AjK 0:0a841b89d614 595 // int usbeh_api_control_transfer(int device,
AjK 0:0a841b89d614 596 // int request_type,
AjK 0:0a841b89d614 597 // int request,
AjK 0:0a841b89d614 598 // int value,
AjK 0:0a841b89d614 599 // int index,
AjK 0:0a841b89d614 600 // USBEH_U08 *data,
AjK 0:0a841b89d614 601 // int length,
AjK 0:0a841b89d614 602 // USBEH_callback callback, void *userData) {
AjK 0:0a841b89d614 603 // int r = usbeh_api_control_transfer(device, USBEH_DEVICE_TO_HOST | USBEH_REQUEST_TYPE_CLASS | USBEH_RECIPIENT_DEVICE, USBEH_GET_DESCRIPTOR, (USBEH_DESCRIPTOR_TYPE_HUB << 8), 0, buffer, sizeof(buffer), 0, 0);
AjK 0:0a841b89d614 604
AjK 0:0a841b89d614 605 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 606 USBEH_DEVICE_TO_HOST | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 607 0x01,
AjK 0:0a841b89d614 608 0x0000,
AjK 0:0a841b89d614 609 0x0000,
AjK 0:0a841b89d614 610 buffer,
AjK 0:0a841b89d614 611 4,
AjK 0:0a841b89d614 612 0, 0);
AjK 0:0a841b89d614 613 debug_printf("Step 1 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 614
AjK 0:0a841b89d614 615 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 616 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 617 0xA9,
AjK 0:0a841b89d614 618 0xA30C,
AjK 0:0a841b89d614 619 0x4423,
AjK 0:0a841b89d614 620 buffer,
AjK 0:0a841b89d614 621 0,
AjK 0:0a841b89d614 622 0, 0);
AjK 0:0a841b89d614 623 debug_printf("Step 2 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 624
AjK 0:0a841b89d614 625 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 626 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 627 0xA9,
AjK 0:0a841b89d614 628 0x2344,
AjK 0:0a841b89d614 629 0x7F03,
AjK 0:0a841b89d614 630 buffer,
AjK 0:0a841b89d614 631 0,
AjK 0:0a841b89d614 632 0, 0);
AjK 0:0a841b89d614 633 debug_printf("Step 3 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 634
AjK 0:0a841b89d614 635 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 636 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 637 0xA9,
AjK 0:0a841b89d614 638 0x5839,
AjK 0:0a841b89d614 639 0x6832,
AjK 0:0a841b89d614 640 buffer,
AjK 0:0a841b89d614 641 0,
AjK 0:0a841b89d614 642 0, 0);
AjK 0:0a841b89d614 643 debug_printf("Step 4 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 644
AjK 0:0a841b89d614 645 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 646 USBEH_DEVICE_TO_HOST | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 647 0xA1,
AjK 0:0a841b89d614 648 0x0000,
AjK 0:0a841b89d614 649 0xE416,
AjK 0:0a841b89d614 650 buffer,
AjK 0:0a841b89d614 651 2,
AjK 0:0a841b89d614 652 0, 0);
AjK 0:0a841b89d614 653 debug_printf("Step 5 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 654
AjK 0:0a841b89d614 655 data[0] = 9; data[1] = 0;
AjK 0:0a841b89d614 656 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 657 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 658 0xA1,
AjK 0:0a841b89d614 659 0x5839,
AjK 0:0a841b89d614 660 0xE416,
AjK 0:0a841b89d614 661 data,
AjK 0:0a841b89d614 662 2,
AjK 0:0a841b89d614 663 0, 0);
AjK 0:0a841b89d614 664 debug_printf("Step 6 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 665
AjK 0:0a841b89d614 666 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 667 USBEH_DEVICE_TO_HOST | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_DEVICE,
AjK 0:0a841b89d614 668 0xA1,
AjK 0:0a841b89d614 669 0x0000,
AjK 0:0a841b89d614 670 0xE416,
AjK 0:0a841b89d614 671 buffer,
AjK 0:0a841b89d614 672 2,
AjK 0:0a841b89d614 673 0, 0);
AjK 0:0a841b89d614 674 debug_printf("Step 7 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 675
AjK 0:0a841b89d614 676 // Now begin toggling 1F / 1E
AjK 0:0a841b89d614 677 chatpad_toggle = 0x1E;
AjK 0:0a841b89d614 678 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 679 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_INTERFACE,
AjK 0:0a841b89d614 680 0x00,
AjK 0:0a841b89d614 681 0x001F,
AjK 0:0a841b89d614 682 0x0002,
AjK 0:0a841b89d614 683 chatpad_trash_buffer,
AjK 0:0a841b89d614 684 0,
AjK 0:0a841b89d614 685 xbox360_chatpad_toggle,
AjK 0:0a841b89d614 686 (void *)0x1E);
AjK 0:0a841b89d614 687 debug_printf("Step 8 TOGGLE = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 688
AjK 0:0a841b89d614 689 result = usbeh_api_control_transfer(deviceNumber,
AjK 0:0a841b89d614 690 USBEH_HOST_TO_DEVICE | USBEH_SETUP_TYPE_MASK_VENDOR | USBEH_RECIPIENT_INTERFACE,
AjK 0:0a841b89d614 691 0x00,
AjK 0:0a841b89d614 692 0x0003,
AjK 0:0a841b89d614 693 0x0002,
AjK 0:0a841b89d614 694 chatpad_trash_buffer,
AjK 0:0a841b89d614 695 0,
AjK 0:0a841b89d614 696 0,
AjK 0:0a841b89d614 697 0);
AjK 0:0a841b89d614 698 debug_printf("Step 9 OUT 0x03 = 0x%x %02x %02x %02x %02x \r\n", result, buffer[0], buffer[1], buffer[2], buffer[3]);
AjK 0:0a841b89d614 699
AjK 0:0a841b89d614 700 //usbeh_sof_counter_init(&chatpad_toggle_timer, USBEH_SOF_COUNTER_DEC | USBEH_SOF_COUNTER_RELOAD, 1700);
AjK 0:0a841b89d614 701 //chatpad_toggle_timer.userData = (int)chatpad_toggle;
AjK 0:0a841b89d614 702 //chatpad_toggle_timer.callback = xbox360_chatpad_timed;
AjK 0:0a841b89d614 703 //usbeh_sof_counter_register(&chatpad_toggle_timer);
AjK 0:0a841b89d614 704
AjK 0:0a841b89d614 705 }
AjK 0:0a841b89d614 706
AjK 0:0a841b89d614 707 #endif