fix(firmware): zero SPI IMU calibration origins to prevent phantom rotation

The Switch applies its stored SPI calibration when interpreting IMU data:
  gyro_dps = (raw - spi_origin) * 936 / coeff

The firmware had real hardware offsets as calibration origins:
  gyro_origin = (9, -22, -95)  accel_origin = (-29, -199, 493)

A real Pro Controller sensor reads those values at rest, so the Switch
subtracts them to get zero. But our bridge already removes hardware bias
via gyro bias calibration and sends near-zero counts when still.

The Switch was then applying a second origin correction:
  gyro_z=2 → (2 - (-95)) * 0.070 = 6.79 dps constant yaw rotation

This caused the character to spin horizontally even when holding the
controller perfectly still.

Fix: zero all calibration origins. The bridge handles bias correction;
the Switch must not apply a second offset on top.
This commit is contained in:
Joey Yakimowich-Payne 2026-03-16 17:22:52 -06:00
commit 30e22c210c
No known key found for this signature in database
GPG key ID: DDF6AF5B21B407D4

View file

@ -97,10 +97,18 @@ static const uint8_t factory_config_data[0xEFF] = {
0xFF, 0xFF, 0xFF, 0xFF,
// config & calibration 1
0xE3, 0xFF, 0x39, 0xFF, 0xED, 0x01, 0x00, 0x40,
0x00, 0x40, 0x00, 0x40, 0x09, 0x00, 0xEA, 0xFF,
0xA1, 0xFF, 0x3B, 0x34, 0x3B, 0x34, 0x3B, 0x34,
// config & calibration 1 (6-axis IMU, SPI 0x6020-0x6037)
// Accel origin (0,0,0): bridge pre-corrects for bias, so Switch must not
// apply a second origin offset. Real controllers have hardware DC offsets
// here, but our emulated sensor sends bias-corrected values.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Accel sensitivity coeff: 0x4000 = 16384 → 4096 LSB/G (matches bridge)
0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
// Gyro origin (0,0,0): bridge removes hardware bias before sending.
// Original values (9, -22, -95) caused phantom 6.7 dps yaw when still.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Gyro sensitivity coeff: 0x343B = 13371 → 818.5 LSB/rad_s (matches bridge)
0x3B, 0x34, 0x3B, 0x34, 0x3B, 0x34,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,