Root cause: missing SPI_SET_PARAMS (CMD 0x0B) before flash_begin.
ROM bootloader defaults to 2MB flash size, silently truncating
writes to 16MB flash. Progress bar showed success but firmware
was corrupt.
Changes:
- Add spi_set_params() with 16MB geometry before flash_begin
- Add MD5 verification after write (SPI_FLASH_MD5, CMD 0x13)
- Add retry logic (3 attempts per block)
- Pad firmware to 4-byte boundary
- flash_end(reboot=false) then separate hard reset after MD5 check
- Pure Rust MD5 implementation (no external crate)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Firmware sends: "KO2: 0B+02->4C+00"
Parser expected: "KO0: trigger=2A mod=02 -> result=4C resmod=00"
Rewrote parse_ko_lines to match real format:
<trigger_hex>+<mod_hex>-><result_hex>+<mod_hex>
Also skips "KO 0 deleted" and "KOSET 1:OK" lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full port of the KaSe/KeSp split keyboard configurator from egui to Slint:
- 6 tabs: Keymap, Advanced, Macros, Stats, Settings, Flash
- Responsive keyboard view with scale-to-fit and key rotations
- Key selector popup with categorized grid, MT/LT builders, hex input
- Combo key picker with inline keyboard visual
- Macro step builder with visual tags
- Serial communication via background threads + mpsc polling
- Heatmap overlay with blue-yellow-red gradient
- OTA flasher with prog port VID filtering and partition selector
- WPM polling, Tamagotchi, Autoshift controls
- Dracula theme matching egui version
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>