Skip to content

Firmware updates and rollback

OTA and USB recovery

In the page, choose build/firmware/normal/espurr.bin and upload. Use the application image, not merged-binary.bin, bootloader or partition-table images. Firmware length, target and project identity are checked; native IDF finalization checks image validity before changing the boot partition. Only one update can run at once. Each ear shows an orange progress bar along its logical outline, with a dim violet remainder. Both ears show the same fraction even with unequal counts or reversed wiring. A completely orange bar means native image finalization succeeded and the new boot slot was selected.

Normal animation and dithering stay paused during OTA. The render owner transmits progress at most once per percentage point, between completed flash writes, and finishes both RMT transactions before the next write. Pixels hold that frame during flash work. The bar obeys main brightness, gamma, RGB trims and the shared current limit; powered-off ears or zero main brightness remain dark. Background and motion overlays are suppressed. An incomplete update aborts on an LED transaction failure before another flash write. An indicator failure after successful boot selection cannot undo that selection. This is build/host-tested; physical upload timing and the visible progress display remain hardware checks.

Truncated, oversized, wrong-target, wrong-project, failed or idle-timed-out writes abort and resume the previous LED mode. The inactive slot may contain partial data, but the running slot remains selected. Settings survive OTA. A successful image is acknowledged before a delayed reboot. Finalization selects the new boot slot before sending that acknowledgement. If the connection drops after finalization, the image may already be selected even though the phone did not receive success; a 15-second reset grace period will boot it. An acknowledged update reboots after 1.5 seconds. Don't interpret a lost final acknowledgement as proof that nothing changed.

The initial USB deployment must include the rollback-enabled bootloader. Moving S3 from an earlier partition layout to the 8 MB layout also needs a full USB flash; app-only OTA cannot replace the partition table. The normal flash plan leaves the reserved recovery slot untouched. The S3 web installer instead installs recovery-only bootstraps, with sparse reset/preserve plans and the GPIO hold enabled. Both retain NVS; the default clears A/B and their boot selection so recovery starts automatically. An optional Install selected release in slot A and boot it choice installs the matching normal app too, marks A new for first-boot validation, and keeps B/NVS/PHY/models. Both phone apps support BLE recovery with a manually selected normal app image. Blank-device Wi-Fi provisioning is available over bonded BLE; phone release downloads remain deferred. For classic ESP32 USB recovery or a deliberate initial flash:

# Activate your EIM-managed ESP-IDF v6.1 environment; run from the repository root.
idf.py --preset normal build
idf.py --preset normal -p /dev/cu.YOUR_ATOM_PORT -b 1500000 flash monitor

Normal full flashing writes the bootloader, partition table, initial OTA metadata and app, and preserves the NVS partition. Do not erase flash as a routine upgrade/recovery step. A boot-held button restores config mode if firmware is otherwise healthy; USB remains available for broken firmware or unusable storage. A full NVS reset is an explicit USB operation.

The espurr app now also offers Setup → Firmware updates over the existing bonded BLE connection. Choose the application .bin in Files, review its version and size, then install. Stay close, keep power connected and leave the app in the foreground; cancellation/disconnection aborts an incomplete transfer. The first firmware containing the endpoint needs browser OTA or USB installation, and the app must be updated alongside it. Full orange ears mean the new image was validated and selected; reconnect after reboot to confirm the running firmware. BLE uses OTS/CoC with bounded 4096-byte flash handoffs, or the 384-byte GATT fallback, exact offsets and SHA-256, then the same native finalisation/rollback path as the browser. These software checks are complete; phone upload, interruption, visible progress and rollback remain physical acceptance tests.

The ESP-BLEOTA app is unsupported. Standard OTS and the existing control service share one conn_mgr host; the common OTA worker retains image validation and rollback.

Firmware 0.5.6 removes the ambient BLE activity effect and passive scanner. Its ID 8 is retired permanently; saved schema 1–15 selections migrate to Motion twinkle under schema 16. Other IDs are unchanged. Secure BLE control and app OTA remain on the existing host. The legacy activity slot stays zero in BLE/browser status for compatibility; it is no longer shown in browser diagnostics.