A fully client-side web tool for loading arbitrary binary data onto the Daisy Seed QSPI flash, paired with a pre-compiled SRAM firmware that reads and processes that data. No server required — everything runs in the browser via WebUSB / WebDFU.
┌─────────────┐ Phase 1: DFU write ┌──────────────────────┐
│ Browser │ ─────────────────────────► │ QSPI flash │
│ (website) │ data file → 0x90080000 │ (Daisy Seed) │
│ │ └──────────────────────┘
│ │ Phase 2: DFU write ┌──────────────────────┐
│ │ ─────────────────────────► │ Internal flash │
│ │ firmware/loader.bin │ (Daisy Seed) │
└─────────────┘ └──────────────────────┘
│ on reset
▼
┌──────────────────────┐
│ SRAM firmware │
│ reads QSPI @ 0x90080000
│ and processes data │
└──────────────────────┘
Both DFU operations happen in a single USB session without disconnecting the device.
QSPI-WebLoader/
├── index.html Main page (fully self-contained)
├── run.sh Local HTTPS dev server (requires Python 3 + OpenSSL)
├── firmware/
│ └── loader.bin Pre-compiled SRAM firmware blob (see fw/ to build it)
├── app/
│ ├── app.js Vue 2 application (drop zone, flash UI, progress)
│ ├── dfu-util.js WebDFU two-phase flash logic
│ └── style.css Styles
├── dfu/
│ ├── dfu.js WebDFU core library
│ ├── dfuse.js DfuSe extension (STM32 target support)
│ └── FileSaver.js File download helper
├── fw/ SRAM firmware source (compile once, ship the .bin)
│ ├── Makefile
│ ├── common.mk
│ ├── init.sh Clone/update libDaisy
│ └── src/
│ └── main.cpp Demo: reads WAV from QSPI, plays audio
└── util/
└── SimpleSecureHTTPServer.py Self-contained HTTPS dev server
# Initialise libDaisy (clones at the pinned commit and builds it)
./init.sh
# Then build the SRAM firmware
cd fw && makeCopy the compiled binary to the website:
cp fw/build/QSPI-WebLoader-Loader.bin firmware/loader.binWebUSB requires HTTPS. The included server generates a self-signed certificate automatically on first run:
./run.sh
# → https://localhost:9001Open https://localhost:9001 in Chrome (or another Chromium-based browser). Accept the self-signed certificate warning once.
- Drop a data file onto the page (e.g. a 48 kHz mono WAV for the demo firmware).
- Put the Daisy into DFU bootloader mode.
- Click Flash to Daisy — a browser device picker will appear.
- Select "Daisy Bootloader" from the list.
- The site writes data to QSPI and the firmware to flash in one go.
- The Daisy reboots automatically and runs the SRAM firmware.
| Address | Contents |
|---|---|
0x90000000 |
QSPI base (reserved for bootloader) |
0x90040000 |
BOOT_SRAM firmware (written by Flash Firmware) |
0x90080000 |
User data (written by Flash Data) |
The firmware reads from 0x90080000. This address is safely past the BOOT_SRAM firmware region (0x90040000), so writing data never collides with flashing the firmware binary.
fw/src/main.cpp is a demo WAV player. It:
- Reads a raw WAV file directly from
0x90080000in QSPI. - Supports 16-bit PCM and 32-bit float, mono or stereo.
- Loops playback via the Daisy audio callback.
- Blinks the LED slowly on success, fast on error.
APP_TYPE = BOOT_SRAM — the compiled binary is stored in the Daisy's internal flash by the bootloader, then copied to SRAM and executed there on each boot. QSPI is therefore free for persistent data that survives firmware updates.
Replace or extend main.cpp to handle any data type your project requires (wavetables, sample banks, preset data, lookup tables, etc.).
The Daisy bootloader exposes two DFUSe alternate interfaces:
| Alternate name | Address | Used for |
|---|---|---|
@QSPI Flash |
0x90000000 |
User data |
@Internal Flash |
0x08000000 |
SRAM firmware blob |
dfu-util.js auto-selects the correct alternate for each phase.
WebUSB is supported in Chromium-based browsers only (Chrome, Edge, Opera). Firefox and Safari are not supported.
- WebDFU library (
dfu.js/dfuse.js) from devanlai/webdfu - JuTron-Dist — reference client-side DFU programmer by electro-smith
- QSPI-Flasher — reference QSPI data flashing workflow and libDaisy integration
- libDaisy — hardware abstraction layer by electro-smith