| name | flash |
| description | Build, flash, and monitor the eink-screen firmware on the LilyGo T5 ePaper S3 PRO, with recovery for the recurring USB-port-drop and wrong-port-auto-detect gotchas and a serial-capture recipe. TRIGGER when the user wants to build/compile, upload/flash, or watch serial for this firmware ("flash it", "upload", "build and run", "check the serial log", "why won't it flash"). DO NOT trigger for editing the display layout (that's HelmLog / `/preview`) or for pure code questions. |
/flash — build, flash, monitor
The build/flash commands and the display/flashing gotchas are in AGENTS.md;
this skill is the operational runbook for getting firmware onto the board
when the native USB-CDC port misbehaves.
Normal path
pio run
pio run -t upload --upload-port /dev/cu.usbmodem2101
Always pass --upload-port. esptool auto-detect regularly grabs the wrong
/dev/cu.* (e.g. Bluetooth headphones) and fails with "No serial data
received".
When the port is missing / upload can't open it
ls /dev/cu.usbmodem* shows nothing, or upload says "port doesn't exist / busy".
- If a serial monitor is open, close it (it holds the port).
- Ask the user to re-plug the USB-C cable, or enter download mode:
hold BOOT, tap RST, release BOOT.
- Re-check
ls /dev/cu.usbmodem*, then retry the upload with --upload-port.
The port dropping right after a Hard resetting via RTS pin is normal for this
board — it re-enumerates. Don't over-debug it; just recover the port.
Reading serial reliably
pio device monitor needs a TTY and fails when run headless/scripted. Capture
with a reconnecting pyserial reader instead (firmware Serial is on USB CDC):
import serial, time
deadline = time.time() + 30
while time.time() < deadline:
try: s = serial.Serial('/dev/cu.usbmodem2101', 115200, timeout=0.3)
except Exception: time.sleep(0.2); continue
try:
while time.time() < deadline:
line = s.readline().decode('utf-8','replace').rstrip()
if line: print(line)
except Exception: pass
finally:
try: s.close()
except Exception: pass
Run it with PlatformIO's Python so pyserial is available:
/Users/dweatbrook/.local/share/uv/tools/platformio/bin/python.
Do not toggle DTR/RTS to "reset" — the wrong pattern drops the board into
download mode (waiting for download) instead of running the firmware. To catch
a clean boot, start the reader and have the user tap RST (only RST).
What a healthy boot looks like
[HelmLog e-paper display]
E epdiy: cache line size 32 (<64B) … Reducing pixel clock … 5 MHz <- harmless
[epd] 960x540 framebuffer=0x...
[wifi] trying <ssid> ... joined ... probing <host>:3002
[wifi] <ssid>: HelmLog reachable -> using it
[http] frame ok; refresh=Ns full=Ns
If you see i2c driver install error, something called Wire.begin() — the
panel won't power on. Remove it (see AGENTS.md).
First-build environment notes
PlatformIO here runs under a uv-installed Python; if tool-esptoolpy install
fails for lack of pip, bootstrap it once:
/Users/dweatbrook/.local/share/uv/tools/platformio/bin/python -m ensurepip --upgrade.
The usc1.contabostorage.com package CDN sometimes TLS-blocks but resolves via
mirror fallback — retry rather than abort.