When writing to factory (0x20000), automatically erase the otadata
partition (0xF000, 8KB) by writing 0xFF blocks. This forces the
bootloader to fall back to factory on next boot, instead of
continuing to boot from ota_0.
Without this, flashing factory "succeeds" but the ESP keeps
booting the old firmware from ota_0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>