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
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
This commit is contained in:
parent
acfce76011
commit
b2e4f9710d
@ -94,10 +94,10 @@ the 1 ms ATN ack and the per-byte ack — both forgiving. The tight constraint i
|
|||||||
|
|
||||||
| IEC signal | Pi GPIO (BCM) | Header pin | Direction | Logic note |
|
| IEC signal | Pi GPIO (BCM) | Header pin | Direction | Logic note |
|
||||||
|------------|---------------|------------|-----------|------------|
|
|------------|---------------|------------|-----------|------------|
|
||||||
| ATN | GPIO 2 | 3 | input (divider) | bus low = Pi low = asserted |
|
| ATN | GPIO 4 | 7 | input (divider) | bus low = Pi low = asserted |
|
||||||
| CLK | GPIO 17 | 11 | input (divider) | bus low = Pi low = asserted |
|
| CLK | GPIO 3 | 5 | input (divider) | bus low = Pi low = asserted |
|
||||||
| DATA (in) | GPIO 18 | 12 | output → 7406 → bus | Pi HIGH = bus asserted (inverted) |
|
| DATA (in) | GPIO 2 | 3 | output → 7406 → bus | Pi HIGH = bus asserted (inverted) |
|
||||||
| RESET | GPIO 3 | 5 | input (divider) | bus low = Pi low = asserted |
|
| RESET | GPIO 17 | 11 | input (divider) | bus low = Pi low = asserted |
|
||||||
| GND | — | 6 (or any) | — | tie to IEC pin 2 |
|
| GND | — | 6 (or any) | — | tie to IEC pin 2 |
|
||||||
|
|
||||||
> Convention used in code: a helper layer converts electrical reads/writes into
|
> Convention used in code: a helper layer converts electrical reads/writes into
|
||||||
|
|||||||
@ -59,11 +59,11 @@ at global number 0 — it's `gpiochip512`, **base 512**:
|
|||||||
$ cat /sys/class/gpio/gpiochip*/base # -> 512 (pinctrl-bcm2835), 566 (exp-gpio)
|
$ cat /sys/class/gpio/gpiochip*/base # -> 512 (pinctrl-bcm2835), 566 (exp-gpio)
|
||||||
```
|
```
|
||||||
|
|
||||||
The old code used `gpio_to_desc(2/3/17/18)`, i.e. the *global* numberspace
|
The old code used `gpio_to_desc(2/3/4/17)`, i.e. the *global* numberspace
|
||||||
assuming base 0. Those small numbers now fall outside the chip's range
|
assuming base 0. Those small numbers now fall outside the chip's range
|
||||||
(512–565), so every `gpio_to_desc()` returned `NULL`, the descriptor check
|
(512–565), so every `gpio_to_desc()` returned `NULL`, the descriptor check
|
||||||
tripped, and init bailed with `-ENODEV`. The `(chip, hwnum)` lookup passes the
|
tripped, and init bailed with `-ENODEV`. The `(chip, hwnum)` lookup passes the
|
||||||
**BCM number as the chip-relative offset** (ATN=2, RESET=3, CLK=17, DATA=18),
|
**BCM number as the chip-relative offset** (ATN=4, RESET=17, CLK=3, DATA=2),
|
||||||
which is base-independent and survives kernel bumps / gpiochip renumbering.
|
which is base-independent and survives kernel bumps / gpiochip renumbering.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|||||||
@ -25,20 +25,26 @@ The shifter is **non-inverting**: bus low (asserted) ⇒ Pi reads LOW.
|
|||||||
|
|
||||||
| IEC signal | IEC DIN pin | Pi GPIO (BCM) | Header pin | Direction |
|
| IEC signal | IEC DIN pin | Pi GPIO (BCM) | Header pin | Direction |
|
||||||
|------------|-------------|---------------|------------|-----------|
|
|------------|-------------|---------------|------------|-----------|
|
||||||
| ATN | 3 | GPIO 2 | 3 | input (via shifter) |
|
| ATN | 3 | GPIO 4 | 7 | input (via shifter) |
|
||||||
| CLK | 4 | GPIO 17 | 11 | input (via shifter) |
|
| CLK | 4 | GPIO 3 | 5 | input (via shifter) |
|
||||||
| DATA | 5 | GPIO 18 | 12 | **bidirectional** (via shifter) |
|
| DATA | 5 | GPIO 2 | 3 | **bidirectional** (via shifter) |
|
||||||
| RESET | 6 | GPIO 3 | 5 | input (via shifter) |
|
| RESET | 6 | GPIO 17 | 11 | input (via shifter) |
|
||||||
| GND | 2 | GND | 6 (or any) | — |
|
| GND | 2 | GND | 6 (or any) | — |
|
||||||
| SRQ | 1 | — | — | not connected |
|
| SRQ | 1 | — | — | not connected |
|
||||||
|
|
||||||
|
> ℹ️ **DATA (GPIO2) and CLK (GPIO3) are the Pi's ARM I²C pins** and carry the
|
||||||
|
> SoC's fixed ~1.8 kΩ pull-ups (benign — DATA is open-drain). Keep
|
||||||
|
> `dtparam=i2c_arm` **off** in `/boot/firmware/config.txt` (the default) so I²C
|
||||||
|
> does not claim these pins. This layout matches a confirmed-working reference
|
||||||
|
> listener.
|
||||||
|
|
||||||
## DATA open-drain emulation
|
## DATA open-drain emulation
|
||||||
|
|
||||||
GPIO 18 is never a push-pull driver of the bus. The module flips its direction:
|
GPIO 2 is never a push-pull driver of the bus. The module flips its direction:
|
||||||
|
|
||||||
- **assert** (pull bus low): GPIO 18 = output **LOW** → shifter pulls bus to 0 V.
|
- **assert** (pull bus low): GPIO 2 = output **LOW** → shifter pulls bus to 0 V.
|
||||||
- **release / read**: GPIO 18 = **input (Hi-Z)** → bus pull-ups float it to 5 V,
|
- **release / read**: GPIO 2 = **input (Hi-Z)** → bus pull-ups float it to 5 V,
|
||||||
and GPIO 18 reads the level the *talker* (C64) is driving — this is how bits
|
and GPIO 2 reads the level the *talker* (C64) is driving — this is how bits
|
||||||
are sampled during receive.
|
are sampled during receive.
|
||||||
|
|
||||||
Logical mapping (handled in `kernel/iec_lines.h`): asserted ⇔ Pi reads LOW.
|
Logical mapping (handled in `kernel/iec_lines.h`): asserted ⇔ Pi reads LOW.
|
||||||
|
|||||||
@ -92,18 +92,21 @@ Constants are defined in [`iec_listener.h`](iec_listener.h); the ioctl number is
|
|||||||
|
|
||||||
### ⚠️ Bare-board caveat
|
### ⚠️ Bare-board caveat
|
||||||
|
|
||||||
With **nothing connected**, the expected result is **`0x15`**, *not* a fault:
|
With **nothing connected**, the expected result is **`0x0B`**, *not* a fault:
|
||||||
|
|
||||||
- `DATA_ASSERT_OK` (`0x01`) passes — it's internal to the Pi.
|
- `DATA_ASSERT_OK` (`0x01`) passes — it's internal to the Pi.
|
||||||
- `ATN_RELEASED` (`0x04`) and `RESET_RELEASED` (`0x10`) pass **only because
|
- `DATA_FLOAT_OK` (`0x02`) and `CLK_RELEASED` (`0x08`) pass **only because
|
||||||
GPIO2/GPIO3 have fixed ~1.8 kΩ pull-ups built into the BCM2710 SoC** (they are
|
DATA=GPIO2 and CLK=GPIO3 have fixed ~1.8 kΩ pull-ups built into the BCM2710
|
||||||
the I²C0 pins; the pull-ups can't be disabled). They read high even with
|
SoC** (they are the I²C pins; the pull-ups can't be disabled). They read high
|
||||||
nothing wired, so on a bare board these two bits prove **nothing** about your
|
even with nothing wired, so on a bare board these two bits prove **nothing**
|
||||||
wiring.
|
about your wiring. In particular `DATA_FLOAT_OK` now floats high via the SoC
|
||||||
- `DATA_FLOAT_OK` (`0x02`) and `CLK_RELEASED` (`0x08`) read low because GPIO17/18
|
pull-up even without the shifter, so it no longer confirms the shifter's DATA
|
||||||
have no such built-in pull-up and nothing is attached.
|
pull-up — it's only meaningful once the shifter is wired.
|
||||||
|
- `ATN_RELEASED` (`0x04`) and `RESET_RELEASED` (`0x10`) read low because
|
||||||
|
ATN=GPIO4 and RESET=GPIO17 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`
|
So on a bare board the only fully internal signal is `DATA_ASSERT_OK`. A full
|
||||||
is only reachable once the level shifter (with its CLK/DATA pull-ups) is wired
|
`0x1F` is only reachable once the level shifter (with its ATN/RESET pull-ups) is
|
||||||
and powered. To make ATN/RESET meaningful, briefly ground each at the connector
|
wired and powered. To make ATN/RESET meaningful, briefly ground each at the
|
||||||
and confirm the corresponding bit *drops*.
|
connector and confirm the corresponding bit *drops*.
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* iec-overlay.dts - pin reservation + pull configuration for the IEC listener.
|
* iec-overlay.dts - pin reservation + pull configuration for the IEC listener.
|
||||||
*
|
*
|
||||||
* GPIO 2 = ATN (input, pull-up: bus idle = 5 V = high)
|
* GPIO 4 = ATN (input, pull-up: bus idle = 5 V = high)
|
||||||
* GPIO 17 = CLK (input, pull-up)
|
* GPIO 3 = CLK (input, pull-up)
|
||||||
* GPIO 3 = RESET (input, pull-up)
|
* GPIO 17 = RESET (input, pull-up)
|
||||||
* GPIO 18 = DATA (bidirectional; starts as input/Hi-Z, the module flips it)
|
* GPIO 2 = DATA (bidirectional; starts as input/Hi-Z, the module flips it)
|
||||||
|
*
|
||||||
|
* NOTE: DATA (GPIO2) and CLK (GPIO3) are the ARM I2C pins and carry the SoC's
|
||||||
|
* fixed ~1.8 kOhm pull-ups, which the overlay's pull settings cannot fully
|
||||||
|
* override. Benign here (DATA is open-drain). Keep dtparam=i2c_arm OFF so I2C
|
||||||
|
* does not claim these pins.
|
||||||
*
|
*
|
||||||
* The module drives GPIO via direct registers, so this overlay's main job is to
|
* The module drives GPIO via direct registers, so this overlay's main job is to
|
||||||
* reserve the pins and set sane pull defaults. Build & install:
|
* reserve the pins and set sane pull defaults. Build & install:
|
||||||
@ -25,12 +30,12 @@
|
|||||||
target = <&gpio>;
|
target = <&gpio>;
|
||||||
__overlay__ {
|
__overlay__ {
|
||||||
iec_input_pins: iec_input_pins {
|
iec_input_pins: iec_input_pins {
|
||||||
brcm,pins = <2 17 3>; /* ATN, CLK, RESET */
|
brcm,pins = <4 3 17>; /* ATN, CLK, RESET */
|
||||||
brcm,function = <0>; /* 0 = input */
|
brcm,function = <0>; /* 0 = input */
|
||||||
brcm,pull = <2>; /* 2 = pull-up */
|
brcm,pull = <2>; /* 2 = pull-up */
|
||||||
};
|
};
|
||||||
iec_data_pin: iec_data_pin {
|
iec_data_pin: iec_data_pin {
|
||||||
brcm,pins = <18>; /* DATA */
|
brcm,pins = <2>; /* DATA */
|
||||||
brcm,function = <0>; /* start as input (Hi-Z) */
|
brcm,function = <0>; /* start as input (Hi-Z) */
|
||||||
brcm,pull = <0>; /* 0 = none (shifter drives) */
|
brcm,pull = <0>; /* 0 = none (shifter drives) */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,8 +10,8 @@
|
|||||||
* bus released (5 V) <=> Pi GPIO reads HIGH
|
* bus released (5 V) <=> Pi GPIO reads HIGH
|
||||||
*
|
*
|
||||||
* DATA is open-drain emulated on a single bidirectional pin:
|
* DATA is open-drain emulated on a single bidirectional pin:
|
||||||
* assert : drive GPIO18 OUTPUT LOW -> shifter pulls bus to 0 V
|
* assert : drive GPIO2 OUTPUT LOW -> shifter pulls bus to 0 V
|
||||||
* release : set GPIO18 INPUT (Hi-Z) -> bus pull-ups float it to 5 V;
|
* release : set GPIO2 INPUT (Hi-Z) -> bus pull-ups float it to 5 V;
|
||||||
* the talker's bits can now be read back through the shifter.
|
* the talker's bits can now be read back through the shifter.
|
||||||
*
|
*
|
||||||
* The hot path uses direct BCM register access (ioremap'd), which the kernel
|
* The hot path uses direct BCM register access (ioremap'd), which the kernel
|
||||||
@ -30,10 +30,10 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
|
||||||
/* --- GPIO assignment (BCM numbering, PLAN.md §3.2) ----------------------- */
|
/* --- GPIO assignment (BCM numbering, PLAN.md §3.2) ----------------------- */
|
||||||
#define IEC_GPIO_ATN 2 /* header pin 3 - input */
|
#define IEC_GPIO_ATN 4 /* header pin 7 - input */
|
||||||
#define IEC_GPIO_RESET 3 /* header pin 5 - input */
|
#define IEC_GPIO_RESET 17 /* header pin 11 - input */
|
||||||
#define IEC_GPIO_CLK 17 /* header pin 11 - input */
|
#define IEC_GPIO_CLK 3 /* header pin 5 - input */
|
||||||
#define IEC_GPIO_DATA 18 /* header pin 12 - bidirectional (open-drain) */
|
#define IEC_GPIO_DATA 2 /* header pin 3 - bidirectional (open-drain) */
|
||||||
|
|
||||||
/* --- BCM2710A1 / BCM2837 (Pi Zero 2 W) peripheral map ------------------- */
|
/* --- BCM2710A1 / BCM2837 (Pi Zero 2 W) peripheral map ------------------- */
|
||||||
/* Same peripheral base as RPi 3. RPi 1 = 0x20000000, RPi 4 = 0xFE000000. */
|
/* Same peripheral base as RPi 3. RPi 1 = 0x20000000, RPi 4 = 0xFE000000. */
|
||||||
|
|||||||
@ -189,8 +189,9 @@ if [ "$ST" -eq 0 ]; then
|
|||||||
ok "self-test PASSED (0x1F) - all four lines wired correctly"
|
ok "self-test PASSED (0x1F) - all four lines wired correctly"
|
||||||
else
|
else
|
||||||
info "self-test did not fully pass."
|
info "self-test did not fully pass."
|
||||||
info "On a BARE board 0x15 is expected and fine: only DATA_ASSERT_OK is"
|
info "On a BARE board 0x0b is expected and fine: DATA_FLOAT_OK + CLK_RELEASED"
|
||||||
info "meaningful; ATN/RESET pass via the SoC's fixed GPIO2/3 pull-ups."
|
info "pass via the SoC's fixed GPIO2/3 (DATA/CLK) pull-ups, and DATA_ASSERT_OK"
|
||||||
|
info "is internal; ATN/RESET read low (GPIO4/17 have no built-in pull-up)."
|
||||||
info "Re-run once the level shifter is wired + powered; you want 0x1F."
|
info "Re-run once the level shifter is wired + powered; you want 0x1F."
|
||||||
fi
|
fi
|
||||||
exit "$ST"
|
exit "$ST"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user