Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ jobs:
dpkg -S /usr/sbin/avahi-daemon 2>/dev/null | grep -q '^avahi-dpea:' \
&& echo "OK /usr/sbin/avahi-daemon owned by avahi-dpea" \
|| { echo "FAIL avahi-daemon binary not replaced by avahi-dpea"; fail=1; }
for line in "dtparam=i2c_arm=on" "dtparam=spi=on" "enable_uart=1" "dtoverlay=disable-bt"; do
for line in "dtparam=i2c_arm=on" "enable_uart=1" "dtoverlay=disable-bt"; do
grep -qx "$line" /boot/firmware/config.txt && echo "OK config: $line" || { echo "FAIL config: $line"; fail=1; }
done
# SPI must NOT be enabled: it would claim GPIO7 (SPI0 CE1), a DPi computer input.
grep -qx "dtparam=spi=on" /boot/firmware/config.txt && { echo "FAIL config: spi should be off"; fail=1; } || echo "OK config: spi not enabled"
# serial login console masked so the DPi RS485 bus owns /dev/serial0.
test -L /etc/systemd/system/serial-getty@ttyAMA0.service && echo "OK serial getty masked" || { echo "FAIL serial getty not masked"; fail=1; }
test -f /etc/NetworkManager/system-connections/dpea-eth0.nmconnection \
&& echo "OK eth0 profile present" || { echo "FAIL eth0 profile"; fail=1; }
# best-effort: mDNS binds 5358 (a container may not let the daemon start; verify on hardware)
Expand Down
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ dependencies and installs them with `uv`.
## What the image bakes in

- **OS**: Raspberry Pi OS Trixie 64-bit (arm64), Desktop
- **Hardware**: I2C, SPI, and UART enabled. `dtoverlay=disable-bt` so
`/dev/serial0` is the PL011 UART for the SlushEngine / DPi bus. `i2c-dev` loaded.
- **Hardware**: I2C and UART enabled, SPI deliberately OFF. `dtoverlay=disable-bt`
so `/dev/serial0` is the PL011 UART for the SlushEngine / DPi bus, and the serial
login console is disabled so a getty does not fight that bus on the same port.
`i2c-dev` loaded. SPI stays off because the DPi computer uses GPIO7 (SPI0 CE1) as
a digital input, which an SPI overlay would claim ("GPIO busy").
- **Networking (`eth0`)**: DHCP for internet, plus an always-on static
`172.17.21.2/22` for a direct laptop-to-Pi cable.
- **mDNS**: the patched avahi that serves mDNS on port **5358**.
Expand All @@ -21,7 +24,7 @@ dependencies and installs them with `uv`.
Current contents:

- core: `git`, `curl`, `ca-certificates`
- I2C/SPI: `i2c-tools`
- I2C: `i2c-tools`
- kivy runtime: `libsdl2-2.0-0`, `libsdl2-image-2.0-0`, `libsdl2-mixer-2.0-0`, `libsdl2-ttf-2.0-0`, `libmtdev1`, `libgl1-mesa-dri`
- mDNS resolution: `libnss-mdns`

Expand Down Expand Up @@ -66,20 +69,21 @@ repo is public, so no GitHub account is needed to download the image.

Runs `shellcheck`, then runs `customize.sh` inside an arm64 Trixie container
and asserts what can be checked without hardware: `uv` present, the 5358 avahi
`.deb` installed, the I2C/SPI/UART lines written, and the eth0 NetworkManager
profile present. This gates merges to `main`.
`.deb` installed, the I2C/UART config lines written (and SPI *not* enabled), the
serial getty masked, and the eth0 NetworkManager profile present. This gates
merges to `main`.

Container checks cannot exercise real hardware or multicast, so they do not cover
actual I2C/SPI/UART function, live `.local` resolution, or the eth0 address
coming up. Those need a flashed Pi.
actual I2C/UART function, live `.local` resolution, or the eth0 address coming up.
Those need a flashed Pi.

### On real hardware (`hardware-smoke-test.sh`)

