Introduce `DEBIAN_SUITE` as a configurable argument in the Dockerfile, build script, and CI workflow to align kernel builds with the target Raspberry Pi OS release. Updated documentation to clarify the relationship between suite versions and kernel compatibility.
iec_listener kernel module
Commodore IEC listener (printer, default address 4) for the Raspberry Pi
Zero 2 W. The timing-critical IEC handshake runs in this kernel module; received
bytes and bus events are pushed to userspace through /dev/iec0.
Build/deploy, pinning, GPIO-descriptor and timing details live in
../docs/kernel-notes.md. This README documents the
self-test, which is the first thing to run after loading the module on real
hardware.
Self-test
The module exposes a hardware self-test via the IEC_IOC_SELFTEST ioctl on
/dev/iec0. It drives the DATA line (the only line the Pi asserts) low and
reads it back, releases it, then samples ATN / CLK / RESET, returning a
bitmask of line states. Run it with the C64 disconnected to check the wiring
before connecting the real bus (see PLAN.md §10).
Running it
selftest.sh is non-persistent (nothing is installed into /lib/modules, no
autoload): it checks vermagic, loads the module, runs the self-test, and always
unloads it again.
sudo ./selftest.sh # auto-finds ./ or ~/iec_listener.ko, address 4
sudo ./selftest.sh ~/iec_listener.ko --address 5 # runs with ~/iec_listener.ko, address 5
It exits non-zero unless the result is a full pass (0x1F), so it is usable in
scripts/CI.
Result bitmask
The ioctl returns a u32; a full pass is 0x1F (all five bits set).
| Bit | Value | Meaning | Source |
|---|---|---|---|
DATA_ASSERT_OK |
0x01 |
DATA read low while the module drives it low | Pi drive + sense path |
DATA_FLOAT_OK |
0x02 |
DATA read high after release (Hi-Z) | external pull-up on DATA |
ATN_RELEASED |
0x04 |
ATN high (idle) | line state |
CLK_RELEASED |
0x08 |
CLK high (idle) | line state |
RESET_RELEASED |
0x10 |
RESET high (idle) | line state |
Constants are defined in iec_listener.h; the ioctl number is
_IOR('I', 3, __u32) = 0x80044903.
Interpreting failures
DATA_ASSERT_OKmissing → driving DATA low doesn't read back low: level shifter wired backwards/inverting, wrong pin, or the sense path is broken. This is the only bit that is fully internal to the Pi — if it fails, suspect the module/build or the DATA wiring, not pull-ups.DATA_FLOAT_OKmissing → DATA stays low after release: missing/weak pull-up on DATA, or the pin didn't return to input.CLK_RELEASEDmissing → CLK reads low at idle: no pull-up on CLK, short, or a swapped signal.ATN_RELEASED/RESET_RELEASEDmissing → that line reads low at idle: short, missing pull-up, or swapped wiring.
⚠️ Bare-board caveat
With nothing connected, the expected result is 0x15, not a fault:
DATA_ASSERT_OK(0x01) passes — it's internal to the Pi.ATN_RELEASED(0x04) andRESET_RELEASED(0x10) pass only because GPIO2/GPIO3 have fixed ~1.8 kΩ pull-ups built into the BCM2710 SoC (they are the I²C0 pins; the pull-ups can't be disabled). They read high even with nothing wired, so on a bare board these two bits prove nothing about your wiring.DATA_FLOAT_OK(0x02) andCLK_RELEASED(0x08) read low because GPIO17/18 have no such built-in pull-up and nothing is attached.
So on a bare board the only meaningful signal is DATA_ASSERT_OK. A full 0x1F
is only reachable once the level shifter (with its CLK/DATA pull-ups) is wired
and powered. To make ATN/RESET meaningful, briefly ground each at the connector
and confirm the corresponding bit drops.