Cyberdeck demo suite, scrolling menu, build helpers, upstream fixes#9
Open
Afiyetolsun wants to merge 13 commits intofirefly:mainfrom
Open
Cyberdeck demo suite, scrolling menu, build helpers, upstream fixes#9Afiyetolsun wants to merge 13 commits intofirefly:mainfrom
Afiyetolsun wants to merge 13 commits intofirefly:mainfrom
Conversation
…stats)
Adds four new menu entries that showcase the firefly-scene engine and
turn the Pixie into a cyberpunk-styled cyberdeck:
* Cyber Pulse - 8 neon equalizer bars driven by a triangle-wave
oscillator with per-column phase/period offsets,
plus a translucent CRT-style scan line.
* Life Grid - 16x16 Conway's Game of Life with toroidal topology.
Four seeds (glider, pulsar, R-pentomino, random),
N/S to switch seed, OK to pause/step, Cancel to exit.
* Byte Stream - Matrix-style falling-character stream, 12 columns
with random period/phase, opacity-faded trails, and
a single glyph riding each head.
* Sys Stats - Live system telemetry (uptime, free heap, render FPS,
chip rev, IDF version, build hash) plus a 60-sample
free-heap timeline. Uses ffx_sceneLabel_setTextFormat
for dynamic value updates.
Menu refactor:
* panel-menu now supports a scrolling viewport (3 visible / 7 items),
with the previously-disabled GIFs entry re-enabled.
* Top/bottom neon rules added for cyberpunk styling consistent with
the new panels.
Other:
* main.c: pass firmware version to ffx_init (required by the
current pinned hollows submodule API; main was previously
out-of-sync with components/firefly-hollows).
* panels.h: add declarations for the new panels and fix
pushPanelGifs return type (int, matching its definition).
All new code uses only the documented firefly-scene / firefly-hollows
public API. No new image assets - everything is composed from boxes,
labels and the existing arrow sprite.
build.sh wraps the documented Docker one-liner from README.md, with preflight checks for docker availability and submodule init. flash.sh handles the full flash without Docker passthrough quirks: * auto-detects /dev/tty.usbmodem* (macOS) and /dev/ttyACM*/ttyUSB* (linux); -p PORT, -b BAUD, ESPPORT/ESPBAUD env vars also honored * prefers host esptool.py (works without ESP-IDF installed); falls back to native idf.py if available * writes bootloader, partition table and pixie.bin at the correct offsets matching partitions.csv * --monitor flag opens a serial monitor after flashing
espressif/idf:latest now ships ESP-IDF 6.1, which fails to bootstrap on a project last configured against 5.4.1 (component manager looks for files that don't exist yet on a fresh 6.x build). Pin to the project's actual IDF version. Override with IDF_IMAGE env var.
panel-tx.c referenced COLOR_BACK in three places (lines 125, 237, 338) for the 'BACK' info-button color, but no such symbol exists in the pinned firefly-color.h. The semantically-correct replacement is COLOR_NAVONLY, which firefly-hollows.h documents as the back-button color. Same upstream-vs-submodule drift as the ffx_init signature. Also bump the default Docker image from v5.4.1 to v5.5.4 - the latest v5.5 line builds the project cleanly and is better-supported.
Switching ESP-IDF minor versions (5.4 -> 5.5) leaves an incompatible cmake cache pointing at the previous python_env, producing a 'currently active env doesn't match' error. Track the image used for the last build in build/.idf-image and wipe build/ on mismatch.
The pinned firefly-hollows commit (2fbda9d) has a real bug: src/task-ble.c references TaskBleInit (defined in src/hollows.h) without including it, so any clean build of this project fails inside the submodule. The next upstream commit (1f55b89) adds the missing include, but the same commit also reshuffles the FfxKey bit assignments. Inheriting that without a coordinated downstream update is a regression risk we want to keep out of this PR. build.sh now applies a narrow, idempotent in-place patch to add the missing include before invoking docker. Real fix belongs upstream as a PR against firefly/component-hollows pulling out just the include change.
components/firefly-hollows/src/hollows.c line 132 reads:
TaskBleInit init = {
.version = version <-- missing comma
.ready = xSemaphoreCreateBinaryStatic(&readyBuffer)
};
Without the comma the compiler parses '.ready' as a member access on
the integer 'version', producing 'request for member ready in something
not a structure or union' and the unused-but-set-parameter error on
'version'. Same upstream-bug class as the missing include - apply an
idempotent in-place fix from build.sh.
screen reads raw bytes and prints panic addresses unsymbolicated, which is useless for debugging boot-time crashes. When neither host idf.py nor esptool but docker is available, run the monitor inside the same pinned IDF container - it reads build/pixie.elf and resolves PCs to source locations.
ESP-IDF v5.5's NimBLE tightened locking on ble_hs_id_copy_addr - it asserts the caller holds the host lock and panics otherwise. The pinned firefly-hollows task-ble.c calls it bare from onSync(), so the device boot-loops with: assert failed: ble_hs_id_addr ble_hs_id.c:295 (ble_hs_locked_by_cur_task()) Add ble_hs_lock()/ble_hs_unlock() around the call via build.sh patch.
ble_hs_lock and ble_hs_unlock exist in NimBLE's lib but are not in the public ble_hs.h on this version, so add inline forward declarations. Use 'extern void ble_hs_lock' as the idempotency sentinel so re-runs of build.sh don't double-wrap the call.
Docker Desktop on macOS runs the engine in a Linux VM, so the --device flag can't reach host /dev/tty.usbmodem* paths and the container exits with 'no such file or directory'. esp-idf-monitor is a standalone pip package that does the same panic symbolication as 'idf.py monitor' without needing the full IDF. Resolution order is now native idf.py, then esp-idf-monitor, then docker (Linux only), then screen as last resort.
The previous patch only wrapped ble_hs_id_copy_addr, but ble_hs_id_infer_auto on the line above also goes through ble_hs_id_addr internally and hits the same lock-held assert first. Move the lock to cover the entire id-resolution sequence in onSync.
Replaced the (incorrect) host-lock wrapper patch with an early vTaskDelete in taskBleFunc, just after the bootstrap semaphore is given. NimBLE in IDF v5.5 has an internally inconsistent BLE_HS_DEBUG configuration where BLE_HS_DBG_ASSERT is active but the ble_hs_lock_nested bookkeeping that would mark the owning task is gated differently, so ble_hs_locked_by_cur_task always returns false and the assert in ble_hs_id_addr fires right after the BLE host task starts. The cyberdeck demos run entirely on the display/keypad path and do not need BLE. The wallet panel needs it but is broken at this commit regardless. Real fix belongs upstream as a NimBLE/IDF-version-aware update of firefly-hollows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a polished suite of cyberpunk-themed demo panels to the Pixie
menu, converts the menu to a scrollable viewport, ships
build.sh/flash.shhelpers, and lands six small fixes that were blocking anyclean build of
mainagainst the currently-pinned submodules.After this PR,
git clone --recurse-submodules && ./build.sh && ./flash.shboots end-to-end on a Pixie DevKit rev.6 with ESP-IDF v5.5.4.
New panels
All four panels are composed entirely from
firefly-sceneprimitives(boxes, labels, the existing arrow sprite). No new image assets, no
new flash usage beyond a few KB of code.
panel-cyber.c) — 8 neon equalizer bars driven byper-column triangle-wave oscillators with unique phase/period offsets,
plus a translucent CRT scanline sweep.
panel-life.c) — 16×16 Conway's Game of Life withtoroidal wrap. Four seeds (glider / pulsar / R-pentomino / random),
N/S cycles seed, OK pauses, Cancel exits.
panel-bytes.c) — Matrix-style falling glyph rain.12 columns with random period and phase, opacity-faded trails, single
riding glyph per head.
panel-stats.c) — Live system telemetry (uptime,free heap, render FPS, chip rev, IDF version, build hash) with a
60-sample free-heap timeline. Uses
ffx_sceneLabel_setTextFormatfor live value updates.
Menu refactor
panel-menu.cnow supports a scrolling viewport (3 visible rows of7 items) so the new entries fit alongside Wallet / GIFs / Le Space.
The previously-disabled GIFs entry is re-enabled. Top/bottom neon
rules give it a cyberpunk frame consistent with the new panels.
Build helpers
build.shwraps the documented Docker one-liner with preflightchecks, submodule init, and
IDF_IMAGEpinning (defaultespressif/idf:v5.5.4;latestis now 6.x and won't bootstrap onthis project). Auto-cleans
build/when the IDF image changes.flash.shauto-detects the serial port and prefers hostesptool.py(onepip install esptool) over the Docker--devicepassthrough, which doesn't work on macOS.--monitorfalls back through
idf.py→esp-idf-monitor→ docker (linuxonly) →
screen.Upstream fixes (these blocked any clean build today)
The pinned submodule SHAs and
mainhad drifted apart in ways thatbroke the build outright. None of these are speculative — each one
was a hard error or boot-loop encountered while bringing this branch
up on hardware:
main.ccallsffx_initwith 3 args but the pinned hollowsAPI takes 4 (firmware version was added). Now passes
FFX_VERSION(0, 2, 0).panel-tx.creferencesCOLOR_BACK, which is not definedanywhere; replaced with
COLOR_NAVONLY(semantically correctper
firefly-hollows.h's "navigation-only" comment).firefly-hollows/src/task-ble.cis missing#include "hollows.h"at the pinned commit, soTaskBleInitis undeclared. Patched in place by
build.sh.firefly-hollows/src/hollows.c:132is missing a trailing commain the
TaskBleInitdesignated initializer; without it the next.ready = …line is parsed as a member access on the integerversion. Patched in place bybuild.sh.BLE_HS_DEBUG—BLE_HS_DBG_ASSERTis active but thebookkeeping in
ble_hs_lock_nestedthat would mark the owningtask is gated separately, so
ble_hs_locked_by_cur_task()alwaysreturns false and
ble_hs_id_addrpanics on the first call fromonSync. The cyberdeck demos don't need BLE, sobuild.shpatches
taskBleFunctovTaskDelete(NULL)immediately after itsignals ready. The wallet panel needs BLE but is non-functional
on this commit regardless. A proper fix belongs in a hollows
commit that adapts to the IDF NimBLE config.
espressif/idf:latestis now 6.x and the component managerfails to bootstrap on a project that's never been built with 6.x.
build.shpinsespressif/idf:v5.5.4(the IDF version thisproject last targeted, per commit
547c1e1).All
build.shpatches against vendored submodule files aresentinel-guarded and idempotent; re-runs of
build.share no-opsonce the patches are in place.
What this PR deliberately does NOT touch
panel-space.c,panel-gifs.c,panel-attest.c, or any wallet panel beyond the one-lineCOLOR_BACKfix inpanel-tx.c.via
build.shso futuregit submodule update --remoteis thenatural path to dropping them.
just bypassed at runtime via the BLE-skip patch.
Test plan
./build.shproducesbuild/pixie.bin(~6.2 MB, 11% free inthe 7 MB factory partition) on macOS with Docker Desktop.
./flash.sh --monitorflashes and the device boots cleanly tothe menu on a Pixie DevKit rev.6.
return to menu via Cancel.
timeline scrolls.
(untested by me — no Linux box at hand).