After flashing a Pi, run `sudo ./hardware-smoke-test.sh` on it. It checks: `uv`
present, `/dev/i2c-*` and `/dev/spidev*` nodes, `/dev/serial0 -> ttyAMA0`, avahi
listening on 5358 (and not 5353), and eth0 holding `172.17.21.2`. For the
direct-cable path, set another machine's ethernet to `172.17.21.1` and confirm
you can reach `172.17.21.2`.
present, `/dev/i2c-*` present and no `/dev/spidev*` (SPI off), `/dev/serial0 ->
ttyAMA0` with the serial login console off, avahi listening on 5358 (and not
5353), and eth0 holding `172.17.21.2`. For the direct-cable path, set another
machine's ethernet to `172.17.21.1` and confirm you can reach `172.17.21.2`.

## Files

Expand Down
16 changes: 15 additions & 1 deletion customize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,28 @@ apt-get install -y --no-install-recommends \
$(sed -e 's/#.*//' -e '/^[[:space:]]*$/d' /tmp/packages.txt)

# --- hardware interfaces (edit config.txt directly) ---
# SPI is deliberately NOT enabled: the DPi computer board uses GPIO7 (SPI0 CE1)
# as a digital input (_IN_3_PIN), so an enabled SPI overlay claims that pin and
# the board's GPIO.setup fails with "GPIO busy".
CONFIG=/boot/firmware/config.txt
[ -f "$CONFIG" ] || CONFIG=/boot/config.txt
grep -q '^dtparam=i2c_arm=on' "$CONFIG" || echo 'dtparam=i2c_arm=on' >> "$CONFIG"
grep -q '^dtparam=spi=on' "$CONFIG" || echo 'dtparam=spi=on' >> "$CONFIG"
grep -q '^enable_uart=1' "$CONFIG" || echo 'enable_uart=1' >> "$CONFIG"
grep -q '^dtoverlay=disable-bt' "$CONFIG" || echo 'dtoverlay=disable-bt' >> "$CONFIG"
grep -q '^i2c-dev' /etc/modules || echo 'i2c-dev' >> /etc/modules

# --- serial login console OFF (the UART hardware stays on via enable_uart above) ---
# Raspberry Pi OS runs a getty on the serial console by default; it holds
# /dev/serial0 open and fights the DPi RS485 bus (serial.Serial on /dev/serial0),
# giving "device reports readiness to read but returned no data (multiple access
# on port?)". Disable it two ways: drop the console= token from cmdline.txt, and
# mask the serial getty. enable_uart=1 above keeps the UART itself available.
CMDLINE=/boot/firmware/cmdline.txt
[ -f "$CMDLINE" ] || CMDLINE=/boot/cmdline.txt
[ -f "$CMDLINE" ] && sed -i -E 's/ ?console=(serial0|ttyAMA0|ttyS0),[0-9]+//g' "$CMDLINE"
install -d /etc/systemd/system
ln -sf /dev/null /etc/systemd/system/serial-getty@ttyAMA0.service

# --- patched avahi (mDNS on 5358) from the prebuilt arm64 .deb (avahi_0.8 CI) ---
AVAHI_DEB_URL="${AVAHI_DEB_URL:-https://github.com/dpengineering/avahi_0.8/releases/latest/download/avahi-dpea_0.8_arm64.deb}"
if curl -fLsS "$AVAHI_DEB_URL" -o /tmp/avahi.deb; then
Expand Down
3 changes: 2 additions & 1 deletion hardware-smoke-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ skip(){ echo "SKIP $1 ($2)"; skipped=$((skipped+1)); }

chk "uv installed" "command -v uv"
chk "I2C device node present" "ls /dev/i2c-*"
chk "SPI device node present" "ls /dev/spidev*"
chk "SPI off (no spidev; GPIO7 free for DPi)" "! ls /dev/spidev*"
chk "/dev/serial0 -> ttyAMA0" "[ \"\$(readlink -f /dev/serial0)\" = /dev/ttyAMA0 ]"
chk "serial login console off" "! systemctl is-active --quiet serial-getty@ttyAMA0.service"
chk "avahi listening on 5358" "ss -lun | grep -q ':5358'"
chk "avahi NOT on 5353" "! ss -lun | grep -q ':5353'"
# The eth0 static (172.17.21.2) only activates when the link has carrier. Running
Expand Down
Loading