feat(kernel): add debounced (glitch-filtered) sense-line reads #5

Open
chris wants to merge 14 commits from debounced-reads into master

14 Commits

Author SHA1 Message Date
2015d4c96e docs(kernel): document DATA line locking design to prevent RMW collisions
All checks were successful
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 57s
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m23s
Build kernel module / package (pull_request) Successful in 19s
Build kernel module / release (pull_request) Has been skipped
Add row to "Decisions baked into the code" table explaining the DATA line
control design: all DATA assert/release operations in the worker and ATN ISR
go through iec_data_*_sync() under iec_data_lock to serialize the GPFSEL0
read-modify-write across CPUs. The release wrapper refuses to release while
ATN is asserted, preventing the ready-for-data release from erasing the ISR's
presence acknowledge — the bug that caused intermittently missed
LISTEN/UNLISTEN commands. Init/exit/self-test keep raw unconditional helpers.

Generated by Clanker 🤖
2026-06-22 00:09:50 +02:00
ec615dbb80 fix(iec_listener): serialize DATA line control to fix missed command bytes
The worker kthread and ATN ISR both modify the DATA line by changing GPIO2's
direction (open-drain emulation). On quad-core Pi they run simultaneously on
different CPUs, causing their read-modify-write operations on the shared GPFSEL0
register to clobber each other. The ISR's ATN presence-acknowledge could be
erased by the worker's ready-for-data release, causing the C64 to see "device
not present" and drop LISTEN/UNLISTEN command bytes.

Add iec_data_lock spinlock and two synchronized wrappers:
- iec_data_assert_sync(): serializes DATA assert
- iec_data_release_sync(): serializes DATA release and refuses to release while
  ATN is asserted, preventing the acknowledge from being undone

Convert all worker and ISR DATA accesses to use the _sync() wrappers. Keep raw
unconditional helpers for init/exit/self-test (exit must free the bus
unconditionally; self-test probes directly).

Generated by Clanker 🤖
2026-06-22 00:08:45 +02:00
6c549b164c maybe fix program not exiting
All checks were successful
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m1s
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 1m13s
Build kernel module / package (pull_request) Successful in 20s
Build kernel module / release (pull_request) Has been skipped
2026-06-20 18:48:25 +02:00
8bb6058a04 update workflow to package the scripts with execute permission hopefully 2026-06-20 18:46:58 +02:00
dba7b5c43c data was bricked reverting debounce to 5 2026-06-20 18:46:17 +02:00
63c3167d9f update workflow
All checks were successful
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 1m10s
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m10s
Build kernel module / package (pull_request) Successful in 21s
Build kernel module / release (pull_request) Has been skipped
2026-06-20 18:21:05 +02:00
565b58480a docs(kernel): document frontend output modes
Added a 'Frontend output modes' section explaining plain text (default),
--debug (annotated trace), and --raw (hex), with launch.sh examples for
each.

Generated by Clanker
2026-06-20 18:20:15 +02:00
affdcdda6b docs(launch): update usage comments for plain-text default
The default output is now plain text, not an annotated trace. Updated the
header comment and added a --debug example.

Generated by Clanker
2026-06-20 18:20:09 +02:00
0d6034702a test(iecpoc): add plain-mode tests for TraceFormatter
Covers the plain property, per-record-type output (printable chars,
CR/LF newlines, LISTEN/UNLISTEN dividers, silenced events and other
commands), and a full-session integration check.

Generated by Clanker
2026-06-20 18:19:47 +02:00
d359aa4acc feat(iecpoc): add plain-text output mode with --debug flag
Default output now shows only the received characters; CR/LF become real
newlines and LISTEN/UNLISTEN print a clearly visible divider. Pass --debug
to restore the previous full annotated trace.

Generated by Clanker
2026-06-20 18:19:41 +02:00
3cf13f14f2 adjust debounce time
All checks were successful
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 59s
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m0s
Build kernel module / package (pull_request) Successful in 18s
Build kernel module / release (pull_request) Has been skipped
2026-06-20 17:52:41 +02:00
63adefea86 yes
All checks were successful
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 1m23s
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m24s
Build kernel module / package (pull_request) Successful in 17s
Build kernel module / release (pull_request) Has been skipped
2026-06-20 17:25:00 +02:00
b2e4f9710d refactor(kernel): align GPIO pin layout with the reference listener
All checks were successful
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 1m1s
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 1m8s
Build kernel module / package (pull_request) Successful in 29s
Build kernel module / release (pull_request) Has been skipped
Adopt the confirmed-working reference's pin assignment so the module runs
on that proven wiring: DATA=BCM2 (pin 3), CLK=BCM3 (pin 5), ATN=BCM4
(pin 7). RESET is kept and relocated to BCM17 (pin 11), the pin freed by
moving CLK. All five GPIOs stay in bank 0, so the direct-register hot
path and ATN IRQ are unchanged -- only the IEC_GPIO_* defines, the
device-tree overlay, and the docs/self-test move.

DATA/CLK now sit on the ARM I2C pins (GPIO2/3) with the SoC's fixed
~1.8k pull-ups; keep dtparam=i2c_arm off. The bare-board self-test
expectation changes from 0x15 to 0x0b accordingly.

Generated by Clanker
2026-06-20 16:09:10 +02:00
acfce76011 feat(kernel): add debounced (glitch-filtered) sense-line reads
All checks were successful
Build kernel module / build (1:6.12.93-1+rpt1, bookworm) (pull_request) Successful in 57s
Build kernel module / build (1:6.18.34-1+rpt1, trixie) (pull_request) Successful in 1m14s
Build kernel module / package (pull_request) Successful in 23s
Build kernel module / release (pull_request) Has been skipped
The IEC bit loop sampled GPIO with a single register read, so a glitch
on a level-shifted 5V<->3.3V bus could corrupt a bit with no chance to
retry (the loop runs with IRQs off). Add a stable-read filter that only
believes a level change after it holds IEC_DEBOUNCE_US (now 5 us); the
fast path is a single read so tight CLK polls stay cheap. Used across
the receive hot path; the ATN ISR and self-test keep raw reads.

Generated by Clanker

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 15:50:54 +02:00