Standardized checklist for version bumps, tagging, post-release verification, and hotfix workflow. Moves inline release steps from BUILDING.md into dedicated RELEASING.md.
5.9 KiB
Ratdeck — Build & Flash Reference
Prerequisites
- Python 3.x with PlatformIO:
pip install platformio - Git
- USB-C cable (data-capable)
No USB drivers needed on macOS or Linux — the ESP32-S3's USB-Serial/JTAG interface is natively supported.
If
piois not on your PATH after install, usepython3 -m platformiofor all commands in this document.
Build
git clone https://github.com/ratspeak/ratdeck.git
cd Ratdeck
python3 -m platformio run
Output: .pio/build/ratdeck_915/firmware.bin
First build downloads all dependencies automatically (microReticulum, Crypto, ArduinoJson, LovyanGFX, NimBLE-Arduino, LVGL).
Flash
Via PlatformIO
python3 -m platformio run --target upload
Via esptool (more reliable)
PlatformIO defaults to the upload speed in platformio.ini (460800 baud). If flashing fails, use esptool directly:
python3 -m esptool --chip esp32s3 --port /dev/cu.usbmodem* --baud 460800 \
--before default-reset --after hard-reset \
write-flash -z 0x10000 .pio/build/ratdeck_915/firmware.bin
Download Mode
If the device doesn't respond to flash commands, enter download mode:
- Hold the trackball (BOOT/GPIO 0) button
- While holding, press the reset button
- Release both — device enters bootloader mode
- Flash as normal
Web Flash
Visit ratspeak.org/download to flash directly from your browser using WebSerial — no build tools required.
Creating a Merged Binary
A merged binary includes bootloader + partition table + app in one file:
python3 -m esptool --chip esp32s3 merge-bin \
--output ratdeck_merged.bin \
--flash-mode dio --flash-size 16MB \
0x0 ~/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32s3/bin/bootloader_dio_80m.bin \
0x8000 .pio/build/ratdeck_915/partitions.bin \
0xe000 ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
0x10000 .pio/build/ratdeck_915/firmware.bin
python3 -m esptool --chip esp32s3 --port /dev/cu.usbmodem* --baud 460800 \
--before default-reset --after hard-reset \
write-flash 0x0 ratdeck_merged.bin
Serial Monitor
python3 -m platformio device monitor -b 115200
Or any serial terminal at 115200 baud.
USB Port Identification
The T-Deck Plus ESP32-S3 uses USB-Serial/JTAG (not a separate UART chip):
| OS | Port | Notes |
|---|---|---|
| macOS | /dev/cu.usbmodem* |
Use glob to match |
| Linux | /dev/ttyACM0 |
May need dialout group |
On Linux: sudo usermod -aG dialout $USER (log out and back in).
Build Flags
From platformio.ini:
| Flag | Purpose |
|---|---|
-std=gnu++17 |
C++17 standard |
-fexceptions |
C++ exceptions (required by microReticulum) |
-DRATDECK=1 |
Main feature flag |
-DARDUINO_USB_CDC_ON_BOOT=1 |
USB CDC serial on boot |
-DARDUINO_USB_MODE=1 |
USB-Serial/JTAG mode (not native CDC) |
-DRNS_USE_FS |
microReticulum: use filesystem for persistence |
-DRNS_PERSIST_PATHS |
microReticulum: persist transport paths |
-DMSGPACK_USE_BOOST=OFF |
Disable Boost dependency in MsgPack |
-DBOARD_HAS_PSRAM |
Enable 8MB PSRAM |
-DDISPLAY_WIDTH=320 |
Display width |
-DDISPLAY_HEIGHT=240 |
Display height |
-DLV_CONF_INCLUDE_SIMPLE |
LVGL config via root lv_conf.h |
"-I${PROJECT_DIR}" |
Required for LVGL to find root lv_conf.h |
build_unflags = -fno-exceptions -std=gnu++11 removes Arduino defaults.
Partition Table
partitions_16MB.csv — 16MB flash layout with OTA support:
| Name | Type | Offset | Size | Purpose |
|---|---|---|---|---|
| nvs | data/nvs | 0x9000 | 20 KB | Non-volatile storage (boot counter, WiFi creds) |
| otadata | data/ota | 0xE000 | 8 KB | OTA boot selection |
| app0 | app/ota_0 | 0x10000 | 4 MB | Primary firmware |
| app1 | app/ota_1 | 0x410000 | 4 MB | OTA update slot |
| littlefs | data/spiffs | 0x810000 | 7.875 MB | LittleFS — identity, config, messages, paths |
| coredump | data/coredump | 0xFF0000 | 64 KB | ESP-IDF core dump on crash |
CI/CD
GitHub Actions workflow (.github/workflows/build.yml):
- Build: Triggers on push to
mainand PRs. Runspio run, uploadsfirmware.binas artifact. - Release: Triggers on
v*tags. Builds firmware, creates a GitHub Release with the binary ZIP attached. Powers the web flasher at ratspeak.org/download.
Release Process
See RELEASING.md for the full release protocol (version bump, tagging, post-release verification, hotfix workflow).
Dependencies
All managed by PlatformIO's lib_deps:
| Library | Source | Purpose |
|---|---|---|
| microReticulum | attermann/microReticulum#392363c |
Reticulum protocol stack (C++) |
| Crypto | attermann/Crypto |
Ed25519, X25519, AES, SHA-256 |
| ArduinoJson | bblanchon/ArduinoJson ^7.4.2 |
Config and message serialization |
| LovyanGFX | lovyan03/LovyanGFX ^1.1.16 |
SPI display driver |
| NimBLE-Arduino | h2zero/NimBLE-Arduino ^2.1 |
BLE Sideband transport |
| LVGL | lvgl/lvgl ^8.3.4 |
UI framework (v8.4) |
Erasing Flash
To completely erase the ESP32-S3 flash (useful if LittleFS is corrupted):
python3 -m esptool --chip esp32s3 --port /dev/cu.usbmodem* erase-flash
After erasing, reflash the firmware. LittleFS will auto-format on first boot and a new identity will be generated.
Common Errors
| Error | Cause | Fix |
|---|---|---|
Could not open port |
Device not connected or wrong port | Check USB cable, try /dev/cu.usbmodem* glob |
Timed out waiting for packet header |
Baud rate too high | Use --baud 460800 with esptool |
| Serial disconnects mid-flash | Unstable USB connection | Enter download mode (hold trackball + reset) |
No module named platformio |
PlatformIO not installed | pip install platformio |
pio: command not found |
Not on PATH | Use python3 -m platformio instead |