Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ Open the **web flasher** in Chrome or Edge desktop and click *Connect*:

> 🔗 **<https://sixback.io/>**

The page reads [`webflasher/manifest.json`](webflasher/manifest.json),
The page reads [`webflasher/manifest.json`](webflasher/manifest.json) or
a board-specific manifest file,
detects the chip family of the connected board, and writes the matching
factory image — bootloader + partition table + firmware + Web UI — in a
single shot. Right after the flash, esp-web-tools also offers to hand
Expand Down Expand Up @@ -179,6 +180,7 @@ page auto-redirects to the device's freshly assigned LAN IP via
| ESP32-C3 | `esp32-c3-devkitm-1` | 4 MB | flashes over the chip's built-in USB-Serial-JTAG |
| ESP32-C6 | `esp32-c6-devkitc-1` | 4 MB | WiFi 6 — works, but cold-start discovery occasionally drops SSDP-multicast packets and rare HTTP-server hangs need a reset |
| ESP32-C5 | `esp32-c5-devkitc1-n4` | 4 MB | **dual-band Wi-Fi 6 (2.4 + 5 GHz)** — native USB-Serial-JTAG; verified connecting on 5 GHz (channel 40; `band`/`channel` shown in `/api/status`). 4 MB / no-PSRAM devkit, A/B-OTA like C3/C6. **Note:** the C5 second-stage bootloader lives at flash `0x2000` (not `0x0`), and merging its factory image needs esptool ≥ 5. 8 MB+PSRAM C5 boards (e.g. Seeed XIAO ESP32-C5) would warrant a separate build target |
| Arduino Nano ESP32 | `arduino_nano_esp32` | 16MB | 8MB PSRAM. Uses an ESP32-S3 like the esp32-s3-devkitc-1, but with a single USB connector. Because this board identifies itself as an ESP32-S3 but uses a different USB connector than the esp32-s3-devkitc-1 for initial IP provisioning, it's image is not the same as the esp32-s3-devkitc-1 image and it therefore can't use the default S3 download/update buttons. **Use the dedicated "Arduino Nano ESP32" buttons for these.** |

