Commit Graph

138 Commits

Author SHA1 Message Date
a2nr 0cbac64c6f feat(frontend): Velxio iframe fullscreen + playground route + SvelteKit service worker
- VelxioTab: add allowfullscreen to Velxio editor iframe
- lesson.css: flex/shrink fixes for .velxio-iframe on mobile
- +layout.svelte: hide Navbar/Footer on /playground full-viewport route
- Add /playground route: Velxio editor iframe + DeployFAB bridge
- Migrate static sw.js to SvelteKit module service-worker.ts
2026-07-18 17:26:59 +07:00
a2nr d6bb2073ac feat: add markdown link support for lesson prerequisites
- Update lesson_service.py to parse markdown link format [title](path)
- Convert all lesson files to use markdown link format for prerequisites
- Backend now extracts slug directly from link path
- Supports both plain text and markdown link formats
2026-07-18 07:31:10 +07:00
a2nr cf3131bed3 chore: update velxio submodule — DeployProgress UI + SerialMonitor BLE toggle 2026-07-18 06:56:20 +07:00
a2nr a0fb1d80cd feat(velxio-deployer): unique device name + WiFi AP setup mode
- 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.
2026-07-18 06:50:10 +07:00
a2nr f164134222 fix(usb-deployer): CH340 port reuse fix — skip reopen, single DTR, baud tracking 2026-07-17 14:35:30 +07:00
a2nr 2773bf2a83 feat(usb-deployer): double DTR reset + post-write delay for stubborn clones 2026-07-17 12:47:58 +07:00
a2nr 95a3569be9 chore: bump version to v17 2026-07-17 11:07:46 +07:00
a2nr 8adc28b745 refactor(usb-deployer): use named settle constant and fix comment 2026-07-17 10:38:40 +07:00
a2nr 852fccacdf fix(usb-deployer): rebalance sync retries/backoff for optiboot window 2026-07-17 10:37:57 +07:00
a2nr 2fd2b1b5b4 fix: register SvelteKit service-worker.js instead of static sw.js 2026-07-17 10:37:48 +07:00
a2nr 84827350af fix(usb-deployer): drain stray bytes until quiet window 2026-07-17 10:37:08 +07:00
a2nr 3d941191e3 refactor(usb-deployer): name timing constants for sync window tuning 2026-07-17 10:35:23 +07:00
a2nr 4ec5d4cb92 fix(usb-deployer): add detailed diagnostic logging for sync failures 2026-07-17 10:24:39 +07:00
a2nr 7dd8e5d522 fix(usb-deployer): preliminary get_sync robustness improvements 2026-07-17 10:23:39 +07:00
a2nr 24db01fd8d refactor: Footer.svelte imports APP_VERSION from $lib/version 2026-07-17 09:46:29 +07:00
a2nr 12725cbdad chore: bump version to v16 2026-07-17 09:26:17 +07:00
a2nr 01f68d354a fix: disable toggle during deploy, SSR guard for matchMedia, reactive isDesktop, safe deployBinary guard 2026-07-17 08:20:56 +07:00
a2nr 185fed636e feat: add BLE/USB toggle with auto-detect in DeployTab 2026-07-17 08:17:54 +07:00
a2nr 369897529d fix: harden USBHardwareDeployer — drain after timeout, async cleanup, flash error recovery, baud切换 2026-07-17 08:15:21 +07:00
a2nr f8e92875c9 feat: add USBHardwareDeployer with STK500v1 protocol via Web Serial API 2026-07-17 08:10:12 +07:00
a2nr 1b51e75ff0 feat: add HardwareDeployer interface, BLEHardwareDeployer implements it 2026-07-17 08:03:42 +07:00
a2nr 029efb7464 feat: convert Intel HEX to binary_content for AVR/Arduino Uno in velxio-compile route 2026-07-17 08:02:50 +07:00
a2nr a7c9d1c499 fix(deploy-tab): await handleOpenSerial() in deploy success path for proper error handling 2026-07-05 17:53:45 +07:00
a2nr bb19523f65 feat(deploy-tab): auto re-pair before deploy if connection lost 2026-07-05 17:49:40 +07:00
a2nr 87364da0c5 feat(deploy-fab): auto-reset Arduino when starting serial monitor 2026-07-05 17:48:44 +07:00
a2nr f6b57c08d1 feat(deploy-tab): auto-reset Arduino when starting serial monitor 2026-07-05 17:48:31 +07:00
a2nr bb113e6ff2 fix(ble-deployer): send ACK after CMD_RESET handler 2026-07-05 17:47:52 +07:00
a2nr c6c6daecbf feat(ble-deployer): add resetArduino() method for DTR pulse 2026-07-05 17:46:32 +07:00
a2nr a18d3f660c feat(ble-deployer): add CMD_RESET for Arduino DTR pulse reset 2026-07-05 17:38:40 +07:00
a2nr bba06933bd feat(elemes): v3.1 checkpoint — BLE deployer enhancements before port to Velxio
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.
2026-07-04 20:21:46 +07:00
a2nr 3dd29e1ba1 revert: DATA sendCommandWithRetry ke f6a04b8 (direct write+waitForAck, no readPoll)
cad90eb merutekan DATA melalui sendCommand() dengan readPoll state===1
yang selalu true — menyebabkan chunk lambat 5s/kirim saat ACK di-drop.
Kembalikan ke direct writeValueWithResponse + waitForAck.
Selama transfer aktif tidak ada idle gap (Qualcomm >8s), jadi ACK notify
tidak terpengaruh idle-drop.

