475 lines
15 KiB
Markdown
475 lines
15 KiB
Markdown
# RFP Infinity Flashing
|
|
|
|
This document covers the two production firmware targets for the Infinity installation.
|
|
There is intentionally no separate `coldboot` firmware anymore: the reliable N16R8
|
|
boot settings are part of the normal master and node targets.
|
|
|
|
## Targets
|
|
|
|
- Master target: `rfp_esp32s3_wroom1_n16r8_master`
|
|
- Node target: `rfp_esp32s3_wroom1_n16r8_3x106`
|
|
|
|
## Firmware Release Names
|
|
|
|
These names are compiled into the firmware as `WLED_RELEASE_NAME` and show up in
|
|
WLED update metadata, OTA validation, serial boot logs, and `/json/info`.
|
|
|
|
- Master: `RFP_N16R8_MASTER_V20260511E`
|
|
- Node: `RFP_N16R8_NODE3x106_V20260511E`
|
|
|
|
Both targets use the same robust ESP32-S3-WROOM-1 N16R8 boot configuration:
|
|
|
|
- Flash: QIO / 16 MB
|
|
- Flash frequency: 80 MHz
|
|
- PSRAM: OPI / 8 MB octal
|
|
- Partition table: `tools/WLED_ESP32_16MB.csv`
|
|
- USB CDC on boot: disabled
|
|
- Boot delay: `WLED_BOOTUPDELAY=1200`
|
|
|
|
## Clean-Flash Warning
|
|
|
|
`erase_flash` removes the complete flash contents, including WLED's saved
|
|
`cfg.json`, Wi-Fi credentials, static IP settings, presets, and filesystem data.
|
|
|
|
The RFP master and node targets compile the show Wi-Fi as firmware defaults:
|
|
|
|
- SSID: `RFPLicht`
|
|
- Password: configured in the RFP build flags
|
|
|
|
After a full erase the board can therefore join Wi-Fi again, but runtime-only
|
|
settings that were stored through the WLED UI must be re-applied unless they are
|
|
also encoded as firmware defaults.
|
|
|
|
## Roles
|
|
|
|
- Master:
|
|
- Usually `192.168.178.10`
|
|
- Runs the `/infinity` web UI
|
|
- Accepts DMX and web commands
|
|
- Sends Infinity Sync packets to the nodes
|
|
- Keeps one dummy WLED pixel on `GPIO21` so the regular WLED UI remains valid
|
|
- Keeps the real WLED status pixel exclusively on `GPIO48`
|
|
- Nodes:
|
|
- Usually `192.168.178.11` to `192.168.178.16`
|
|
- Render the LED output locally
|
|
- Receive Infinity Sync from the master
|
|
- Use three LED outputs: `GPIO4/5/6`, each with `106` LEDs
|
|
|
|
## Build: Master
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_master
|
|
```
|
|
|
|
Master firmware output:
|
|
|
|
```text
|
|
.pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin
|
|
build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin
|
|
```
|
|
|
|
## Build: Nodes
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_3x106
|
|
```
|
|
|
|
Node firmware output:
|
|
|
|
```text
|
|
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
|
build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_NODE3x106_V20260511E.bin
|
|
```
|
|
|
|
## Recommended Update: Master USB First, Nodes Via Master
|
|
|
|
Use this for normal show updates. The laptop only needs USB access to the
|
|
master; it does not need to join the RFP Wi-Fi. The workflow is:
|
|
|
|
1. Build master and node firmware locally.
|
|
2. Flash the master app by USB.
|
|
3. Hard-reset the master and verify its RFP release over the serial relay.
|
|
4. Stream node OTA updates through the master to nodes `.11` to `.16`.
|
|
|
|
The master USB flash deliberately does **not** run `erase_flash` and does
|
|
**not** run `uploadfs`. This avoids rewriting the large LittleFS area during a
|
|
normal firmware update and keeps runtime config/filesystem data intact.
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0
|
|
```
|
|
|
|
Use existing build artifacts without rebuilding:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0 --no-build
|
|
```
|
|
|
|
Resume node updates after a failure:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0 --no-build --nodes-only --start-from 192.168.178.14
|
|
```
|
|
|
|
Flash only the master with the same safe USB app-flash path:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
./flash_master.sh
|
|
```
|
|
|
|
`flash_master.sh` is now intentionally an app/bootloader/partition update only:
|
|
no full erase and no filesystem upload. Use a full clean flash only when the
|
|
partition table or filesystem must be deliberately reset.
|
|
|
|
## USB App Flash: Master
|
|
|
|
Recommended helper:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
./flash_master.sh
|
|
```
|
|
|
|
Manual flow:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
|
|
|
PORT=/dev/ttyACM0
|
|
ENV=rfp_esp32s3_wroom1_n16r8_master
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio run -e "$ENV"
|
|
|
|
.venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
|
--chip esp32s3 \
|
|
--port "$PORT" \
|
|
--baud 460800 \
|
|
--before default_reset \
|
|
--after hard_reset \
|
|
write_flash -z \
|
|
--flash_mode qio \
|
|
--flash_freq 80m \
|
|
--flash_size 16MB \
|
|
0x0 .pio/build/rfp_esp32s3_wroom1_n16r8_master/bootloader.bin \
|
|
0x8000 .pio/build/rfp_esp32s3_wroom1_n16r8_master/partitions.bin \
|
|
0xe000 .piohome/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
|
|
0x10000 build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin
|
|
```
|
|
|
|
If upload does not start immediately:
|
|
|
|
1. Hold `BOOT`
|
|
2. Tap `RESET`
|
|
3. Release `BOOT`
|
|
4. Run the upload again
|
|
|
|
## USB Clean Flash: Node
|
|
|
|
Recommended helper:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
./flash_node.sh
|
|
```
|
|
|
|
Manual flow:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
|
|
|
PORT=/dev/ttyACM0
|
|
ENV=rfp_esp32s3_wroom1_n16r8_3x106
|
|
|
|
.venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
|
--chip esp32s3 \
|
|
--port "$PORT" \
|
|
erase_flash
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio run -e "$ENV" -t clean
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio run -e "$ENV" -t upload --upload-port "$PORT"
|
|
```
|
|
|
|
## OTA Preflight
|
|
|
|
Check whether the current devices look OTA-updatable before flashing:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --preflight-only --no-build
|
|
```
|
|
|
|
Single node:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_network_flash.py flash \
|
|
--targets 192.168.178.11 \
|
|
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin \
|
|
--expect-release RFP_N16R8_NODE3x106_V20260511E \
|
|
--preflight-only
|
|
```
|
|
|
|
## OTA Update: Whole Installation From RFP Wi-Fi
|
|
|
|
This builds locally and flashes nodes `.11` to `.16` first, then the master `.10`.
|
|
The master is flashed last so the show controller stays available while the nodes
|
|
update.
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py
|
|
```
|
|
|
|
If your PC is not connected to the RFP Wi-Fi and the master is already on the
|
|
right release, keep the master connected by USB and let the master relay node
|
|
OTA updates through its own Wi-Fi connection:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --via-master-usb --port /dev/ttyACM0 --no-build
|
|
```
|
|
|
|
This node-only relay is still useful for resumes and tests. For full updates,
|
|
prefer `tools/rfp_update_master_usb_then_nodes.py` so the master is flashed and
|
|
verified first. The relay streams the node firmware through the master and does
|
|
not store the full file on the master filesystem. The default relay baud rate is
|
|
`921600` for faster node updates; opening `/dev/ttyACM0` can reset the ESP32-S3,
|
|
so the tool waits briefly before sending commands. If a flaky USB cable or hub
|
|
causes serial errors, retry with `--relay-baud 115200`.
|
|
|
|
The updater prefers the named release binaries from `build_output/release/` when
|
|
they exist and verifies the expected RFP release name after reboot:
|
|
|
|
- Nodes: `RFP_N16R8_NODE3x106_V20260511E`
|
|
- Master: `RFP_N16R8_MASTER_V20260511E`
|
|
|
|
During the controlled migration from older generic WLED-MM builds, the updater
|
|
sends WLED's `skipValidation=1` upload parameter by default. The update is still
|
|
accepted only if the target reboots and then reports the expected RFP release
|
|
name in `/json/info`.
|
|
|
|
If you explicitly want WLED's release-name validation to block mismatches before
|
|
upload, use:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --no-skip-validation
|
|
```
|
|
|
|
Use existing build artifacts without rebuilding:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --no-build
|
|
```
|
|
|
|
Devices that already report the selected RFP release are skipped by default.
|
|
This avoids reflashing the same binary and then trying to prove an update from
|
|
an unchanged release string. To force reflashing the same release anyway:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --no-build --force-current-release
|
|
```
|
|
|
|
Resume from a failed device:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_update_all_ota.py --no-build --start-from 192.168.178.14
|
|
```
|
|
|
|
## OTA Update: Single Device
|
|
|
|
Master:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_network_flash.py flash \
|
|
--targets 192.168.178.10 \
|
|
--firmware build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin \
|
|
--expect-release RFP_N16R8_MASTER_V20260511E \
|
|
--skip-validation
|
|
```
|
|
|
|
Node:
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
.venv/bin/python tools/rfp_network_flash.py flash \
|
|
--targets 192.168.178.11 \
|
|
--firmware build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_NODE3x106_V20260511E.bin \
|
|
--expect-release RFP_N16R8_NODE3x106_V20260511E \
|
|
--skip-validation
|
|
```
|
|
|
|
## Why OTA Can Fail After Build Success
|
|
|
|
OTA updates only the application image. It does not reliably replace bootloader,
|
|
flash mode, or partition table. If a board still has an old partition layout, do
|
|
one USB clean flash with the production target first. After that, OTA should be
|
|
usable again.
|
|
|
|
The OTA helper is intentionally strict: upload is considered successful if the
|
|
device reboot is proven by an offline transition, an uptime reset, or a WLED
|
|
transport reset during upload plus the expected RFP release name in `/json/info`.
|
|
When flashing the exact same release again, the transport-reset proof is weaker,
|
|
so the whole-installation updater skips already matching devices by default.
|
|
|
|
## Global 2D Timing Check
|
|
|
|
The `/infinity` scene controls intentionally expose only one brightness control.
|
|
It sits next to `Master Speed`, starts at `100%`, and the old per-row dimmers
|
|
are forced to full output by the controller UI.
|
|
|
|
Global 2D animations derive their beat position from Infinity master time, not
|
|
from frame arrival time on each node. `Master Speed` is BPM, with one beat equal
|
|
to one visible 2D step. For example, `Checkerd` at `240 BPM` changes pattern
|
|
`240` times per minute.
|
|
|
|
Use `Strobe` in the `/infinity` Global 2D mode selector to check sync visually.
|
|
Its `Pulse Width` control is the normal `Size` control renamed for this mode.
|
|
The strobe is rendered from the shared beat phase, so all nodes should flash
|
|
in parallel at every BPM value from `20` to `240`.
|
|
|
|
## Master Crash Capture
|
|
|
|
If the master ever restarts unexpectedly, capture the next run with a serial log.
|
|
This keeps the production partition layout unchanged while still decoding ESP32
|
|
panic backtraces.
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
|
|
mkdir -p /tmp/rfp-master-crash
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio device monitor \
|
|
-e rfp_esp32s3_wroom1_n16r8_master \
|
|
--port /dev/ttyACM0 \
|
|
-b 115200 \
|
|
--filter esp32_exception_decoder \
|
|
--filter log2file
|
|
```
|
|
|
|
After a crash, save:
|
|
|
|
- The monitor log from the current directory or PlatformIO log output
|
|
- The first `rst:` line after reboot
|
|
- Any `Guru Meditation`, `panic`, or decoded backtrace lines
|
|
- The current `/json/info` fields `ver`, `release`, `e32code`, and `e32text`
|
|
|
|
Do not switch to a coredump partition shortly before the event unless a repeated
|
|
crash proves that serial logs are not enough.
|
|
|
|
## WLED Backup Mode
|
|
|
|
The regular WLED UI is intentionally kept available as a fallback.
|
|
|
|
- `Show Mode: ON` means Infinity Sync is active.
|
|
- `WLED Backup: ON` means Infinity Sync is stopped and regular WLED control can be used.
|
|
|
|
Stop Infinity on the master by API:
|
|
|
|
```bash
|
|
curl -X POST http://192.168.178.10/json/infinity \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"enabled":false}'
|
|
```
|
|
|
|
Re-enable later:
|
|
|
|
```bash
|
|
curl -X POST http://192.168.178.10/json/infinity \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"enabled":true}'
|
|
```
|
|
|
|
## Coldboot Diagnosis
|
|
|
|
The firmware side is now consolidated into the normal production targets. If a
|
|
board still starts only after pressing `RESET`, capture the serial log directly
|
|
after real power-on.
|
|
|
|
```bash
|
|
cd /home/jan/Documents/RFP/WLED-MM/repo
|
|
|
|
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
|
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
|
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
|
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
|
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
|
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
|
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
|
.venv/bin/python -m platformio device monitor \
|
|
-e rfp_esp32s3_wroom1_n16r8_master \
|
|
--port /dev/ttyACM0 \
|
|
-b 115200
|
|
```
|
|
|
|
Expected directly after power-on:
|
|
|
|
```text
|
|
rst:0x1 (POWERON_RESET)
|
|
SPI_FAST_FLASH_BOOT
|
|
```
|
|
|
|
If there is no clean boot log until the reset button is pressed, inspect hardware:
|
|
|
|
- `EN` / `CHIP_PU` must not float.
|
|
- Use a proper pull-up and reset delay, e.g. `10 kOhm` pull-up plus `1 uF` from `EN` to GND.
|
|
- If the 3.3 V rail rises slowly or external loads drag it down, use a reset supervisor.
|
|
- Check strapping pins and external DMX/LED wiring for backfeeding during power-up.
|