From 38defb52466318d40ea31490ef00e38bf7333585 Mon Sep 17 00:00:00 2001 From: Cyd Date: Sun, 19 Jul 2026 14:19:30 -0500 Subject: [PATCH] FastRIO certified: 31250v2 final runs clean; config plumbing for baud/poll Operator-verified zero lamp misses/hangs through the slow-chord test (62500's killer) and 392/min mash. Final run: NAK=0, 25 timeout resends silently healing inbound response loss, counters flat, zero wedges. --poll 20 delivered ~31Hz analog (1.7x legacy); the shortfall vs 50Hz is additive host pacing (delay after awaited exchange), not board saturation - noted as a future host tweak. AppConfig gains RioBaudRate (default 9600) + AnalogPollMs (default 55), plumbed through RioCoordinator; existing configs unchanged. Production matrix recorded in ANALYSIS.md: 9600 patched chip for native-game cabinets, 31250v2 + poll 20-25 + FTDI for RIOJoy cockpits. Co-Authored-By: Claude Fable 5 --- rio-firmware/RIOv4_2-ANALYSIS.md | 31 +++++++++++++++++++ .../riomash-31250v2-final-20260719-141437.log | 28 +++++++++++++++++ ...riomash-31250v2-poll20-20260719-141620.log | 28 +++++++++++++++++ src/RioJoy.Core/Profiles/AppConfig.cs | 15 +++++++++ src/RioJoy.Tray/RioCoordinator.cs | 9 ++++-- 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 rio-firmware/testlogs/riomash-31250v2-final-20260719-141437.log create mode 100644 rio-firmware/testlogs/riomash-31250v2-poll20-20260719-141620.log diff --git a/rio-firmware/RIOv4_2-ANALYSIS.md b/rio-firmware/RIOv4_2-ANALYSIS.md index 5be3689..e10c62c 100644 --- a/rio-firmware/RIOv4_2-ANALYSIS.md +++ b/rio-firmware/RIOv4_2-ANALYSIS.md @@ -374,3 +374,34 @@ The stop-and-wait + typed-resolution machinery stays enabled at every rate as delivery insurance (it hardens 9600 production cabinets against ordinary electrical noise, and its retries are near-zero on clean links). 62500 images remain in the repo for future firmware work. + +## FINAL CERTIFICATION (2026-07-19) — 31250 v2 ships + +Operator-verified at 31250 v2 with stop-and-wait active: **zero lamp +misses/hangs** through the slow-chord test (the exact scenario that +condemned 62500) and a 392-presses/min mash. + +`testlogs/riomash-31250v2-final`: analog 89.0% (structural), **NAK = 0**, +25 resends — all timeout-triggered, i.e. the retry machinery silently +healing occasional INBOUND response loss (29 host-side framing events), +which is exactly the insurance it exists to provide. Counters flat, +zero wedges, gaps <100ms except run-start/stop artifacts. + +`testlogs/riomash-31250v2-poll20` (--poll 20): delivered ~31 Hz analog +(2036 replies/65s) vs the legacy 18 Hz — 1.7×. The 62.6%-of-slots figure +is a host artifact, not board saturation: the poll loop delays AFTER each +awaited exchange (~6-9 ms), so the real cadence is interval+exchange. +Absolute-schedule pacing would approach 40+ Hz; ~94% of actually-issued +polls were answered. Future host tweak, not firmware. + +### Production configuration +| deployment | chip | config.json | +|---|---|---| +| native-game cabinets | `RIOv4_2_patched.bin` (9600) | defaults (RioBaudRate 9600, AnalogPollMs 55) | +| RIOJoy-only cockpits (FastRIO) | `RIOv4_2_patched_31250v2.bin` | RioBaudRate 31250, AnalogPollMs 20-25, FTDI-class adapter | + +AppConfig.RioBaudRate + AnalogPollMs are plumbed through RioCoordinator; +stop-and-wait delivery is always on (near-zero cost on clean links). +Firmware images, hashes, disassemblies, the mechanized mash harness, and +all eleven bench logs live in this directory. The original AMD chip is +retired, preserved unmodified. diff --git a/rio-firmware/testlogs/riomash-31250v2-final-20260719-141437.log b/rio-firmware/testlogs/riomash-31250v2-final-20260719-141437.log new file mode 100644 index 0000000..cdbe5b4 --- /dev/null +++ b/rio-firmware/testlogs/riomash-31250v2-final-20260719-141437.log @@ -0,0 +1,28 @@ +== RIO mash test :: COM1 @ 31250 8N1, 300s, chip label '31250v2-final' == + lamp echo ON (drives reply/lamp collisions), wedge threshold 2.0s, poll 55ms, app auto-recovery DISABLED + log: C:\VWE\riojoy\riomash-31250v2-final-20260719-141437.log + firmware: 4.2 + counters before: RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] + +>>> MASH NOW: two hands, 8 lamp buttons, as fast as you can. <<< +>>> Test runs 300s. A wedge alarm will beep + banner. <<< +>>> Ctrl+C ends the run early and still prints the summary. <<< + +[ 31.83s] progress: presses=157 (157/min) analog=500 maxGap=0.28s wedges=0 +[ 61.84s] progress: presses=432 (419/min) analog=976 maxGap=0.28s wedges=0 +[ 65.45s] operator stop (Ctrl+C) — ending run, snapshotting counters... + +== MASH SUMMARY [31250v2-final] == +run : 65s on COM1, lamps on, wedge threshold 2.0s +firmware : 4.2 +presses/releases : 436 / 436 (392 presses/min) +analog replies : 1051 (~1181 poll slots; 89.0%), sentinels 0 +framing / NAK : 29 / 0 (command resends NAK/timeout: 25) +gap histogram : <100ms:1048 100-250ms:0 250-500ms:2 0.5-1s:0 1-2s:0 2-5s:0 >5s:0 +longest gaps : 0.33s@65.4s, 0.28s@0.6s, 0.09s@45.0s, 0.08s@19.8s, 0.08s@22.4s, 0.08s@41.7s, 0.08s@24.5s, 0.08s@8.5s, 0.08s@37.5s, 0.08s@14.6s +wedge events : 0 +counters before : RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] +counters after : RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] +counter delta : RestartCount=+0 AbandonCount=+0 FullBufferCount=+0 +verdict : PASS — no wedge; compare gap histogram + counter delta to baseline +log file : C:\VWE\riojoy\riomash-31250v2-final-20260719-141437.log diff --git a/rio-firmware/testlogs/riomash-31250v2-poll20-20260719-141620.log b/rio-firmware/testlogs/riomash-31250v2-poll20-20260719-141620.log new file mode 100644 index 0000000..deb7c3f --- /dev/null +++ b/rio-firmware/testlogs/riomash-31250v2-poll20-20260719-141620.log @@ -0,0 +1,28 @@ +== RIO mash test :: COM1 @ 31250 8N1, 120s, chip label '31250v2-poll20' == + lamp echo ON (drives reply/lamp collisions), wedge threshold 2.0s, poll 20ms, app auto-recovery DISABLED + log: C:\VWE\riojoy\riomash-31250v2-poll20-20260719-141620.log + firmware: 4.2 + counters before: RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] + +>>> MASH NOW: two hands, 8 lamp buttons, as fast as you can. <<< +>>> Test runs 120s. A wedge alarm will beep + banner. <<< +>>> Ctrl+C ends the run early and still prints the summary. <<< + +[ 31.97s] progress: presses=63 (63/min) analog=986 maxGap=0.51s wedges=0 +[ 62.02s] progress: presses=314 (304/min) analog=1890 maxGap=0.51s wedges=0 +[ 65.66s] operator stop (Ctrl+C) — ending run, snapshotting counters... + +== MASH SUMMARY [31250v2-poll20] == +run : 65s on COM1, lamps on, wedge threshold 2.0s +firmware : 4.2 +presses/releases : 318 / 318 (285 presses/min) +analog replies : 2036 (~3250 poll slots; 62.6%), sentinels 0 +framing / NAK : 73 / 0 (command resends NAK/timeout: 57) +gap histogram : <100ms:2032 100-250ms:1 250-500ms:1 0.5-1s:1 1-2s:0 2-5s:0 >5s:0 +longest gaps : 0.51s@0.7s, 0.29s@65.7s, 0.13s@50.6s, 0.08s@55.1s, 0.07s@50.9s, 0.07s@50.7s, 0.07s@50.8s, 0.07s@54.3s, 0.06s@48.5s, 0.06s@57.9s +wedge events : 0 +counters before : RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] +counters after : RestartCount=0 AbandonCount=0 FullBufferCount=0 [board/lamp faults reported!] +counter delta : RestartCount=+0 AbandonCount=+0 FullBufferCount=+0 +verdict : PASS — no wedge; compare gap histogram + counter delta to baseline +log file : C:\VWE\riojoy\riomash-31250v2-poll20-20260719-141620.log diff --git a/src/RioJoy.Core/Profiles/AppConfig.cs b/src/RioJoy.Core/Profiles/AppConfig.cs index 7ba2c72..def5af0 100644 --- a/src/RioJoy.Core/Profiles/AppConfig.cs +++ b/src/RioJoy.Core/Profiles/AppConfig.cs @@ -10,6 +10,21 @@ public sealed class AppConfig /// Default RIO COM port when a profile doesn't specify one. public string DefaultRioComPort { get; set; } = "COM1"; + /// + /// RIO link baud rate. 9600 = stock/wedge-patched firmware (native-game + /// compatible). 31250 = the validated FastRIO chip + /// (rio-firmware/RIOv4_2_patched_31250v2.bin) — needs an FTDI-class + /// adapter; classic 16550 UARTs cannot make this rate. + /// + public int RioBaudRate { get; set; } = 9600; + + /// + /// Analog poll interval in milliseconds (legacy cadence 55 → ~18 Hz). + /// The FastRIO chip sustains ~20-25 ms (~30+ Hz effective; bench + /// 2026-07-19). Leave at 55 for stock-speed boards. + /// + public int AnalogPollMs { get; set; } = 55; + /// Default plasma COM port when a profile doesn't specify one. public string? DefaultPlasmaComPort { get; set; } = "COM2"; diff --git a/src/RioJoy.Tray/RioCoordinator.cs b/src/RioJoy.Tray/RioCoordinator.cs index f005f57..9d4eedd 100644 --- a/src/RioJoy.Tray/RioCoordinator.cs +++ b/src/RioJoy.Tray/RioCoordinator.cs @@ -47,7 +47,8 @@ public sealed class RioCoordinator : IDisposable public RioCoordinator(Func config, Func? transportFactory = null) { _config = config ?? throw new ArgumentNullException(nameof(config)); - _transportFactory = transportFactory ?? (port => new SerialPortTransport(port)); + _transportFactory = transportFactory + ?? (port => new SerialPortTransport(port, _config().RioBaudRate)); } /// Raised (with a short status string) whenever the active state changes. @@ -211,7 +212,11 @@ public sealed class RioCoordinator : IDisposable } _transport = _transportFactory(port); - _link = new RioSerialLink(_transport); + _link = new RioSerialLink(_transport, new RioSerialLinkOptions + { + AnalogPollInterval = TimeSpan.FromMilliseconds( + Math.Max(10, config.AnalogPollMs)), // floor guards a typo'd config + }); _runtime = new RioRuntime( _link, profile.ToInputMap(),