Browser-based USB DFU flash programmer for the STM32F723, using the factory ROM bootloader over USB Full-Speed. No drivers, no desktop software — runs entirely in Chrome via the WebUSB API.
Program the STM32F723 flash from a .hex or .bin file through the device's built-in ROM bootloader (USB DFU / DfuSe mode), erasing and writing only the flash sectors touched by the file. All other flash is left intact.
Pure HTML/JS/CSS — no build step, no npm, no server-side component.
stm32programmer/
├── index.html UI shell
├── style.css Dark theme
└── src/
├── hex-parser.js Intel HEX + BIN parser → [{address, data}]
├── dfu.js DfuSe protocol over WebUSB
└── app.js Event wiring, USB lifecycle, progress
The STM32 ROM bootloader exposes a USB DFU class device (DfuSe variant):
| Field | Value |
|---|---|
| USB VID | 0x0483 (STMicroelectronics) |
| USB PID | 0xDF11 (DFU mode) |
| Transfer size | 2048 bytes |
| Protocol | DFU 1.1 + ST DfuSe extensions |
DFU operations used:
| Request | Code | Purpose |
|---|---|---|
DNLOAD |
0x01 |
Write block / special command |
UPLOAD |
0x02 |
Read block (verify) |
GETSTATUS |
0x03 |
Poll state machine |
CLRSTATUS |
0x04 |
Clear error |
ABORT |
0x06 |
Return to dfuIDLE |
DfuSe special commands (sent as DNLOAD wBlockNum=0):
| Byte 0 | Command | Effect |
|---|---|---|
0x21 |
SET_ADDRESS |
Set base address for subsequent data blocks |
0x41 |
ERASE |
Erase the sector containing the given address |
Write sequence per segment:
- Erase each overlapping sector via
ERASEcommand SET_ADDRESSto segment startDNLOAD wBlockNum=2,3,4…for each 2 KB chunk- (Optional)
UPLOADto read back and verify byte-by-byte - (Optional)
SET_ADDRESS(0x08000000)+ zero-lengthDNLOAD wBlockNum=2to trigger jump to app
| Sector | Start | Size |
|---|---|---|
| 0 | 0x08000000 |
16 KB |
| 1 | 0x08004000 |
16 KB |
| 2 | 0x08008000 |
16 KB |
| 3 | 0x0800C000 |
16 KB |
| 4 | 0x08010000 |
64 KB |
| 5 | 0x08020000 |
128 KB |
| 6 | 0x08040000 |
128 KB |
| 7 | 0x08060000 |
128 KB (xE 512 KB variant only) |
The app auto-detects the map from the DfuSe interface string descriptor. The hardcoded table above is the fallback.
- Pull BOOT0 pin high (connect to VCC or assert via solder bridge/switch).
- Reset the device (press reset button or cycle power).
- The STM32 will enumerate as a DFU device — no firmware runs.
Confirm the device is visible:
- macOS/Linux:
lsusb→ should showSTMicroelectronics STM Device in DFU Mode - Windows: Device Manager →
Universal Serial Bus devices→STM Device in DFU Mode
WebUSB requires a secure context (HTTPS or localhost). Start the server from the project folder:
cd /path/to/stm32programmer
python3 -m http.server 8080Then open Chrome (not Safari, Firefox, or Edge) and navigate to:
http://localhost:8080
- Drag and drop a
.hexor.binfile onto the drop zone, or click to browse. - For
.hexfiles: target addresses are read from the file automatically. - For
.binfiles: enter the Flash address where the binary should be loaded (default0x08000000).
The status line shows the number of segments and total byte count.
Click Connect Device. Chrome will show a USB device picker — select the STM32 DFU entry.
On success the device name and sector count appear. If the DfuSe interface string is readable, the exact sector map for your variant is used automatically.
Click Program Flash.
Progress is shown in three phases:
| Bar | What it shows |
|---|---|
| Erase | Sectors erased / total sectors to erase |
| Write | KB written / total KB |
| Verify | KB read back and confirmed (if enabled) |
Verify after write (checked by default): reads every written byte back from flash and compares it to the source file. The first mismatch is reported with its address and both values.
Leave DFU & reset (checked by default): after programming (and verify), triggers the ROM bootloader to jump to 0x08000000 and run your firmware. The device will disconnect from USB.
| Option | Default | Effect |
|---|---|---|
| Verify after write | ✓ on | Read-back and byte-compare every written address |
| Leave DFU & reset | ✓ on | Jump to application after programming |
| Symptom | Likely cause | Fix |
|---|---|---|
| "WebUSB not available" | Not Chrome, or not on localhost/HTTPS | Use Chrome at http://localhost:8080 |
| Device not listed in picker | Not in DFU mode | Check BOOT0 and reset |
| "Access denied" or "device in use" | Another tool (STM32CubeProgrammer, dfu-util) has the device | Close the other tool |
| Verify mismatch | Write error or wrong address | Check that the hex/bin targets the correct flash region; retry |
| Device disconnects mid-write | USB cable issue or device reset | Use a short, quality USB cable; retry |
| "Cannot reach idle state" | Device stuck in error | Disconnect, power-cycle the STM32, reconnect |