**S3 is the recommended target for distribution.** During the 4-phase
end-to-end test (S3 ↔ C6 ping-pong with full erase/flash/provision each
Expand Down Expand Up @@ -225,8 +227,8 @@ Requires PlatformIO and a Linux/macOS host.

```bash
# build everything (all targets) + LittleFS images
pio run -e esp32 -e s3 -e s3-8mb -e c3 -e c6
pio run -e esp32 -e s3 -e s3-8mb -e c3 -e c6 -t buildfs
pio run -e esp32 -e s3 -e s3-8mb -e c3 -e c6 -e nano-esp32
pio run -e esp32 -e s3 -e s3-8mb -e c3 -e c6 -e nano-esp32 -t buildfs

# produce tagged factory images + manifest for the web flasher
./scripts/build_release.sh v0.8.22 # tag arg bakes the version into all firmwares
Expand Down
34 changes: 33 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
; Pattern aus RFNETHM uebernommen.
build_dir = /root/pio-build/bosefix32
; Default-Env-Liste: alle Targets werden bei einem nackten "pio run" gebaut.
default_envs = esp32, s3, s3-8mb, c3, c6, c5
default_envs = esp32, s3, s3-8mb, c3, c6, c5, nano-esp32

; -----------------------------------------------------------------------------
; Gemeinsame Konfiguration aller Targets — wird per "extends = common" geerbt.
Expand Down Expand Up @@ -259,3 +259,35 @@ build_flags =
; kryptischem "HTTP -1"; lokaler Multipart-Upload (/api/ota) bleibt.
; Verifiziert 2026-07-03, siehe ~/.claude/docs/esp32-c5-ota-tls-heap.md
-D SIXBACK_OTA_SELFUPDATE_UNSUPPORTED=1

; =============================================================================
; ESP32-S3, Arduino Nano ESP32 variant — Same as ESP32-S3 (N16R8V), EXCEPT no CH343.
; Serial() MUST be on the HW JTAG CDC like the c3/c6), otherwise Improv is unattainable.
; Download to target via the web interface or issue manual commands to download
; each binary to the appropriate offset (bootloader, partition table, app, spiffs)
; via esptool.py.
; =============================================================================
[env:nano-esp32]
extends = common
board = arduino_nano_esp32
board_build.partitions = partitions.csv
board_build.filesystem = littlefs
board_upload.flash_size = 16MB
board_build.arduino.memory_type = qio_opi
board_build.flash_mode = qio
board_build.psram_type = opi
build_flags =
${common.build_flags}
; Serial() on the HW JTAG CDC, shared with bootloader
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D BOARD_HAS_PSRAM
; Spotify trigger pipeline (Web API remote via scmudc-preset-pressed):
; requires WiFiClientSecure + token refresh + heap reserves, plus
; PSRAM/16MB flash for stability. Hence S3 only.
-D SIXBACK_SPOTIFY_ENABLED=1
-D SIXBACK_OTA_ENABLED=1
; Own artifact namespace for OTA pull (see ota_pull.cpp chipPrefix_).
-D SIXBACK_OTA_PREFIX='"sixback-nano-esp32"'
; #15: gabbo-WS-Watcher like the S3 (PSRAM available).
-D SIXBACK_GABBO_WATCHER_ENABLED=1
54 changes: 50 additions & 4 deletions scripts/build_release.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# SixBack — build release artefacts for ESP-Web-Tools distribution.
#
# For each target (esp32, s3, s3-8mb, c3, c6, c5) it produces:
# For each target (esp32, s3, s3-8mb, c3, c6, c5, nano-esp32) it produces:
# webflasher/sixback-<tgt>-factory.bin — merged bootloader+parts+app+fs
# webflasher/sixback-<tgt>-firmware.bin — app-only (for OTA over WiFi)
# webflasher/sixback-<tgt>-littlefs.bin — Web-UI image (for FS-OTA)
Expand Down Expand Up @@ -57,8 +57,8 @@ fi
# partitions-4mb.csv. Followup umgesetzt: scripts/fs_exclude_esp32.py strippt
# silence.mp3 (Spotify-only, ~120 KB) NUR fuer env:esp32 aus dem FS-Image
# (PROJECT_DATA_DIR -> gefilterte Staging-Kopie). Damit passt esp32 wieder rein.
"$HOME/.platformio/penv/bin/pio" run -e s3 -e s3-8mb -e c3 -e c6 -e c5 -e esp32 -t buildfs
"$HOME/.platformio/penv/bin/pio" run -e s3 -e s3-8mb -e c3 -e c6 -e c5 -e esp32
"$HOME/.platformio/penv/bin/pio" run -e s3 -e s3-8mb -e c3 -e c6 -e c5 -e esp32 -e nano-esp32 -t buildfs
"$HOME/.platformio/penv/bin/pio" run -e s3 -e s3-8mb -e c3 -e c6 -e c5 -e esp32 -e nano-esp32

# Resolve final version: tag if set, else read the core from version.h.
# Dev FW_VERSION_STRING carries a "+<counter>" suffix (e.g. "0.8.4+1116");
Expand Down Expand Up @@ -120,6 +120,8 @@ check_size "$PIO_BUILD/s3/firmware.bin" $APP_16MB "s3 app"
check_size "$PIO_BUILD/s3/littlefs.bin" $FS_16MB "s3 fs"
check_size "$PIO_BUILD/s3-8mb/firmware.bin" $APP_8MB "s3-8mb app"
check_size "$PIO_BUILD/s3-8mb/littlefs.bin" $FS_8MB "s3-8mb fs"
check_size "$PIO_BUILD/nano-esp32/firmware.bin" $APP_16MB "nano-esp32 app"
check_size "$PIO_BUILD/nano-esp32/littlefs.bin" $FS_16MB "nano-esp32 fs"

if [ "$size_errors" -gt 0 ]; then
echo >&2
Expand Down Expand Up @@ -166,6 +168,8 @@ merge_target s3 esp32s3 16MB 0x610000 0x0
merge_target s3-8mb esp32s3 8MB 0x610000 0x0 # Seeed XIAO u.a. (Issue #23)
merge_target c3 esp32c3 4MB 0x3B0000 0x0
merge_target c6 esp32c6 4MB 0x3B0000 0x0
merge_target nano-esp32 esp32s3 16MB 0x610000 0x0


# --- C5: eigener Merge (NICHT merge_target) -------------------------------
# Zwei C5-Spezifika, die merge_target nicht abdeckt:
Expand Down Expand Up @@ -354,7 +358,49 @@ write_manifest "$OUT/manifest-update-s3-8mb.json" <<EOF
}
EOF

# --- 3d) Deploy-Reihenfolge-Guard ------------------------------------------
# ---3d) nano-esp32 variant--------------------
# esp-web-tools selects builds ONLY via chipFamily — a second ESP32-S3
# entry in the main manifest would be ineffective (the first one wins). The
# Arduino Nano ESP32 variant therefore gets its OWN manifest pair + own
# install button on the landing page.
# Offsets identical to the 16 MB S3 (app slots the same size, spiffs the same
# Offset 0x610000)
write_manifest "$OUT/manifest-nano-esp32.json" <<EOF
{
"name": "SixBack (Arduino Nano ESP32)",
"version": "$VERSION",
"funding_url": "https://paypal.me/busware",
"new_install_prompt_erase": true,
"builds": [
{
"chipFamily": "ESP32-S3",
"parts": [
{ "path": "sixback-nano-esp32-factory.bin", "offset": 0 }
]
}
]
}
EOF

write_manifest "$OUT/manifest-update-nano-esp32.json" <<EOF
{
"name": "SixBack (Arduino Nano ESP32 update)",
"version": "$VERSION",
"funding_url": "https://paypal.me/busware",
"new_install_prompt_erase": false,
"builds": [
{
"chipFamily": "ESP32-S3",
"parts": [
{ "path": "sixback-nano-esp32-firmware.bin", "offset": 65536 },
{ "path": "sixback-nano-esp32-littlefs.bin", "offset": 6356992 }
]
}
]
}
EOF

# --- 3e) Deploy-Reihenfolge-Guard ------------------------------------------
# Jede in index.html referenzierte Manifest-Datei muss in $OUT existieren —
# verhindert tote Install-Buttons, wenn die Seite vor den Artefakten deployed
# wuerde (Praezedenzfall v0.8.10: Page-only-Fix per rsync).
Expand Down
62 changes: 49 additions & 13 deletions webflasher/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ <h1>SixBack — Web Flasher</h1>
</div>

<div class="panel flash">
<h2 style="margin-top:0">Install SixBack on your ESP32</h2>
<p>Plug your ESP32 board into USB, click below, and pick the serial port that appears.<br>
The browser detects the chip and flashes the matching image.</p>
<h2 style="margin-top:0">Install SixBack on your Espressif ESP32</h2>
<p>Connect your ESP32 board (except ESP32-S3 boards with only
8&nbsp;MB flash + PSRAM, e.g. Seeed&nbsp;XIAO&nbsp;ESP32S3 or an Arduino Nano ESP32;
see below for those) to your computer using a data USB cable, click below,
and pick the serial port that appears.<br>
The browser detects the chip family and flashes the matching image.</p>
<p style="display:flex; gap:1.5em; justify-content:center; flex-wrap:wrap; align-items:flex-start; margin-top:1em">
<span style="text-align:center">
<esp-web-install-button manifest="manifest.json"></esp-web-install-button>
Expand All @@ -79,19 +82,22 @@ <h2 style="margin-top:0">Install SixBack on your ESP32</h2>
<b>Update existing</b> for a stick that already runs SixBack.
</p>
<div class="warn">
<strong>ESP32-S3-DevKitC-1 has two USB sockets — flash over the one labelled <code>UART</code>.</strong>
That socket appears as a <code>CH340</code>/<code>CH343</code> serial port. If you flash over
the board's other, native <code>USB</code> socket instead, the flash still succeeds, but the
<strong>The ESP32-S3-DevKitC-1 has two USB ports — flash over the one labelled <code>UART</code>.</strong>
That port appears as a <code>CH340</code>/<code>CH343</code> serial port. If you flash over
the board's other USB port, the native <code>USB</code> port instead, the flash still succeeds, but the
browser's <b>“Connect device to Wi-Fi”</b> step afterwards will <em>not</em> appear — SixBack
answers the provisioning handshake only on the <code>UART</code> port. You'd then have to set up
WiFi through the <code>SixBack-…</code> hotspot the stick opens instead. Single-socket boards
(XIAO&nbsp;S3, ESP32-C3&nbsp;/&nbsp;C6&nbsp;/&nbsp;C5) have only one port and are unaffected.
</div>
<hr style="border:none; border-top:1px solid var(--mute); opacity:.3; margin:1.2em 0">
<h3 style="margin:.2em 0 .4em">ESP32-S3 with 8&nbsp;MB flash (Seeed XIAO ESP32S3 &amp; similar)</h3>
<p style="font-size:.9em">The buttons above flash the <b>16&nbsp;MB</b> S3 layout. Boards with only
<b>8&nbsp;MB flash + PSRAM</b> (e.g. Seeed&nbsp;XIAO&nbsp;ESP32S3) need this dedicated image instead —
the standard one does not fit and the flash would fail partway through.</p>
<p style="font-size:.9em">Use for ESP32-S3 boards with only
<b>8&nbsp;MB flash + PSRAM</b> (e.g. Seeed&nbsp;XIAO&nbsp;ESP32S3). Because of limitation with
the ESP32 Web Tools, these boards have their own buttons and manifest files.
The standard ESP32-S3 image downloaded by the above buttons does not fit and the flash would fail
partway through.
</p>
<p style="display:flex; gap:1.5em; justify-content:center; flex-wrap:wrap; align-items:flex-start; margin-top:.6em">
<span style="text-align:center">
<esp-web-install-button manifest="manifest-s3-8mb.json"></esp-web-install-button>
Expand All @@ -103,7 +109,7 @@ <h3 style="margin:.2em 0 .4em">ESP32-S3 with 8&nbsp;MB flash (Seeed XIAO ESP32S3
</span>
</p>
<p style="color:var(--mute); font-size:.85em">
Not sure which one you have? The <code>Nxx</code> in the module name tells the flash size:
Not sure which Espressif board you have? The <code>Nxx</code> in the module name tells the flash size:
<code>N8…</code>&nbsp;=&nbsp;8&nbsp;MB, <code>N16…</code>&nbsp;=&nbsp;16&nbsp;MB.
XIAO&nbsp;ESP32S3 / Sense&nbsp;=&nbsp;8&nbsp;MB; XIAO&nbsp;ESP32S3&nbsp;<em>Plus</em>&nbsp;=&nbsp;16&nbsp;MB
(use the standard buttons above). PSRAM is required either way.<br>
Expand All @@ -115,6 +121,31 @@ <h3 style="margin:.2em 0 .4em">ESP32-S3 with 8&nbsp;MB flash (Seeed XIAO ESP32S3
<a href="sixback-s3-8mb-firmware.bin">firmware</a> @0x10000 ·
<a href="sixback-s3-8mb-littlefs.bin">littlefs</a> @0x610000
</p>
<hr style="border:none; border-top:1px solid var(--mute); opacity:.3; margin:1.2em 0">
<h3 style="margin:.2em 0 .4em">Arduino Nano ESP32</h3>
<p style="font-size:.9em">The Arduino Nano ESP32 has a ESP32-S3 microcontroller,
but it only has one USB port. cause of limitation with the ESP32 Web Tools, the Arduino Nano ESP32
has its own buttons and manifest files.
<br>
<strong>NOTE: </strong>The fresh install image replaces the bootloader on the Arduino Nano ESP32.
The board must be placed in the bootloader flash mode before hitting the Connect button.
To do this, short pin B1 to GND and press and release the RST button. The built-in RGB LED
should go green. Remove the short between B1 and GND; the Built-in LED should go red/blue (purple).
The board is ready to flash. Press the Connect button and select the ttyACM0 (USB JTAG/serial debug unit)
port (in Linux). After flashing, the built-in LED should go off. Follow
the same steps to enter the bootloader flash mode again to flash the update image. The update image
does not replace the bootloader. Or do an Over-the-Air (OTA) update from the Web UI after the initial flash.
</p>
<p style="display:flex; gap:1.5em; justify-content:center; flex-wrap:wrap; align-items:flex-start; margin-top:.6em">
<span style="text-align:center">
<esp-web-install-button manifest="manifest-nano-esp32.json"></esp-web-install-button>
<br><small style="color:var(--mute); display:block; margin-top:.4em">Fresh install Arduino Nano ESP32 — erases all settings</small>
</span>
<span style="text-align:center">
<esp-web-install-button manifest="manifest-update-nano-esp32.json"></esp-web-install-button>
<br><small style="color:var(--mute); display:block; margin-top:.4em">Update existing Arduino Nano ESP32 — keeps settings</small>
</span>
</p>
</div>

<div class="warn">
Expand All @@ -135,7 +166,7 @@ <h3 style="margin:.2em 0 .4em">ESP32-S3 with 8&nbsp;MB flash (Seeed XIAO ESP32S3
</div>

<div class="ok">
<strong>Recommended hardware: ESP32-S3-DevKitC-1-N16R8</strong> —
<strong>Recommended hardware: ESP32-S3-DevKitC-1-N16R8 or Arduino Nano ESP32</strong> —
16 MB flash, 8 MB PSRAM, mature WiFi 5 stack. In extended end-to-end
testing this was the most robust target. ESP32 / C3 / C6 / C5 work too
(factory image auto-selected), but the C6's WiFi 6 stack occasionally
Expand All @@ -156,7 +187,12 @@ <h3 style="margin:.2em 0 .4em">ESP32-S3 with 8&nbsp;MB flash (Seeed XIAO ESP32S3
</div>

<h2>What you get</h2>
<p>After flashing, point your browser at <code>http://sixback.local/</code>: discover the speakers
<p>After flashing the initial install image, hit the next button. A dialog box should appear
asking for your WiFi credentials. You have 2 minutes to
enter your Wi-Fi SSID and password. The stick also opens for 5 minutes an **open** AP called
`SixBack-XXYYZZ`(no password) with a DNS hijack
so any browser connecting to it gets the WiFi-setup form automatically. After provisioning the WiFi,
point your browser at <code>http://sixback.local/</code>: discover the speakers
on your LAN, migrate them off the dead Bose cloud, and manage all six preset buttons by
drag &amp; drop — search TuneIn / add custom streams in the sidebar, drag tiles onto preset
slots, push to the speaker.</p>
Expand All @@ -182,7 +218,7 @@ <h2>How it works</h2>
flashing, so you can hand over Wi-Fi SSID and password from the same page.</li>
<li>The device then advertises itself as <code>sixback.local</code> on mDNS;
open <code>http://sixback.local/</code> to manage your Bose speakers.</li>
</ol>
</ol>

<div class="ok">
<strong>OTA updates later:</strong> once SixBack runs on the device, future
Expand Down