31250 bench run: wedge patch holds under retry storm; window is byte-scaled
127s mash at 31250: zero wedges — but 5655 framing resyncs, duplicate replies (215% of poll slots) and AbandonCount=65 reveal the board's reply ACK-wait scales with byte time: ~5+ms at 9600 (USB beats it, zero framing) vs ~1.6ms at 31250 (USB cannot). All 65 retry exhaustions self-recovered through the patched give-up path — the strongest field proof of the latch fix yet; unpatched firmware would have wedged on the first. Verdict recorded in ANALYSIS.md: cabinets run the 9600 patched chip; 31250 stays a bench branch until the retry window is widened in firmware. Tool: before-snapshot now retries once (can lose the post-DTR boot race, as this run showed); evidence log archived. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -240,3 +240,27 @@ heavier mash is decisive. Remaining (cabinet): overnight idle soak +
|
||||
a native-game session. Both check snapshots also reported a board/lamp
|
||||
fault item — persistent across chips, likely a real tired lamp; inspect
|
||||
separately.
|
||||
|
||||
## 31250-baud bench run (2026-07-18) — patch holds; retry window is byte-scaled
|
||||
|
||||
`testlogs/riomash-patched-31250-20260718-003114.log` (127s mash, FTDI
|
||||
COM1 @ 31250, latency timer already 1ms): **zero wedges**, but
|
||||
framing=5655, analog replies at 215% of poll slots (duplicates), and
|
||||
AbandonCount=65 — a reply-retry storm. Reading: the board's reply
|
||||
ACK-wait window scales with BYTE TIME, not wall clock. At 9600 the
|
||||
window (~5+ms) hides USB turnaround entirely (zero framing in both
|
||||
9600 runs); at 31250 it shrinks to ~1.6ms, which USB cannot reliably
|
||||
beat, so most replies retransmit and 65 exhausted all 4 retries.
|
||||
|
||||
Two conclusions:
|
||||
1. **Brutal confirmation of the wedge patch**: 65 trips through the
|
||||
give-up path in 127s, every one self-recovered ($DFF0 stub). The
|
||||
unpatched firmware would have latched dead on the first.
|
||||
2. **31250 needs one more firmware tweak to be clean**: widen the
|
||||
reply-retry wait (the pacing/limit around the $D90E/$D9BE retry
|
||||
machine) so the window stays >=10ms of wall clock at 31250. Until
|
||||
then: cabinets run the 9600 patched chip (validated clean); 31250
|
||||
stays a bench branch. Note the duplicate replies also mean the raw
|
||||
reply rate overstates throughput — unique samples are still capped
|
||||
by the host's 55ms poll; harvesting the speed needs a faster poll
|
||||
AFTER the retry window is fixed.
|
||||
|
||||
@@ -346,23 +346,30 @@ internal static class MashTest
|
||||
// --- helpers ---------------------------------------------------------
|
||||
async Task<Dictionary<RioStatusType, int>> SnapshotStatusAsync()
|
||||
{
|
||||
lock (gate) { statusItems.Clear(); statusCollecting = true; }
|
||||
try
|
||||
// Two attempts: the first request can lose a race with the board's
|
||||
// post-DTR boot (port open pulses DTR = board reset), or get eaten
|
||||
// by a reply collision — seen on the 31250 bench run.
|
||||
for (int attempt = 0; ; attempt++)
|
||||
{
|
||||
await link.RequestVersionAsync();
|
||||
await link.RequestCheckAsync();
|
||||
}
|
||||
catch { /* port trouble surfaces as an empty snapshot */ }
|
||||
await Task.Delay(1200);
|
||||
lock (gate) { statusItems.Clear(); statusCollecting = true; }
|
||||
try
|
||||
{
|
||||
await link.RequestVersionAsync();
|
||||
await link.RequestCheckAsync();
|
||||
}
|
||||
catch { /* port trouble surfaces as an empty snapshot */ }
|
||||
await Task.Delay(1200);
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
statusCollecting = false;
|
||||
// Counters arrive one item per type; keep the last value per type.
|
||||
var map = new Dictionary<RioStatusType, int>();
|
||||
foreach (CheckStatus item in statusItems)
|
||||
map[item.Type] = item.Number;
|
||||
return map;
|
||||
lock (gate)
|
||||
{
|
||||
statusCollecting = false;
|
||||
// Counters arrive one item per type; keep the last value per type.
|
||||
var map = new Dictionary<RioStatusType, int>();
|
||||
foreach (CheckStatus item in statusItems)
|
||||
map[item.Type] = item.Number;
|
||||
if (map.Count > 0 || attempt == 1)
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user