Correct 04000000 finding: CheckRequest self-test leftover, not test mode
Bench refutation (display is static under axis movement; version-only exchanges leave it alone) kills the A-9-E chord theory. Real mechanism: the CheckRequest handler at $C5A6 runs a full self-test — sets the test-display flag $2421, brackets itself with TestModeChange 0x8C, lamp pattern, pod scan, five-channel encoder sweep — and returns without repainting, leaving the channel-4 frame (04000000) as a stale cosmetic snapshot. Board fully healthy; no reset needed. PROTOCOL.md now warns hosts that 0x8C fires around every check. Candidate firmware fix (repaint cave off $C5E4) noted for a future burn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,14 @@ from [`g_baRIOLengthsA`](../legacy/riovjoy2.cpp#L171).
|
|||||||
| 0x8B | KeyReleased | RIO→PC | 2 | `pad`, `index` |
|
| 0x8B | KeyReleased | RIO→PC | 2 | `pad`, `index` |
|
||||||
| 0x8C | TestModeChange | RIO→PC | 1 | `mode` (0 = exit) |
|
| 0x8C | TestModeChange | RIO→PC | 1 | `mode` (0 = exit) |
|
||||||
|
|
||||||
|
> **TestModeChange fires on every CheckRequest too** (firmware v4.2,
|
||||||
|
> handler `$C5A6`): the board's check self-test brackets itself with
|
||||||
|
> `0x8C` mode≠0 / mode=0, flashes the lamps, and leaves a stale
|
||||||
|
> `04000000` frame on the 8-digit diagnostic display (cosmetic; see
|
||||||
|
> [hardware/display-board-1408.md](hardware/display-board-1408.md)).
|
||||||
|
> Hosts should treat `0x8C` around a check as routine, not as the
|
||||||
|
> operator entering keypad test mode.
|
||||||
|
|
||||||
### Reset targets (ResetRequest payload)
|
### Reset targets (ResetRequest payload)
|
||||||
|
|
||||||
`0` = general/all, `1` = throttle, `2` = left pedal, `3` = right pedal,
|
`0` = general/all, `1` = throttle, `2` = left pedal, `3` = right pedal,
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ J1 (14-pin, from the RIO's EXTERNAL DISPLAY port) is all input:
|
|||||||
## What the RIO firmware displays (v4.2)
|
## What the RIO firmware displays (v4.2)
|
||||||
|
|
||||||
All display writes go through `$CB49` (buffer render) or five canned
|
All display writes go through `$CB49` (buffer render) or five canned
|
||||||
patterns at `$CB7C–$CC52`, driven from three contexts: initialization,
|
patterns at `$CB7C–$CC52`, driven from four contexts: initialization,
|
||||||
the built-in **test mode**, and the **serial error/crash displays**
|
the built-in **test mode**, the **serial error/crash displays**, and
|
||||||
(below). During normal, healthy gameplay the display is static.
|
the **CheckRequest self-test** (all below). During normal, healthy
|
||||||
|
gameplay the display is static.
|
||||||
|
|
||||||
**Normal operation:** `F0000000` — written at cold boot (`$C068`) and warm
|
**Normal operation:** `F0000000` — written at cold boot (`$C068`) and warm
|
||||||
re-init (`$C64B`), then left alone.
|
re-init (`$C64B`), then left alone.
|
||||||
@@ -92,6 +93,20 @@ In the axis tests `hhll` is the **live 16-bit quadrature count in hex**
|
|||||||
and watch the number move. The channel IDs are literally the keypad keys
|
and watch the number move. The channel IDs are literally the keypad keys
|
||||||
that start them, which is why the fourth axis reads `0C`.
|
that start them, which is why the fourth axis reads `0C`.
|
||||||
|
|
||||||
|
## The CheckRequest self-test leftover: `04000000`
|
||||||
|
|
||||||
|
The host `CheckRequest` (`0x80`) triggers a full self-test in the
|
||||||
|
handler at `$C5A6`: it sets the same display flag test mode uses
|
||||||
|
(`$2421`), brackets itself with `TestModeChange 0x8C` notifications,
|
||||||
|
flashes a lamp pattern, scans the pods, and sweeps the five encoder
|
||||||
|
channels — rendering each channel's `cc00hhll` frame as it goes. It
|
||||||
|
clears the flag on exit but **never repaints the display**, so after
|
||||||
|
every status check the digits are left showing the last frame:
|
||||||
|
channel 4, usually `04000000` with idle encoders. It is a stale
|
||||||
|
snapshot (axis movement does not update it — bench-confirmed
|
||||||
|
2026-07-19), purely cosmetic, and the board keeps operating normally.
|
||||||
|
Any reset repaints `F0000000`.
|
||||||
|
|
||||||
## Error displays (the third use)
|
## Error displays (the third use)
|
||||||
|
|
||||||
Two more display writers live in the serial machinery — the display is
|
Two more display writers live in the serial machinery — the display is
|
||||||
|
|||||||
@@ -498,13 +498,25 @@ sub-threshold teardowns — stock paints `E0…` at the first — and flipped
|
|||||||
exactly at the 5th teardown to **`E0000105`** (`$3187`=00 overflows,
|
exactly at the 5th teardown to **`E0000105`** (`$3187`=00 overflows,
|
||||||
`$3184`=01 give-up, `$3185`=05 teardowns), confirmed by eye on the
|
`$3184`=01 give-up, `$3185`=05 teardowns), confirmed by eye on the
|
||||||
cockpit display. Mash regression (120s, lamps on,
|
cockpit display. Mash regression (120s, lamps on,
|
||||||
`testlogs/riomash-patched-e0t5-9600-20260719-154259.log`): **PASS** —
|
`testlogs/riomash-patched-e0t5-9600-20260719-154259.log`): **PASS** �
|
||||||
0 wedges, 236/236 presses, 88.0% analog fill, NAK 0, board counters
|
0 wedges, 236/236 presses, 88.0% analog fill, NAK 0, board counters
|
||||||
flat. Incidental live finding: mid-mash the cockpit keypad delivered
|
flat. The 31250v2_e0t5 image is the same patch on the certified
|
||||||
the A-9-E test-mode chord plus a `4`, dropping the board into axis
|
FastRIO base and is expected to behave identically.
|
||||||
test 4 (display `04000000`) — button scanning stops in test mode
|
|
||||||
(mainline parks in the test loop) while the ISR-driven serial protocol
|
**Post-run display `04000000` — the CheckRequest self-test (corrected
|
||||||
keeps answering polls. Field-validates the display doc's test-mode map;
|
finding).** The first read of this (keypad A-9-E chord entering test
|
||||||
exit is keypad `F` then `D`. The 31250v2_e0t5 image
|
mode) was wrong — disproved on the bench: the display is static (axis
|
||||||
is the same patch on the certified FastRIO base and is expected to
|
movement does not change it) and version-only exchanges leave it alone.
|
||||||
behave identically.
|
The real mechanism is the **CheckRequest (`0x80`) handler at `$C5A6`**:
|
||||||
|
a full built-in self-test that sets the test-display flag `$2421`
|
||||||
|
(`$C5B1`), sends `TestModeChange 0x8C` to the host (`$C70E`), runs a
|
||||||
|
lamp pattern (`$D34A`), scans the pods, sweeps all five encoder
|
||||||
|
channels (`$CC53`, ending on channel 4 — whose `cc00hhll` frame is the
|
||||||
|
last thing rendered), enqueues the fault reports, clears the flag
|
||||||
|
(`$C5E1`), notifies `0x8C` again — and **returns without repainting the
|
||||||
|
display**. Every status check therefore leaves a stale
|
||||||
|
`04 00 <ch4 count>` snapshot (idle: `04000000`) on the digits. The
|
||||||
|
board is fully healthy afterwards; no reset is needed. Proper fix, if
|
||||||
|
the cosmetic bothers: a ~10-byte cave off `$C5E4` that repaints `F0`
|
||||||
|
(`JSR $CB7C`) and re-renders the E0 readout when over threshold
|
||||||
|
(`JSR $D5F2`) — candidate for the next burn, not yet built.
|
||||||
|
|||||||
Reference in New Issue
Block a user