Log functions call global_logger->log_vprintf_() without a null check.
The test main.cpp skips the generated setup() (which calls
Logger::pre_setup()), so set up a static Logger before running tests.
Call global_logger->log_vprintf_() directly without null-checking
global_logger on every log call. Logger::pre_setup() sets global_logger
before any other component is created in the generated setup() function,
so it is guaranteed to be valid by the time any log function is invoked.
Also removes the __FlashStringHelper* esp_log_vprintf_ overload which
was dead code (only called from esp_log_printf_, never directly).
Add a Python codegen test to verify the ordering invariant, and a
comment on App.pre_setup() documenting the constraint.
Move the pure logic (string building, escaping, byte length
calculation) out of the nested closure into a module-level function
that can be tested without codegen mocks. Tests cover both copilot
review concerns: empty friendly_name with MAC suffix, and UTF-8
byte length for non-ASCII characters.
Add generate_boards.py script that reads board definitions and variant
pin headers from the arduino-pico repository to auto-generate boards.py
with support for 143+ boards including RP2350 variants.
Fix the Pico W LED pin from 32 (non-existent GPIO, never worked) to 64
(CYW43 wireless GPIO 0, hardware verified).
Make gpio.py pin validation data-driven:
- CYW43 virtual pin detection uses board pin map data
- Pin range based on MCU type from generated board metadata
- No hardcoded board names or magic numbers
Serial ports in the chooser may belong to other devices (e.g. FT232R),
not the RP2040. Show the BOOTSEL tip whenever no BOOTSEL device is
detected via picotool, regardless of whether serial ports are present.
Replace UF2 file copy to mass storage volume with direct picotool upload.
This avoids macOS "disk not ejected properly" warnings caused by the RP2040
resetting immediately after receiving the firmware.
- Use picotool (already installed by PlatformIO) for BOOTSEL detection
and firmware upload via USB
- Upload ELF directly with `picotool load -v -x` for real-time progress
- Remove platform-specific mass storage volume detection (macOS/Linux/Windows)
- Show helpful udev rules message on Linux permission errors
Move signed bin creation from post_build script to upload_using_platformio.
The post_build AddPostAction only runs during build, not during nobuild
upload, so the file was missing when PlatformIO tried to upload.
Now create firmware.bin.signed before calling PlatformIO upload.
Add auto-detection of RP2040 BOOTSEL mass storage volumes (RPI-RP2) on
macOS, Linux, and Windows. Show detected volumes as upload targets with
a progress bar for UF2 file copy. Display helpful BOOTSEL instructions
when no RP2040 device is found.
- Add get_rp2040_mass_storage_volumes() to detect mounted RPI-RP2 volumes
- Add PortType.MASS_STORAGE and upload_using_uf2_copy() with progress bar
- Move ProgressBar to helpers.py for shared use
- Wait for USB-CDC serial port after upload for log output
- Auto-select single serial port for logs after mass storage upload
- Create firmware.bin.signed in post_build to fix nobuild upload target
- Show BOOTSEL tip when only OTA options are available
Every entity generated two codegen calls:
entity->set_name("Name", hash);
entity->set_entity_strings(packed);
Merge these into a single configure_entity(name, hash, packed) call
to reduce generated code size. For a config with 50+ entities this
eliminates 50+ function calls from the generated setup() function.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>