2026-07-19 19:23:51 -04:00
2026-07-19 19:23:51 -04:00
2026-07-19 19:23:51 -04:00
2026-07-19 19:23:51 -04:00
2026-07-19 19:23:51 -04:00
2026-07-20 16:34:19 -04:00
2026-07-19 19:23:51 -04:00

xteink-web-emulator

An offline, in-browser emulator for the xteink X3/X4 (ESP32-C3 + e-ink): upload a firmware .bin, run the real machine code client-side, see the screen, press buttons, mount a virtual SD — no server, no proprietary engine.

Status: native and WebAssembly builds provide one xteink machine that selects X3 or X4 at launch. Unmodified canonical firmware auto-detects the selected variant: X3 boots with its UC8253 display and SD card; X4 reaches its SSD1677 driver through a blank protocol stub. A basic static browser UI now loads local firmware, renders the panel, and drives the physical buttons. See ROADMAP.md for architecture and plan.

Quick start (native QEMU)

git clone --recursive https://github.com/crosspoint-reader/crosspoint-reader ../crosspoint-reader
# Build ../crosspoint-reader's PlatformIO `default` environment first.
nix develop
make qemu             # clone espressif/qemu @ pinned commit, apply patch, build
make firmware sdimage # 16 MB flash.bin + FAT32 sd.img from the PlatformIO build
make run              # X3 (default)
make run VARIANT=x4   # X4 detection + blank SSD1677 stub

Point at a firmware build with make firmware FIRMWARE_DIR=/path/to/.pio/build/gh_release. make qemu is a long compile on modest hardware — set JOBS to taste.

WebAssembly build

Podman or Docker is required. The QEMU source is the third_party/qemu submodule, so initialize it first:

git submodule update --init third_party/qemu

The build is limited to riscv32-softmmu and the X3/X4 device graph; networking, audio, virtfs, tools, docs, and unrelated boards are disabled.

make qemu-wasm
# dist/wasm/qemu-system-riscv32.{js,wasm,worker.js} + esp32c3-rom.bin

The build runs Node smoke checks when Node is available.

Browser interface

make web
# Open http://127.0.0.1:8000/web/

Choose a CrossPoint firmware .bin — either the ~5 MB release app image (it is merged in-browser with the bundled bootloader and partition table into a 16 MB flash) or a full 16 MB image — select X3 or X4, and boot. The controls map to the device's ADC button ladders and active-low Power GPIO. make web serves the required COOP/COEP headers for Emscripten pthreads; a generic static server without those headers will not work.

Real firmware boots in WASM and drives the X3 panel (528×792). Browser SD files are persisted in OPFS and edited in the Files tab. At boot, the browser builds a 64 MiB raw FAT32 image with nested-directory and VFAT long-name support; QEMU mounts that image directly, avoiding vvfat. Choose Apply & reboot to expose edits to the guest. Guest writes modify only the ephemeral image. The Debug tab reports committed WASM heap, visible MEMFS data, and browser JS heap where supported. X4 remains a white display stub.

Contents

  • qemu/patches/0001-xteink-machine.patch — the xteink,variant=x3|x4 machine and its device models (I²C fingerprints, ADC, GPIO, SPI2, X3 UC8253, X4 panel stub, SD-over-SPI fix), applied onto the pinned espressif/qemu commit by scripts/build-qemu.sh.
  • third_party/qemu — submodule of the xteink QEMU fork (espressif/qemu + the machine models + the wasm32 TCG backend), built for the browser by scripts/build-qemu-wasm.sh. Edit it in place; make web recompiles incrementally. qemu/wasm/Dockerfile is the pinned Emscripten dependency environment.
  • flake.nix — the espressif-qemu release binary as the fast generic baseline (nix run .#run-upstream -- flash.bin), plus a devShell with QEMU's full build environment. Makefileqemu, firmware, sdimage, run, chip.
  • web/fat32.js and web/sdstore.js — dependency-free FAT32 image generation and persistent OPFS file storage.
  • scripts/mksd.sh — build a FAT32 SD backing image for native QEMU.
  • tests/make test runs JS/FAT32 checks; make browser-test boots the official CrossPoint 1.4.1 firmware and navigates to Test/example.txt in headless Firefox.
  • chip/eink-x3.chip.c — the reverse-engineered X3 e-ink protocol, first written as a Wokwi chip and now the reference for the QEMU display device. make -C chip test runs its host self-check.

Why not Wokwi

Wokwi runs any bin in a browser and we had the e-ink chip working — but its simulation engine is proprietary and gated behind a license/service, so it can't be self-hosted or run airgapped. QEMU is the open path; the e-ink protocol work carried straight over.

S
Description
No description provided
Readme 781 KiB
Languages
JavaScript 43.2%
C 14%
Python 12.7%
CSS 7%
Shell 6.9%
Other 16.2%