New IO-ARCHITECTURE.md, derived from the v4.2 image, the U7 GAL decode and schematic sheets 1/3: - $A010 control-latch bit map (CCK / D_OUT / WR_SB / RD_SB / SEL0-2) - the 50-byte script format the firmware replays, and the ROM table map - full port/address population: 9 buttons boards + 2 keypads across all 8 ports; the 0x00-0x6F logical map and its 0x48-0x4F gap - the keypad engine ($CC53/$CC7E): 4-row matrix scan, row-patched RAM scripts, the $DC14 key-code table, message type $8B - lamp readback ($21C2) and the 72-byte lamp-fault mask at $DFA8 -- fault reports are type $03 with the lamp index in $2519 - scan cycle budget: 1.91 ms/pass, 17.3 ms/scan, ~58 Hz; demux is 60% - expansion: one spare buttons board, and nothing further without a protocol revision Corrections to existing docs: - $CC53 was cited as the encoder sweep; it is the keypad-1 scanner. The sweep is $C8CC-$C9A7, driven from $C0CB. - U31 is on sheet 3, not sheet 1, and is completely uncommitted: no address, data, strobe or pod-bus signal reaches it. Not an expansion hook -- populating it does nothing without new wiring. - No spare HCTL-2016 footprints exist. The decode has 3 free selects on U9, but the PCB carries exactly 5 positions and sheet 1 draws 5. More analog axes need hardware, not firmware. Also carries the previously-uncommitted standard-rate (16550) feasibility analysis and baudscan.py, plus a note that the FastRIO "FTDI-class adapter" rule really means arbitrary-rate generation: CP2102N qualifies, classic CP2102 snaps 31250 to 38400. Bench-measured 2026-07-26; on-cockpit latency check still pending. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
43 lines
1.8 KiB
Python
43 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Exhaustive HC11 SCI rate scan vs 16550-standard rates, per candidate
|
|
oscillator can. Evidence behind the "Standard-rate (16550) feasibility"
|
|
section of RIOv4_2-ANALYSIS.md.
|
|
|
|
HC11 SCI baud = E / (16 * SCP * 2^SCR), E = can/4,
|
|
SCP (prescale) in {1,3,4,13}, SCR (divider) 2^0..2^7.
|
|
16550 standard = 1.8432MHz / (16 * divisor), divisor integer >= 1.
|
|
A pairing is workable if |error| <= 2.0% (conservative per-link UART
|
|
budget; >3% is hopeless, 2-3% marginal). From the stock 8 MHz can the
|
|
only in-tolerance pairings are 9615<->9600 (stock, the /13 prescale)
|
|
and 10417<->115200/11 (+8.3% throughput, pointless) -- every faster
|
|
rate carries the +8.51% residue of 125000/115200 = 625/576.
|
|
"""
|
|
STD = [9600, 14400, 19200, 28800, 38400, 57600, 115200] # 16550-reachable
|
|
XTALS = {
|
|
"8.000000 (stock)": 8_000_000,
|
|
"7.372800": 7_372_800,
|
|
"9.830400": 9_830_400,
|
|
"11.059200": 11_059_200,
|
|
"12.288000": 12_288_000,
|
|
"14.745600": 14_745_600,
|
|
}
|
|
for name, x in XTALS.items():
|
|
e = x / 4
|
|
print(f"\n=== can {name} MHz -> E = {e/1e6:.4f} MHz ===")
|
|
rows = []
|
|
for scp, scpbits in [(1, 0b00), (3, 0b01), (4, 0b10), (13, 0b11)]:
|
|
for scr in range(8):
|
|
rate = e / (16 * scp * (1 << scr))
|
|
if rate < 9000:
|
|
continue
|
|
baudreg = (scpbits << 4) | scr
|
|
best = min(STD, key=lambda s: abs(rate - s) / s)
|
|
err = (rate - best) / best * 100
|
|
cyc = e / (rate / 10) # E-cycles per 10-bit byte
|
|
rows.append((rate, baudreg, best, err, cyc))
|
|
for rate, baudreg, best, err, cyc in sorted(rows, reverse=True):
|
|
flag = " <== EXACT" if abs(err) < 0.01 else (
|
|
" <-- ok" if abs(err) <= 2.0 else "")
|
|
print(f" BAUD=${baudreg:02X} {rate:9.1f} vs {best:6d} "
|
|
f"err {err:+6.2f}% {cyc:6.0f} E-cyc/byte{flag}")
|