Perubahan:
- sendCommandWithRetry: build payload sendiri, pakai chunkCRC param,
  write+waitForAck langsung (tidak lewat sendCommand)
- sendCommand: hanya handle INIT dan END (DATA dihapus dari blok)
- Hapus writeSucceeded flag (tidak lagi dipakai)
- Hapus readPoll fallback untuk DATA
- Bump v12 (Footer + SW cache)
2026-07-01 06:07:57 +07:00
a2nr 26ada16c4d feat(frontend): bump version badge + SW cache to v11 for deploy verification 2026-07-01 05:12:42 +07:00
a2nr c20b2d5a8e fix: END ACK regression — readPoll pintar + INIT_ACK_INDEX 0xFFFE + binary_parser.c git track
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
2026-07-01 05:10:38 +07:00
a2nr d146e445d6 feat(frontend): add version badge (v10) in footer for deploy verification 2026-06-30 19:39:15 +07:00
a2nr 1d3a48940e fix(firmware+frontend): remove binary_parser_reset() re-deploy wipes CRC + tighten INIT poll
Firmware (state_machine.c):
- Remove binary_parser_reset() from SERIAL_BRIDGE→RECEIVING handler
- Remove binary_parser_reset() from ERROR→RECEIVING handler
- Parser's INIT handler already resets itself; calling reset AFTER
  INIT payload processing wipes expected_total_crc to 0 → CRC fail

Frontend (ble-deployer.ts):
- Tighten INIT readValue poll: state===1 (RECEIVING) only
  Previously accepted state >= 1 && <= 4 which could false-positive
  on FLASHING(3) or SERIAL_BRIDGE(4) stale states

Cache v9 → v10
2026-06-30 19:21:35 +07:00
a2nr 6ccbb88678 bump(frontend): cache v8→v9 for clean SW refresh 2026-06-30 18:32:05 +07:00
a2nr cad90ebd2e fix(frontend): route DATA through sendCommand for readValue() fallback
sendCommandWithRetry now delegates to sendCommand() instead of
using raw writeValueWithResponse + await ackPromise. This ensures
DATA chunks also benefit from the readValue() state poll fallback
when Android BLE notify is unreliable after idle.
2026-06-30 18:14:03 +07:00
a2nr 4a6ef8ce57 feat(firmware): serial bridge throttle, LED blink fix, re-deploy safety
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
2026-06-30 18:13:42 +07:00
a2nr f6a04b81ba fix: re-deploy crash + readValue poll for INIT/DATA
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
2026-06-30 17:55:26 +07:00
a2nr 9918aafe41 fix: Phase B — readValue() state poll fallback for END ACK
Firmware:
- Add BLE_GATT_CHR_F_READ to flashing characteristic
- Read callback returns state_machine_get_current() as 1 byte
  (4=SERIAL_BRIDGE=success, 5/6=ERROR)

Frontend:
- Replace ineffective pendingAcks poll with readValue() poll
- CCCD refresh fire-and-forget (non-blocking)
- Race ackPromise (notify) vs readPoll (readValue)
- Clean up ackPromise resolver on readPoll win
- Cache v7 → v8
2026-06-30 17:35:23 +07:00
a2nr 9dda8fe3e6 fix: event-driven poll loop for END ACK to work around Android BLE notification delivery issue on Qualcomm chipsets
- Race ackPromise against a polling loop that yields to the event loop
  every 200ms (vs a single blocking await that can miss notifications)
- bump SW cache v5→v6
2026-06-30 13:12:55 +07:00
a2nr e4ec3f1ded feat: custom evaluation config 2026-06-17 20:34:36 +07:00
a2nr 120a1338c0 feat: enhance fullscreen mode slide and hide able slide 2026-05-14 20:25:21 +07:00
a2nr bc49877123 feat: update to support folder inside content folder to easy to manage 2026-05-14 19:45:10 +07:00
a2nr 8485425d0f docs: add slide tutorial for teacher 2026-05-14 19:04:24 +07:00
a2nr 58e897f743 feat: add markdown-based interactive slide carousel with fullscreen mode 2026-05-14 18:53:46 +07:00
a2nr 9e5617274e add : docomentation 2026-05-14 16:33:45 +07:00
a2nr 7384b6e585 feat: readable content: 2026-05-14 16:26:11 +07:00
a2nr 5f150da651 fix: progress path fix 2026-05-12 14:49:18 +07:00
a2nr 86d2851593 fix: generate token only change progress lesson 2026-05-12 08:37:25 +07:00