Преглед изворни кода

Restore Switch Pro gyro after Steam use (#249)

Co-authored-by: j <j@jtml.net>
jmt-gh пре 1 месец
родитељ
комит
ac7a2ac33c
4 измењених фајлова са 35 додато и 2 уклоњено
  1. 13 1
      OpenPuck/haptics.cpp
  2. 2 0
      OpenPuck/steam_commands.h
  3. 3 1
      docs/PROTOCOL.md
  4. 17 0
      docs/TESTING_GUIDE.md

+ 13 - 1
OpenPuck/haptics.cpp

@@ -588,7 +588,6 @@ void hapticReinit(uint8_t slot)
 
 	// clang-format off
 	static const uint8_t haptic_reset_data_1[] = { 
-			SETTING_IMU_MODE, 0x00, 0x00, 
 			SETTING_LEFT_TRACKPAD_MODE, 0x07, 0x00, 
 			SETTING_RIGHT_TRACKPAD_MODE, 0x07, 0x00, 
 			SETTING_WIRELESS_PACKET_VERSION, 0x02, 0x00, 
@@ -665,6 +664,19 @@ void hapticOnReconnect(int slot)
 	g_rumble80Ms[slot] = 0;
 	// Scrub haptics queued before the link came up (stale across the reconnect) -- this slot only.
 	hapticCancelPendingOn(slot);
+	if (g_usbMode == MODE_SW_PRO) {
+		static const uint8_t RAW_IMU[] = {
+			SETTING_IMU_MODE,
+			SETTING_GYRO_MODE_SEND_RAW_ACCEL |
+				SETTING_GYRO_MODE_SEND_RAW_GYRO,
+			0x00
+		};
+
+		// Steam can leave the controller's persisted IMU mode off. Switch
+		// Pro reports require the raw RF samples that setting suppresses.
+		relayEnqueue(IBEX_CMD_SET_SETTINGS_VALUES, RAW_IMU,
+			     sizeof RAW_IMU, false, (uint8_t)slot);
+	}
 	// NO automatic haptic re-init. hapticReinit lands 0x81 (CLEAR DIGITAL MAPPINGS -- rid < 0x87 so it
 	// EXECUTES even on legacy framing). 0x81 is NON-IDEMPOTENT (ibex FUN_0001f554): EVERY call re-runs the
 	// lizard-disable event + func_0x0001bbf0 (a hardware peripheral re-arm unique to the 0x81 path) -- so

+ 2 - 0
OpenPuck/steam_commands.h

@@ -80,6 +80,8 @@
 #define SETTING_LED_USER_BRIGHTNESS 45 // 0x2d
 #define SETTING_ENABLE_RAW_JOYSTICK 46 // 0x2e
 #define SETTING_IMU_MODE 48 // 0x30
+#define SETTING_GYRO_MODE_SEND_RAW_ACCEL 0x0008
+#define SETTING_GYRO_MODE_SEND_RAW_GYRO 0x0010
 #define SETTING_WIRELESS_PACKET_VERSION 49 // 0x31
 #define SETTING_LEFT_TRACKPAD_CLICK_PRESSURE 52 // 0x34
 #define SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE 53 // 0x35

+ 3 - 1
docs/PROTOCOL.md

@@ -333,7 +333,9 @@ does a `detach -> rebuild -> attach` so the host re-reads the descriptor cleanly
   **connected slot only** (the slot gate is what stops a haptic aimed at another of the four exposed
   slots from buzzing the single controller). The 63-byte settings/config reports `0x87`/`0x88`/`0x89`
   are not haptics and are not pushed on this path (`0x87` lizard-off reaches the controller via the
-  feature `0x01` passthrough). Restricting this to `0x82` alone silently dropped the ping/grip/test
+  feature `0x01` passthrough). Steam owns `IMU_MODE` in native puck mode. Switch Pro mode instead writes
+  raw accelerometer + gyroscope (`0x18`) when the RF link comes up because the controller retains Steam's
+  IMU-off state across pucks. Restricting haptics to `0x82` alone silently dropped the ping/grip/test
   haptics, which use other report IDs.
 
 #### ⚠️ Two different `0x8x` id spaces — never share a rule between them

+ 17 - 0
docs/TESTING_GUIDE.md

@@ -16,6 +16,23 @@
 - Is battery level shown and correct?
 - Is the polling rate and response rate the same? Is it around 250hz?
 
+### Testing Steam settings relay and Switch Pro gyro
+
+This test catches controller-side IMU state changes that survive an ordinary
+firmware downgrade:
+
+1. Factory-erase the puck, pair the controller, and let Steam finish its normal
+   controller configuration.
+2. Switch directly to Switch Pro mode without calibrating motion controls.
+3. Confirm that all three gyro axes respond, then power-cycle the controller and
+   confirm them again.
+
+Steam's `0x87 SET_SETTINGS` blocks can contain setting `0x30` (`IMU_MODE`). In
+Steam mode the puck must relay every complete settings tuple, including IMU
+mode. Switch Pro mode must write `0x18` (raw accelerometer + raw gyroscope) when
+the controller connects; otherwise Steam's retained IMU-off state suppresses
+the RF motion samples used for Switch motion reports.
+
 ### Testing the DirectInput mode (mode 11)
 
 Windows has a built-in DirectInput tester: run `joy.cpl` (or Settings → Bluetooth & devices → Devices → More