From 57cda79320563f4c8890fd71e99fdfb7091d5966 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 21 Jun 2020 08:49:14 -0700 Subject: [PATCH] Add specifications for Saitek X52 [skip ci] --- docs/specs/x52_controller_map.md | 110 +++++++++++++++++++++++++++++++ docs/specs/x52_hid_report.txt | 60 +++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 docs/specs/x52_controller_map.md create mode 100644 docs/specs/x52_hid_report.txt diff --git a/docs/specs/x52_controller_map.md b/docs/specs/x52_controller_map.md new file mode 100644 index 0000000..6a7edcd --- /dev/null +++ b/docs/specs/x52_controller_map.md @@ -0,0 +1,110 @@ +Saitek X52 Controller Map +========================= + +This page documents the HID Report format and how to decode the report to map +to axis/buttons for the Saitek X52. + +> **Note:** I am not sure that the button indices match with real hardware. The +> indices are guessed by comparing the Test screen printed in the manuals for +> both the X52 and X52 Pro, and my own +> [documentation](x52pro_controller_map.md). I also looked at the [source code +> of this project](https://github.com/xythobuz/Saitek-X52-PPM) to figure out +> possible mappings. Given that the above project only uses PID 0x0255, it is +> entirely possible that the report format for the X52 with PID 0x075c is +> different. + +Axis +==== +* 0 - X axis +* 1 - Y axis +* 2 - Twist axis +* 3 - Throttle axis +* 4 - Clutch button rotary (rotary X) +* 5 - E button rotary (rotary Y) +* 6 - Slider + +Buttons +======= +* 0 - Trigger primary +* 1 - FIRE/LAUNCH +* 2 - A +* 3 - B +* 4 - C +* 5 - SHIFT +* 6 - D +* 7 - E +* 8 - T1 Up +* 9 - T1 Down +* 10 - T2 Up +* 11 - T2 Down +* 12 - T3 Up +* 13 - T3 Down +* 14 - Trigger secondary +* 15 - Stick 4-way N +* 16 - Stick 4-way E +* 17 - Stick 4-way S +* 18 - Stick 4-way W +* 19 - Throttle 4-way N (pull up) +* 20 - Throttle 4-way E +* 21 - Throttle 4-way S (push down) +* 22 - Throttle 4-way W +* 23 - MODE 1 +* 24 - MODE 2 +* 25 - MODE 3 +* 26 - FUNCTION +* 27 - START/STOP/Down +* 28 - RESET/Up +* 29 - CLUTCH (i) +* 30 - Mouse button - primary +* 31 - Mouse button - secondary +* 32 - Mouse wheel down +* 33 - Mouse wheel up + +The function button toggles between the clock and stopwatch on +the MFD. If in stopwatch mode, the start/stop button starts or +stops the stopwatch. If already stopped, the start/stop button +will restart the stopwatch. The reset button will stop the +stopwatch, if running, and also reset the display to 00:00. + +If the MFD is in clock mode, then the start/stop button cycles +backwards through the three on-board clock displays, while the +reset button cycles forward through the displays. + +If the primary clock has not been set using the vendor API, +then the MFD will not display anything in clock mode. The +start/stop and reset buttons will also not change anything +on the display. Stopwatch mode is not affected by this. + +Refer to the vendor API documentation for details on how to +configure the MFD display. + +USB Report Format +================= +The X52 reports 14 bytes of data everytime a joystick event occurs. + +The 15 bytes are laid out in little endian format as shown below: + +* 11-bits of X axis position +* 11-bits of Y axis position +* 10-bits of twist axis position +* 8 bits of throttle position +* 8 bits of rotary X position +* 8 bits of rotary Y position +* 8 bits of slider position +* 34 bits of button information +* 1 bits of padding +* 4 bits of hat position +* 4 bits of thumbstick X position +* 4 bits of thumbstick Y position + +A report would look like the following: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | X axis data | Y axis data | Rz axis data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Throttle | Rx axis data | Ry axis data | Slider data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Buttons 7-0 | Buttons 15-8 | Buttons 23-16 | Buttons 31-24 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Hat |///|Btn| MouseX| MouseY| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/docs/specs/x52_hid_report.txt b/docs/specs/x52_hid_report.txt new file mode 100644 index 0000000..d6f6bda --- /dev/null +++ b/docs/specs/x52_hid_report.txt @@ -0,0 +1,60 @@ +0x05, 0x01, // Usage Page (Generic Desktop Ctrls) +0x09, 0x04, // Usage (Joystick) +0xA1, 0x01, // Collection (Application) +0x09, 0x01, // Usage (Pointer) +0xA1, 0x00, // Collection (Physical) +0x09, 0x30, // Usage (X) +0x09, 0x31, // Usage (Y) +0x15, 0x00, // Logical Minimum (0) +0x26, 0xFF, 0x07, // Logical Maximum (2047) +0x75, 0x0B, // Report Size (11) +0x95, 0x02, // Report Count (2) +0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x09, 0x35, // Usage (Rz) +0x15, 0x00, // Logical Minimum (0) +0x26, 0xFF, 0x03, // Logical Maximum (1023) +0x75, 0x0A, // Report Size (10) +0x95, 0x01, // Report Count (1) +0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x09, 0x32, // Usage (Z) +0x09, 0x33, // Usage (Rx) +0x09, 0x34, // Usage (Ry) +0x09, 0x36, // Usage (Slider) +0x15, 0x00, // Logical Minimum (0) +0x26, 0xFF, 0x00, // Logical Maximum (255) +0x75, 0x08, // Report Size (8) +0x95, 0x04, // Report Count (4) +0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x05, 0x09, // Usage Page (Button) +0x19, 0x01, // Usage Minimum (0x01) +0x29, 0x22, // Usage Maximum (0x22) +0x15, 0x00, // Logical Minimum (0) +0x25, 0x01, // Logical Maximum (1) +0x95, 0x22, // Report Count (34) +0x75, 0x01, // Report Size (1) +0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x75, 0x02, // Report Size (2) +0x95, 0x01, // Report Count (1) +0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x05, 0x01, // Usage Page (Generic Desktop Ctrls) +0x09, 0x39, // Usage (Hat switch) +0x15, 0x01, // Logical Minimum (1) +0x25, 0x08, // Logical Maximum (8) +0x35, 0x00, // Physical Minimum (0) +0x46, 0x3B, 0x01, // Physical Maximum (315) +0x66, 0x14, 0x00, // Unit (System: English Rotation, Length: Centimeter) +0x75, 0x04, // Report Size (4) +0x95, 0x01, // Report Count (1) +0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) +0x05, 0x05, // Usage Page (Game Ctrls) +0x09, 0x24, // Usage (Move Right/Left) +0x09, 0x26, // Usage (Move Up/Down) +0x15, 0x00, // Logical Minimum (0) +0x25, 0x0F, // Logical Maximum (15) +0x75, 0x04, // Report Size (4) +0x95, 0x02, // Report Count (2) +0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) +0xC0, // End Collection +0xC0, // End Collection + +// 119 bytes