- C 67.6%
- Python 25%
- Nix 3.9%
- CMake 2.6%
- Shell 0.9%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| cmake | ||
| docs | ||
| packaging | ||
| prompts | ||
| python | ||
| scripts | ||
| src | ||
| tests | ||
| third_party | ||
| .clang-format | ||
| .gitignore | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CMakeLists.txt | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
epaperd
epaperd is a daemon that drives a multi-panel e-paper display over
USB. Four IT8951 controllers and a Good Display panel hang
off a Raspberry Pi Zero; producers (clock, status display, Game of
Life, …) connect over a Unix socket and the daemon composites their
surfaces into one framebuffer, pushing only the changed regions to the
hardware.
This repository also keeps it8951, the original single-shot CLI for
talking to one IT8951 controller. It stays around as a hardware
debugging utility.
The daemon is being built up prompt-by-prompt — see prompts/. Today's
deliverable is the build/deploy/CI scaffolding; the daemon itself is a
stub.
Installing
On Debian / Raspberry Pi OS, grab the two .deb files from the release
page and install them. The daemon binary is statically linked (musl), so
epaperd pulls in no runtime dependencies. The Python package depends on
python3 and python3-numpy, which apt resolves automatically.
$ sudo dpkg -i epaperd_<ver>_arm64.deb # arm64 / aarch64 Pi
$ sudo dpkg -i python3-epaper_<ver>_all.deb # same file for every arch
$ sudo usermod -aG epaper "$USER" # log out + back in to take effect
The daemon starts automatically on install and on every boot — no manual
systemctl enable needed.
On NixOS, add the flake and set services.epaperd.enable = true;.
Configuration lives in /etc/epaperd.conf (created with defaults on
first install, never overwritten by upgrades). The shipped default has
every key documented inline — open it to see what's tunable. Full
reference is in docs/config.md.
Full install instructions — package matrix, NixOS module options, building
the .debs yourself — are in docs/install.md.
Running a producer
Example producers live in python/examples/ inside the source tarball
(also on the release page). Unpack the tarball, then run any example
directly — they connect to the daemon's socket and exit cleanly on
Ctrl-C:
$ tar xf epaperd-<ver>.tar.gz
$ cd epaperd-<ver>/python/examples
# clock overlay — updates once per second, transparent background
$ python3 clock_overlay.py
# Conway's Game of Life — fills the whole display
$ python3 gol.py
# custom socket path if needed
$ python3 clock_overlay.py --socket /run/epaperd/socket
The --socket option defaults to /run/epaperd/socket, which is where
the systemd unit listens. Multiple producers can run simultaneously; the
daemon composites their surfaces by z-order.
Building
The dev loop is edit on your laptop, cross-compile, ship to the Pi. Native builds also work for local testing.
Native (Nix, recommended)
$ nix build .#default
$ ./result/bin/it8951 -v
Or drop into a dev shell and use cmake directly:
$ nix develop
$ cmake -S . -B build
$ cmake --build build
$ ./build/src/it8951/it8951 -v
Cross-build (Nix)
Three musl-static targets — each output is a single self-contained ELF with libc, libusb, and libudev baked in. No runtime deps on the Pi.
| Target | For |
|---|---|
cross-armv6l |
Pi Zero (original), Pi 1 |
cross-aarch64 |
Pi Zero 2W, Pi 3 / 4 / 5 |
cross-x86_64-v3 |
Modern x86_64 (Haswell or later) |
$ nix build .#cross-aarch64
$ file result/bin/it8951
# ELF 64-bit LSB executable, ARM aarch64, ... statically linked, ...
Deploying to a host
$ EPAPERD_PI=epaper.local scripts/deploy.sh
# or
$ scripts/deploy.sh epaper.local
The script probes the host's uname -m, picks the matching cross
target, cross-builds, scps it8951 to /tmp/, and runs it8951 -v to
confirm the binary loads.
Running it8951
Clear the display
$ sudo it8951 -c -m 0 /dev/sdb 0 0 800 600
Send an 8-bit grayscale image
$ sudo it8951 /dev/sdb 0 0 800 600 < image.raw
Generate an image and display it
$ convert -background white -fill black \
-font Ubuntu -pointsize 50 label:"$(date)" \
-gravity Center -extent 800x600 \
-depth 8 gray:- \
| sudo it8951 -d -m 2 /dev/sdb 0 0 800 600
Draw an image in A2 (fast 1-bit) mode
$ sudo it8951 -m 4 /dev/sdb 0 0 800 600 < image.raw
See docs/development.md for the full dev workflow.