Public Access
- New native environment: pio test -e native - test/mocks: fake Arduino core, EEPROM and recording BROSE9323 driver - test/test_nano: 25 tests covering every command, bitmaps, bad input, flip time storage and the periodic full redraw - Board environments ignore tests so they are never uploaded Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
4.1 KiB
Markdown
70 lines
4.1 KiB
Markdown
# Flipdot display: notes for Claude
|
||
|
||
A PlatformIO project with two firmware targets for an 84×19 Brose flipdot clock.
|
||
See README.md for the overview.
|
||
|
||
## Layout and build
|
||
|
||
- `platformio.ini` has the environments `nano`, `esp32` (OTA to 10.1.1.198) and
|
||
`esp32_usb` (COM11). The sources are split with `build_src_filter` (`src/nano/`,
|
||
`src/esp32/`).
|
||
- `lib/BROSE9323/` is the shared driver. Its behaviour depends on build flags set in
|
||
`platformio.ini`, not in the header:
|
||
- `ESPSERIAL` (ESP32): draw calls become serial commands.
|
||
- `FLIPDOT_PLCC_ADAPTER` (Nano, optional): alternative pinout.
|
||
- PlatformIO CLI is not on PATH. Run `~/.platformio/penv/Scripts/pio.exe run` (Git Bash)
|
||
or `$env:USERPROFILE\.platformio\penv\Scripts\pio.exe run` (PowerShell).
|
||
- If an ESP32 build fails with `No module named 'intelhex'`, run
|
||
`~/.platformio/penv/Scripts/python.exe -m pip install intelhex`.
|
||
- After any change, build both targets (`pio run`). After Nano changes, also run
|
||
`pio test -e native`.
|
||
|
||
## Constraints
|
||
|
||
- **Nano RAM is tight** (ATmega328P, 2 KB). The frame buffers are allocated with
|
||
`calloc`. Avoid `String`, large stack buffers and new globals in Nano code. Put constant
|
||
data in `PROGMEM`.
|
||
- The ESP32 talks to the Nano on `Serial2` (`nanoSerial` in `libs.h`, GPIO 17 TX / GPIO 16
|
||
RX). `Serial` (UART0/USB) is free for debug output. Never write debug text to
|
||
`nanoSerial`: the Nano runs lines that start with s/S/F/D/P/B/R/T as commands.
|
||
- Open hardware TODOs are listed in the README `TODO` section. Update it when one is done.
|
||
- `src/esp32/secrets.h` holds the real credentials and is gitignored. Never commit it.
|
||
Add new secrets to `secrets.example.h` as placeholders.
|
||
- The relay (ESP32 GPIO 13, `LOW` = on) powers both the panels and the Nano. Each time it
|
||
switches on, the Nano cold-boots and then sends `READY`. The ESP's `relayOn()` waits for
|
||
that message, at most `NANO_BOOT_TIMEOUT`. The timeout also covers the case where the
|
||
Nano's TX isn't wired to the ESP's RX.
|
||
- `relayOff()` ends `nanoSerial` and sets its TX pin to input. Otherwise the idle-high TX line
|
||
powers the Nano through its RX pin. Never send display commands while `relay_on` is
|
||
false.
|
||
- The Nano keeps no state over a power cycle except the flip time in EEPROM. The driver
|
||
forces a full redraw on the first `display()` after boot (`_force_next`).
|
||
- Hardware is not available here. Builds can be checked, but runtime behaviour can't.
|
||
|
||
## Nano serial parser (`src/nano/main.cpp`)
|
||
|
||
- Files: `main.cpp` (setup/loop, refresh), `config.h` (all constants and debug
|
||
defines), `command_parser.*` (protocol, one method per command), `settings.*` (EEPROM).
|
||
- Line based and non-blocking: bytes are collected into a 64-character buffer and a
|
||
command runs when `\n` arrives. Bitmap (`B`) pixel data is the exception. It is drawn
|
||
while it arrives, so it can be longer than the buffer. Keep `loop()` free of busy-waits.
|
||
- A full redraw (`display(true)`) blocks for about 0.5 s, which overflows the 64-byte
|
||
serial receive buffer. Only run it when no data is expected: right after a `D`, or after
|
||
2 s with no serial data. The ESP sends one frame per second, ending with `D`.
|
||
- Flip time is stored in EEPROM as a magic word at address 0 and a `uint16_t` at
|
||
address 2. Values outside 50–2000 µs are rejected.
|
||
- The Nano only replies `READY` (at boot) and `ERR: ...`. There is no per-frame
|
||
acknowledgement. Whether the Nano's TX is wired to the ESP's RX is unconfirmed, so every
|
||
wait for a reply needs a timeout.
|
||
- Unit tests: `pio test -e native` runs `test/test_nano/` on the PC with the fakes in
|
||
`test/mocks/` (Arduino, EEPROM, and a `BROSE9323` that records calls). It needs gcc on
|
||
PATH (Strawberry Perl provides it at `C:\Strawberry\c\bin`). Add a test for every
|
||
protocol change. The mocks only implement what the Nano code uses, so extend them when
|
||
new Arduino or driver functions are called.
|
||
- The board environments have `test_ignore = *`, so test firmware is never uploaded. Plain
|
||
`pio test` runs nothing; always pass `-e native`.
|
||
|
||
## Git
|
||
|
||
- Remote: https://mangavalk.com/mangavalk/Flipdot-display.git, branch `main`.
|