Skip to content

Instantly share code, notes, and snippets.

@mildmojo
Created August 10, 2016 01:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mildmojo/ae8f83620aea980a680d32fe0202be87 to your computer and use it in GitHub Desktop.
Save mildmojo/ae8f83620aea980a680d32fe0202be87 to your computer and use it in GitHub Desktop.
Diff on Arduino 1.6.9 + TeensyDuino 1.29 adding XInput support per http://www.zlittell.com/2015/07/fightstick/
diff -ruw a2/arduino-1.6.9/hardware/teensy/avr/boards.txt arduino-1.6.9/hardware/teensy/avr/boards.txt
--- a2/arduino-1.6.9/hardware/teensy/avr/boards.txt Tue Aug 9 20:50:12 2016
+++ arduino-1.6.9/hardware/teensy/avr/boards.txt Mon Aug 8 05:20:42 2016
@@ -65,6 +65,9 @@
teensy31.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick
teensy31.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK
teensy31.menu.usb.flightsimjoystick.fake_serial=teensy_gateway
+teensy31.menu.usb.xinput=[MSF] Shoryuken! (XINPUT DEVICE)
+teensy31.menu.usb.xinput.build.usbtype=USB_XINPUT
+teensy31.menu.usb.xinput.fake_serial=teensy_gateway
teensy31.menu.usb.everything=All of the Above
teensy31.menu.usb.everything.build.usbtype=USB_EVERYTHING
teensy31.menu.usb.disable=No USB
@@ -241,6 +244,9 @@
teensy30.menu.usb.flightsim=Flight Sim Controls
teensy30.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM
teensy30.menu.usb.flightsim.fake_serial=teensy_gateway
+teensy30.menu.usb.xinput=[MSF] Shoryuken! (XINPUT DEVICE)
+teensy30.menu.usb.xinput.build.usbtype=USB_XINPUT
+teensy30.menu.usb.xinput.fake_serial=teensy_gateway
teensy30.menu.usb.disable=No USB
teensy30.menu.usb.disable.build.usbtype=USB_DISABLED
teensy30.menu.speed.96=96 MHz (overclock)
@@ -352,6 +358,9 @@
teensyLC.menu.usb.flightsim=Flight Sim Controls
teensyLC.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM
teensyLC.menu.usb.flightsim.fake_serial=teensy_gateway
+teensyLC.menu.usb.xinput=[MSF] Shoryuken! (XINPUT DEVICE)
+teensyLC.menu.usb.xinput.build.usbtype=USB_XINPUT
+teensyLC.menu.usb.xinput.fake_serial=teensy_gateway
teensyLC.menu.usb.disable=No USB
teensyLC.menu.usb.disable.build.usbtype=USB_DISABLED
teensyLC.menu.speed.48=48 MHz
diff -ruw a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/WProgram.h arduino-1.6.9/hardware/teensy/avr/cores/teensy3/WProgram.h
--- a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/WProgram.h Tue Aug 9 20:48:45 2016
+++ arduino-1.6.9/hardware/teensy/avr/cores/teensy3/WProgram.h Mon Aug 8 05:22:10 2016
@@ -29,6 +29,7 @@
#include "usb_midi.h"
#include "usb_rawhid.h"
#include "usb_flightsim.h"
+#include "usb_xinput.h"
#include "usb_mtp.h"
#include "usb_audio.h"
#include "usb_touch.h"
diff -ruw a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.c arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.c
--- a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.c Tue Aug 9 20:48:47 2016
+++ arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.c Tue Aug 9 20:21:31 2016
@@ -87,7 +87,11 @@
EP0_SIZE, // bMaxPacketSize0
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
+#ifdef DEVICE_VERSION // bcdDevice
+ LSB(DEVICE_VERSION), MSB(DEVICE_VERSION),
+#else
0x00, 0x02, // bcdDevice
+#endif
1, // iManufacturer
2, // iProduct
3, // iSerialNumber
@@ -488,8 +492,11 @@
#define MULTITOUCH_INTERFACE_DESC_SIZE 0
#endif
+#ifdef USB_XINPUT
+#define CONFIG_DESC_SIZE 153
+#else
#define CONFIG_DESC_SIZE MULTITOUCH_INTERFACE_DESC_POS+MULTITOUCH_INTERFACE_DESC_SIZE
-
+#endif
// **************************************************************
@@ -507,9 +514,16 @@
NUM_INTERFACE, // bNumInterfaces
1, // bConfigurationValue
0, // iConfiguration
- 0xC0, // bmAttributes
- 50, // bMaxPower
-
+#ifdef DEVICE_ATTRIBUTES
+ DEVICE_ATTRIBUTES, // bmAttributes
+#else
+ 0xC0,
+#endif
+#ifdef DEVICE_POWER
+ DEVICE_POWER, // bMaxPower
+#else
+ 50,
+#endif
#ifdef CDC_IAD_DESCRIPTOR
// interface association descriptor, USB ECN, Table 9-Z
8, // bLength
@@ -866,6 +880,108 @@
JOYSTICK_INTERVAL, // bInterval
#endif // JOYSTICK_INTERFACE
+#ifdef XINPUT_INTERFACE
+ //Interface 0
+ 9, //bLength (length of interface descriptor 9 bytes)
+ 4, //bDescriptorType (4 is interface)
+ 0, //bInterfaceNumber (This is interface 0)
+ 0, //bAlternateSetting (used to select alternate setting. notused)
+ 2, //bNumEndpoints (this interface has 2 endpoints)
+ 0xFF, //bInterfaceClass (Vendor Defined is 255)
+ 0x5D, //bInterfaceSubClass
+ 0x01, //bInterfaceProtocol
+ 0, //iInterface (Index of string descriptor for describing this notused)
+ //Some sort of common descriptor? I pulled this from Message Analyzer dumps of an actual controller
+ 17,33,0,1,1,37,129,20,0,0,0,0,19,2,8,0,0,
+ //Endpoint 1 IN
+ 7, //bLength (length of ep1in in descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x81, //bEndpointAddress (0x81 is IN1)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 4, //bInterval (polling interval in frames 4 frames)
+ //Endpoint 2 OUT
+ 7, //bLength (length of ep2out in descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x02, //bEndpointAddress (0x02 is OUT2)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 8, //bInterval (polling interval in frames 8 frames)
+ //Interface 1
+ 9, //bLength (length of interface descriptor 9 bytes)
+ 4, //bDescriptorType (4 is interface)
+ 1, //bInterfaceNumber (This is interface 1)
+ 0, //bAlternateSetting (used to select alternate setting. notused)
+ 4, //bNumEndpoints (this interface has 4 endpoints)
+ 0xFF, //bInterfaceClass (Vendor Defined is 255)
+ 0x5D, //bInterfaceSubClass (93)
+ 0x03, //bInterfaceProtocol (3)
+ 0, //iInterface (Index of string descriptor for describing this notused)
+ //A different common descriptor? I pulled this from Message Analyzer dumps of an actual controller
+ 27,33,0,1,1,1,131,64,1,4,32,22,133,0,0,0,0,0,0,22,5,0,0,0,0,0,0,
+ //Endpoint 3 IN
+ 7, //bLength (length of ep3in descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x83, //bEndpointAddress (0x83 is IN3)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 2, //bInterval (polling interval in frames 2 frames)
+ //Endpoint 4 OUT
+ 7, //bLength (length of ep4out descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x04, //bEndpointAddress (0x04 is OUT4)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 4, //bInterval (polling interval in frames 4 frames)
+ //Endpoint 5 IN
+ 7, //bLength (length of ep5in descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x85, //bEndpointAddress (0x85 is IN5)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 64, //bInterval (polling interval in frames 64 frames)
+ //Endpoint 5 OUT (shares endpoint number with previous)
+ 7, //bLength (length of ep5out descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x05, //bEndpointAddress (0x05 is OUT5)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 16, //bInterval (polling interval in frames 16 frames)
+ //Interface 2
+ 9, //bLength (length of interface descriptor 9 bytes)
+ 4, //bDescriptorType (4 is interface)
+ 2, //bInterfaceNumber (This is interface 2)
+ 0, //bAlternateSetting (used to select alternate setting. notused)
+ 1, //bNumEndpoints (this interface has 4 endpoints)
+ 0xFF, //bInterfaceClass (Vendor Defined is 255)
+ 0x5D, //bInterfaceSubClass (93)
+ 0x02, //bInterfaceProtocol (3)
+ 0, //iInterface (Index of string descriptor for describing this notused)
+ //Common Descriptor. Seems that these come after every interface description?
+ 9,33,0,1,1,34,134,7,0,
+ //Endpoint 6 IN
+ 7, //bLength (length of ep6in descriptor 7 bytes)
+ 5, //bDescriptorType (5 is endpoint)
+ 0x86, //bEndpointAddress (0x86 is IN6)
+ 0x03, //bmAttributes (0x03 is interrupt no synch, usage type data)
+ 0x20, 0x00, //wMaxPacketSize (0x0020 is 1x32 bytes)
+ 16, //bInterval (polling interval in frames 64 frames)+
+ //Interface 3
+ //This is the interface on which all the security handshaking takes place
+ //We don't use this but it could be used for man-in-the-middle stuff
+ 9, //bLength (length of interface descriptor 9 bytes)
+ 4, //bDescriptorType (4 is interface)
+ 3, //bInterfaceNumber (This is interface 3)
+ 0, //bAlternateSetting (used to select alternate setting. notused)
+ 0, //bNumEndpoints (this interface has 0 endpoints ???)
+ 0xFF, //bInterfaceClass (Vendor Defined is 255)
+ 0xFD, //bInterfaceSubClass (253)
+ 0x13, //bInterfaceProtocol (19)
+ 4, //iInterface (Computer never asks for this, but an x360 would. so include one day?)
+ //Another interface another Common Descriptor
+ 6,65,0,1,1,3
+#endif // XINPUT_INTERFACE
+
#ifdef MTP_INTERFACE
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
@@ -1214,6 +1330,20 @@
3,
{0,0,0,0,0,0,0,0,0,0}
};
+struct usb_string_descriptor_struct usb_string_xinput_security_descriptor = {
+ 0xB2, 0x03, 0x58, 0x00, 0x62, 0x00, 0x6F, 0x00, 0x78, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00,
+ 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x4D, 0x00,
+ 0x65, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x20, 0x00, 0x33, 0x00, 0x2C, 0x00,
+ 0x20, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00,
+ 0x20, 0x00, 0x31, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2C, 0x00, 0x20, 0x00, 0xA9, 0x00,
+ 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x35, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x69, 0x00,
+ 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00,
+ 0x43, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00,
+ 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x2E, 0x00, 0x20, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x6C, 0x00,
+ 0x20, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00,
+ 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x64, 0x00,
+ 0x2E, 0x00
+ };
void usb_init_serialnumber(void)
{
@@ -1273,6 +1403,9 @@
#ifdef FLIGHTSIM_INTERFACE
{0x2200, FLIGHTSIM_INTERFACE, flightsim_report_desc, sizeof(flightsim_report_desc)},
{0x2100, FLIGHTSIM_INTERFACE, config_descriptor+FLIGHTSIM_HID_DESC_OFFSET, 9},
+#endif
+#ifdef XINPUT_INTERFACE
+ {0x0304, 0x0409, (const uint8_t *)&usb_string_xinput_security_descriptor, 0},
#endif
#ifdef KEYMEDIA_INTERFACE
{0x2200, KEYMEDIA_INTERFACE, keymedia_report_desc, sizeof(keymedia_report_desc)},
diff -ruw a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.h arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.h
--- a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.h Tue Aug 9 20:48:46 2016
+++ arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_desc.h Tue Aug 9 20:36:53 2016
@@ -492,6 +492,34 @@
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY
+#elif defined(USB_XINPUT)
+ #define DEVICE_CLASS 0xFF
+ #define DEVICE_SUBCLASS 0xFF
+ #define DEVICE_PROTOCOL 0xFF
+ #define DEVICE_VERSION 0x0114
+ #define DEVICE_ATTRIBUTES 0xA0
+ #define DEVICE_POWER 0xFA
+ #define VENDOR_ID 0x045e
+ #define PRODUCT_ID 0x028e
+ #define MANUFACTURER_NAME {'©','M','i','c','r','o','s','o','f','t'}
+ #define MANUFACTURER_NAME_LEN 10
+ #define PRODUCT_NAME {'C','o','n','t','r','o','l','l','e','r'}
+ #define PRODUCT_NAME_LEN 10
+ #define EP0_SIZE 8
+ #define NUM_ENDPOINTS 6
+ #define NUM_USB_BUFFERS 24
+ #define NUM_INTERFACE 4
+ #define XINPUT_INTERFACE 0
+ #define XINPUT_RX_ENDPOINT 2
+ #define XINPUT_RX_SIZE 3
+ #define XINPUT_TX_ENDPOINT 1
+ #define XINPUT_TX_SIZE 20
+ #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
+ #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY
+ #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY
+ #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY
+ #define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_AND_RECEIVE
+ #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY
#elif defined(USB_MTPDISK)
#define VENDOR_ID 0x16C0
diff -ruw a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_inst.cpp arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_inst.cpp
--- a2/arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_inst.cpp Tue Aug 9 20:48:46 2016
+++ arduino-1.6.9/hardware/teensy/avr/cores/teensy3/usb_inst.cpp Tue Aug 9 19:54:51 2016
@@ -72,6 +72,9 @@
usb_serial_class Serial;
#endif
+#ifdef USB_XINPUT
+ usb_xinput_class XInput;
+#endif
#else // F_CPU < 20 MHz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment