- Add device_name module: NVS-persisted custom name with MAC-suffix
fallback (Velxio-XXXX) so every device is uniquely identifiable
out-of-the-box in BLE pairing dialog
- Add wifi_ap module: first-boot SoftAP (Velxio-Setup-XXXX / velxio123)
with embedded HTTP config portal at 192.168.4.1 for renaming
- main.c: enter AP setup mode when no custom name is set
- ble_service.c: use dynamic device name from device_name_get(),
with adv-packet length guard
- led_button.c: BOOT button long-press (5s) factory reset (erase NVS)
- sdkconfig.defaults: enable WiFi stack + set NimBLE default name
Frontend deviceName display already committed in 01f68d3.
v3.1 enhancements (4 Jul 2026):
- Baud dropdown (9600/19200/38400) + CMD_SET_BAUD
- LED blink patterns per-state (IDLE/RECEIVING/FLASHING/SERIAL_BRIDGE)
- Arduino event-based connect/disconnect (CherryUSB)
- Serial terminal always visible saat paired
- Re-deploy fix: serial_bridge_stop before parser
- Dual baud: 115200 STK500 + 9600 serial bridge
- Footer v15, SW cache v14
This is a checkpoint commit. Next cycle: port Deploy from
SvelteKit (DeployTab.svelte) to Velxio React app (native integration).
DeployTab.svelte will be deprecated after port complete.
Akar masalah:
- 4a6ef8c menambah binary_parser_reset() di handler re-deploy SERIAL_BRIDGE
yang menghapus expected_total_crc setelah INIT — menyebabkan CRC mismatch
di END. Source 1d3a489 sudah menghapus reset-nya, tapi device butuh rebuild.
- cad90eb merutekan DATA melalui sendCommand() dengan readPoll state===1
yang selalu true saat DATA — write gagal dilaporkan sukses.
Perbaikan:
1. readPoll pintar untuk DATA: state===1 tidak lagi dianggap sukses.
readPoll hanya fast-fail di state>=5; deadline fallback hanya ok
jika writeValueWithResponse sukses (GATT write response = bukti delivery).
2. INIT_ACK_INDEX=0xFFFE (Fase 3): inisialisasi INIT dengan index unik
menghilangkan tabrakan dengan DATA[0] (index 0). binary_parser.c echo
index recv di ACK INIT. Guard handleFlashingNotification diperluas.
3. pendingAcks.clear() di awal deployHex mencegah poisoning antar deploy.
4. Track firmware inti ke git: binary_parser.c, checksum.c, stk500v1.c,
usb_host.c + headers + CMakeLists + sdkconfig + partitions.
Build: ESP-IDF v6, ESP32-S3, flash via /dev/ttyACM0
serial_bridge.c + .h:
- Implement 20pkt/s throttle with 240-byte buffer
- serial_bridge_on_usb_data() for buffering USB serial data
- Flush every 50ms or 500ms stale timeout
led_button.c + .h:
- Per-color LED blink toggle in led_button_tick()
- BLUE_BLINK 200ms, RED_BLINK 100ms, GREEN_BLINK 200ms
- Fix: was set_led(true,true,true) for all blink patterns
main.c:
- Route USB serial data through serial_bridge_on_usb_data
- Add led_button_tick() call in main loop
state_machine.c:
- Add binary_parser_reset() on SERIAL_BRIDGE re-deploy
Firmware (state_machine.c):
- Add EVENT_BLE_INIT handler to SERIAL_BRIDGE state
-> transition back to RECEIVING for re-deploy
- Add EVENT_BLE_INIT handler to ERROR states
-> allows re-deploy from error without pressing Retry
Frontend (ble-deployer.ts):
- Add readValue() state poll for INIT and DATA commands
(same Android notify idle-drop bug affects these too)
- INIT success: firmware state >= 1 (RECEIVING+)
- DATA success: firmware state == 1 (RECEIVING)
- Error on state >= 5