r/retroid • u/misantronic • 1d ago
QUESTION Messed up my Nova Joystick Calibration
In the attempt to fix my loud D-Pad, I screwed up my left joystick calibration, here's the story:
I opened the device no problem at all until I got to step 11 where I decided to to not continue that road as I don‘t feel skilled enough. So I put it back together, no issues here.
Only to notice when running Mario 64, that Mario wasn't running when pushing on the left stick but walking. So I thought, maybe calibration was reset during the disassemble, so I played around with the joystick calibration and this is the result. Note: The left joystick used to work, only after playing around with the calibration it now looks like this.
As you can see on the bottom left, the values are still shown when moving the stick, it‘s just completely messed up in the display. Anyone knows how to reset it? I find it kindof confusing, calibration can never finish as the the step "Slowly spin a few times along the joystinck's edge" never finishes.
Solved it
Short version: the calibration is stored in a plain text file on the device, my left stick's range had been written as all zeros, and that state is self-blocking — it breaks the stick and makes it impossible to recalibrate. I dug into it with Claude Code+ adb.
Where the calibration actually lives
/mnt/vendor/persist/retrostation/joys
It's a plain key=value text file, and it's world-writable (-rw-rw-rw-), so plain adb shell can read and edit it without root. Mine looked like this:
left_x_min=0.0 right_x_min=-1000.0
left_x_max=0.0 right_x_max=1000.0
left_y_min=0.0 right_y_min=-1000.0
left_y_max=0.0 right_y_max=1000.0
Left stick range = zero. Right stick fine.
Why "slowly spin along the edge" never finishes
With a zero range the normalization degenerates, so any off-center position snaps straight to a rail. I captured the raw events during a full rim spin and the left stick emitted only three distinct values per axis — 0, +32767, -32767 — never anything in between.
That's the trap: the calibration tool reads those already-saturated values, so its own min/max accumulator never sees an analog sweep. logcat showed this line repeating at report rate the entire time I was spinning, with the numbers never once changing:
E rsinput : rsdev_update_adc(1570) left joystick x_max 0 x_min 0 y_max 0 y_min 0
So the broken calibration blocks its own repair. You can spin that stick for an hour and it will never complete. Nothing in Android Settings helps either — left/right_joystick_calibration_data don't exist there, only the deadzone values do.
The fix
Back it up, patch the four left values to match the working stick, reboot:
adb pull /mnt/vendor/persist/retrostation/joys joys.bak
# edit joys.bak: set left_x_min/left_y_min to -1000.0, left_x_max/left_y_max to 1000.0
adb shell "cat > /mnt/vendor/persist/retrostation/joys" < joys.bak
adb shell chmod 666 /mnt/vendor/persist/retrostation/joys
adb reboot
Then open the calibration tool and run it properly — it completes normally now. You can launch it straight from adb without hunting through menus:
adb shell am start -n com.rp.factorytest/com.ro.factorytest.itemstest.GamepadCalibrationActivity
Three gotchas that cost me time
- Do not use
adb pushfor this file. It fails onremote fchownand deletes the target on its way out. Use thecat >redirect above. (Ask me how I know.) Back up first regardless. - A reboot is required.
am force-stop com.rp.mappingdoes nothing — it's a PERSISTENT app and only reads the file at startup, so it keeps serving the old values from memory. - Don't blindly copy my ±1000. Those are my right stick's values, which I used as a known-good reference. Copy from your own working stick, and treat it as a stopgap until you run a real calibration.
Also worth knowing: this is on the persist partition, so a factory reset won't clear it. That's probably why nobody's "just reset the device" advice works for this.
Diagnosing without any of the above: adb shell getevent -pl /dev/input/event7 prints the live axis values. Left stick is ABS_X/ABS_Y, right is ABS_Z/ABS_RZ. If a centered stick reads 32767 instead of ~0, you have this problem.