Static web pages that update the application firmware (app.bin) of
SLogic16U3 and SLogic32U3 over WebUSB. This repository is also the
tools/ota submodule of sipeed/SLogic,
whose release notes read the firmware version table from it.
index.html: one device; select it, choose the file, click Update firmware.batch.html: many boards in parallel for production (see below).firmware.json: firmware version table (minimum / latest per model), served with the pages so other tools can warn about old firmware.
Light/dark theme and English/中文 included.
Every push to main runs the tests and publishes the site to GitHub Pages
(.github/workflows/pages.yml); pull requests run the tests only. Only
index.html, batch.html, style.css, favicon.svg, firmware.json and
src/ are published. The public domain and CDN in front of Pages are managed
by operations. The batch page's browser policy allows exactly one origin,
STATION_ORIGIN in src/station.js (currently https://slogic.sipeed.com):
keep it equal to the public address the pages are served from. GitHub Pages
sends Access-Control-Allow-Origin: *, so other sites can read
firmware.json.
WebUSB is available in Chrome, Edge, Opera, Brave and other Chromium-based browsers on desktop (Windows, macOS, Linux). Firefox and Safari do not implement WebUSB; the page still opens there and tells the user to switch browsers. The page must be served over https:// or from http://localhost (browsers only allow USB access on secure origins).
No build step; serve the directory as static files:
python3 serve.py # http://localhost:8000 (this computer)
python3 serve.py --lan # https://<lan-ip>:8443 for colleagues on the LANUSB access needs a secure page, and a plain http://<lan-ip> address is not
one, so --lan serves HTTPS with a self-signed certificate (generated with
openssl into .certs/, covering this computer's IPv4 addresses). Each visitor
accepts the browser's certificate warning once.
After changing any file under src/ or style.css, run python3 stamp.py:
it puts content hashes into the asset URLs of both pages (an import map), so
browsers never mix cached old modules with new ones. The tests fail if a
stamp is out of date.
Demo mode: http://localhost:8000/?demo (SLogic32U3) or ?demo=16u3
simulates a device and its flash, so the whole flow can be previewed without
hardware.
Ten quick clicks on the logo of index.html (within 3 seconds) toggle a
hidden Flash tools card that replaces steps 2 and 3 (the log moves
along); a reload leaves it. In update mode it reads,
writes and erases the configuration flash at any offset over the same DFU
bridge as the update (src/flashops.js, UI in src/advanced.js):
- Read a range into a hex view (only the visible rows are drawn, so a
whole 16 MiB chip is fine), download it as
.bin, or compare it with a file (differing bytes are highlighted, with links to the first ones). - Verify the flash against a file: reads the file's length at an offset and compares byte for byte (differences highlighted in the hex view).
- Write a file at an offset. By default the 4 KiB sectors it touches are erased first, the bytes of those sectors outside the range are read before and written back, and the result is verified.
- Erase a range: widened to 4 KiB sectors, 64 KiB blocks inside, chip erase for the whole flash; optional blank check.
Writes and erases ask for confirmation with the exact range. The flash map
shows the selected range, what an erase will touch, the firmware file's
area and the start addresses of the APP and DFU images (flashAddr /
dfuAddr in src/devices.js; only starts, their lengths are not known);
a write or erase that covers one of them is called out before it runs.
Click 0x0 or an APP / DFU label on the map to use it as the offset; the
chips under the length give common sizes. Offsets and lengths accept
0x10000, 10000h, 65536, 64K, 1M.
| Step | SLogic32U3 | SLogic16U3 |
|---|---|---|
| Enter update mode (DFU) | automatic: USB RECONFIG request | automatic from firmware 202610230648; older firmware: user presses MODE |
| Check flash | bridge reset, JEDEC ID, flash size check | same |
| Erase / blank check / write / verify | 64 KiB erases, read back blank, page program (48 B per transaction), full read-back compare | same, 12 B per transaction |
| Restart | automatic: USB RECONFIG request | tried over USB; works with the update-mode image 15k_usb_dfu-202610221618, otherwise (board stays in update mode for 5 s) the page asks for a re-plug |
| Mode | USB ID |
|---|---|
| SLogic16U3 normal / update | 359f:3031 / 359f:30f1 |
| SLogic32U3 normal / update | 359f:3032 / 359f:30f2 (early update firmware used 30f1) |
A browser only lets a page open devices the user picked in its device dialog. The update-mode device ("SLogic DFU") has a different USB ID and no serial number, so the browser cannot remember it: each update asks for one extra click ("Select update-mode device"). Everything else runs on its own.
Measured on an SLogic32U3 (Linux, 1.7 MB image): about 40 s in total, of which erase 2 s, blank check 6 s, write 24 s, verify 6 s. On an SLogic16U3 with firmware 202610230648 and the new update-mode image (0.5 MB image): 31 s, switching both ways over USB.
The page cannot read the update-mode image's version (the device reports no
serial number in update mode), so for a SLogic16U3 it decides from the
normal-mode firmware (reconfigSince in src/devices.js) whether to switch
in over USB, and finds out at the restart whether the update-mode image takes
the request. ?demo=16u3-new simulates such a board.
The flash protocol (USB-SPI bridge packets, SPI NOR commands, chunk sizes) is
taken from the production flasher in the SLogic production-test tools
(slogicpt/dfu, resources/products/*/product.toml [ota]).
For production: choose the model and the firmware once, press Start, then keep plugging in boards. Every board is updated in parallel as soon as it appears; the page lists each board with its state and a progress bar, plus counters (done / in progress / waiting / failed / completed this session).
The page mirrors the board's status LED so the operator can work by the LED:
| LED | Meaning |
|---|---|
| steady cyan | done (or normal mode): unplug it |
| cyan + slow red blink | update mode: being updated, leave it plugged in |
- New boards from the factory arrive in update mode and are written as soon as they are plugged in; a SLogic32U3 then restarts into normal mode.
- Boards in normal mode are left alone by default (on a production line that is usually a board that is already done). For rework or returned units, tick the rework option: SLogic32U3 boards in normal mode are then switched to update mode automatically. A board that already reports the new firmware S/N is never updated again.
- SLogic16U3 boards are updated when they arrive in update mode (MODE button); when done they stay in update mode until re-plugged.
- Boards of the other model are flagged and left alone.
Station setup. The update-mode device has no USB serial number, so a
browser normally asks for permission for every board. The batch page's
"Station setup" section installs the browser policy WebUsbAllowDevicesForUrls
for the site the pages are published on, https://slogic.sipeed.com
(STATION_ORIGIN in src/station.js; any path on that site), so boards are
picked up without any click. A web page
cannot change system settings itself, so the buttons download a file to run
once:
| OS | Install | Remove |
|---|---|---|
| Windows | slogic-webusb-install.reg: double-click, confirm (admin) |
slogic-webusb-remove.reg |
| macOS | slogic-webusb.mobileconfig: open, then approve in System Settings › Privacy & Security › Profiles |
remove the profile there |
| Linux | sudo sh slogic-webusb-install.sh (also installs the udev rule) |
sudo sh slogic-webusb-remove.sh |
Chrome and Edge are covered (plus Chromium and Brave on Linux); restart the
browser afterwards and check chrome://policy. While installed, the browser
shows "managed by your organization". Without the policy, or when the page is
opened from another address (e.g. serve.py --lan), "Add device manually"
adds boards one at a time through the browser's dialog.
Preview without hardware: batch.html?demo (simulated operator plugging and
unplugging boards) or batch.html?demo=16u3.
-
Linux: the browser needs access to the USB device. Install a udev rule covering the update-mode IDs too, then re-plug:
sudo tee /etc/udev/rules.d/60-slogic.rules >/dev/null <<'EOF' SUBSYSTEM=="usb", ATTRS{idVendor}=="359f", ATTRS{idProduct}=="0300|3031|3032|30f1|30f2", MODE="0666", TAG+="uaccess" EOF sudo udevadm control --reload-rules && sudo udevadm trigger
-
Windows: WebUSB needs the WinUSB driver on the update-mode device. If it does not appear in the browser's device dialog, check Device Manager.
-
Close SLogicView, PulseView, AllLogic, ngscopeclient and sigrok-cli first: a device that another program has open cannot be switched to update mode.
index.html, style.css, favicon.svg the page
firmware.json firmware version table (min / latest per model); published
with the pages, also read by sipeed/SLogic's release notes
batch.html batch update page
src/app.js page controller (UI state, progress, prompts)
src/batch.js batch page controller
src/batch-engine.js batch logic: device tracking, parallel updates, board states
src/led.js status LED icon
src/updater.js the update sequence: mode switch, recovery, flash, restart
src/flash.js SPI NOR operations and erase/program/verify
src/flashops.js advanced mode: read / write / erase at any offset
src/advanced.js advanced mode UI (flash tools card, hex view)
src/spi.js USB-SPI bridge packets and registers
src/usb.js WebUSB bulk transport, RECONFIG request
src/devices.js model table, USB IDs, update parameters, file checks
src/i18n.js English / Chinese strings
src/demo.js ?demo: simulated WebUSB device and flash
test/ node tests (node --test test/*.test.mjs)
node --test test/*.test.mjs-
replay.test.mjsreplays USB transcripts recorded from the reference Python flasher (test/gen_transcript.py) and requires byte-identical traffic, plus error paths (verify mismatch, hung bus, cancel). To record a new transcript:python3 test/gen_transcript.py <SLogic16U3-tools dir> /tmp/t.json --size 0x10200 --write-chunk 48 EXTRA_TRANSCRIPTS=/tmp/t.json node --test test/*.test.mjs
-
updater.test.mjsruns the whole update for both models against the demo device and checks the flash content. -
batch.test.mjsruns batches of simulated boards (mixed modes, parallel, unplug/replug, already-updated and wrong-model boards). -
devices.test.mjscovers model identification and firmware warnings. -
firmware.test.mjschecks the format offirmware.json.