Files
socktop-swipe/notes/HARDWARE-NOTES.md
T
jasonwitty ad8ebcaa71 docs: record the LattePanda deployment and the traps it turned up
The rack display has been running v2 since today and passed a physical swipe
test and a cold boot, so the hardware table now says what is actually in
service and what is merely intended: the Wyse 3040 has not been tried yet and
should not read as though it has.

notes/HARDWARE-NOTES.md gains the two traps that cost the most time during the
deployment, both of which will recur:

lightdm autologin fires when a seat starts, not after a logout, so `i3-msg
exit` does not test the autostart -- it strands a keyboard-less wall display at
a greeter that nobody standing at the rack can get past. Only a real reboot
tests the boot path.

And `ssh host 'sudo ...'` allocates no TTY, so sudo has nowhere to prompt and
fails; chaining the rest of the recovery behind `&&` then swallows it silently.
Use `ssh -t`, and `;` for steps that must run regardless.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 14:03:30 -07:00

5.2 KiB

Hardware notes

Things about specific hardware that cost time to work out. Kept out of the README because they are not install steps.

Screen size and rack size are different measurements

Three numbers get confused because they all describe "how big":

  • 9 inch — the GeeekPi touchscreen itself, 1280x720.
  • 10 inch — the mini-rack standard its bracket is made for.
  • 19 inch — the standard equipment rack, which is what cad/ adapts it to.

So "a 9-inch screen on a 10-inch mount, adapted to a 19-inch rack" is three correct numbers, not a contradiction. The README uses the screen size when talking about the panel and the rack size when talking about the adapter.

The ILITEK panel reports 2-3 contacts for one finger

A physically one-finger swipe arrives as two, sometimes three, simultaneous contacts. In v1 this was the single most expensive failure: lisgd detected the direction correctly every time and then rejected it on Cfg(f=1) <=> Evt(f=2), which reads as noise unless you know what it means.

touch.fingers: [1, 2, 3] accepts all three. socktop-swipe doctor now reports it in English, and the travel is averaged across contacts rather than summed — otherwise a ghost-contact panel looks like it swiped three times as far.

Phantom display outputs (LattePanda DSI-1)

The LattePanda's onboard DSI header shows up as DSI-1 connected 1024x600 with zero EDID bytes (xrandr reports 0mm x 0mm), and X happily puts workspace 1 on it. Everything then looks healthy over ssh — the window is fullscreen on the primary output — while the real panel shows an empty workspace.

xrandr | grep ' connected'      # a real panel has physical mm; phantoms say 0mm x 0mm
for c in /sys/class/drm/card0-*; do echo "$c $(cat "$c"/status) edid=$(wc -c <"$c"/edid)"; done

Fix, adjusting the names:

sudo tee /etc/X11/xorg.conf.d/20-outputs-socktop-swipe.conf >/dev/null <<'EOF'
Section "Monitor"
    Identifier "DSI-1"
    Option     "Ignore" "true"
EndSection
Section "Monitor"
    Identifier "HDMI-2"
    Option     "Primary" "true"
EndSection
EOF

Then set touch.width/touch.height to the real panel's mode. On the LattePanda that is 1280x720, not the 1024x600 the phantom claims.

sudo xset silently does nothing

xset talks to the X connection of the user running it, so sudo xset s off targets root's X connection and succeeds while changing nothing for your session. A sudo bash noblank.sh wrapper looks like it worked and blanking stays armed. It must run as the session user.

Also: xset is per-session and dies on reboot. The durable fix is the Xorg ServerFlags snippet with all four timeouts at 0 — which also covers the display manager's greeter — plus an xset line in the session autostart, because a session can re-enable the screensaver after X starts. Both, not either.

Check the real state:

xset q | grep -A1 -E 'Screen Saver|DPMS'   # want timeout 0, prefer blanking no, DPMS Disabled

Panel resolution is not the X screen size

With a second display attached, X reports the combined root window (e.g. 2304x720). touch.width/touch.height must describe the touch panel alone or the edge and distance maths is scaled to the wrong thing. v1 hit this because lisgd asks X when not told; v2 always requires the values in the config.

LattePanda specifics

Atom x5-Z8350 @ 1.44 GHz, 1.9 GB RAM, Cherry Trail Gen8 graphics, Debian 11, i3 on X11. Binaries in ~/.cargo/bin, which is not on the PATH that i3 or a non-login ssh gives you — hence the binaries: block in the config.

Memory is the binding constraint. Prefer the lightweight option and count processes; reach for tmux pane zoom rather than duplicate program instances. A Wayland compositor with native touch gestures is not an answer here: Hyprland is not packaged in Debian, so it means a source build on a 1.44 GHz Atom, and it would not help anyway — libinput emits no gesture events for touchscreens on any version, so a raw-touch reader is required regardless.

Wyse 3040

Same silicon as the LattePanda (Atom x5-Z8350, Cherry Trail), so the stack is already validated. Differences: 8/16 GB soldered eMMC and no M.2, so a minimal Debian netinst and a careful eye on disk; DisplayPort out, so a DP-to-HDMI adapter for the panel; roughly 3-4 W idle, 101x101x28 mm, VESA holes.

The eMMC is why the installer checks free space before starting a build: a Rust toolchain plus a target directory is around 1.8 GB.

Never log out of a keyboard-less wall display

lightdm autologin fires when a seat starts, not after a logout. i3-msg exit therefore drops the display to the greeter and leaves it there — and the rack panel has no keyboard, so nobody can log back in at the machine. Recovering it needs sudo systemctl restart lightdm or a reboot, and the LattePanda has no passwordless sudo.

So: i3-msg exit does not test the autostart, it only strands the box. The only honest test of the boot path is an actual reboot.

Related trap when handing over a root command: ssh host 'sudo …' allocates no TTY, so sudo has nowhere to prompt and fails. Use ssh -t. Chaining with && then swallows the rest of the line, which is how a recovery command silently did nothing at all. Use ; for recovery steps that must run regardless.