- Add FT601Connection in radar_protocol.py using ftd3xx library with
proper setChipConfiguration re-enumeration handling (close, wait 2s,
re-open) and 4-byte write alignment
- Add USB Interface dropdown to V65 Tk GUI (FT2232H default, FT601 option)
- Add USB Interface combo to V7 PyQt dashboard with Live/File mode toggle
- Fix mock frame_start bit 7 in both FT2232H and FT601 connections
- Use FPGA range data from USB packets instead of recomputing in Python
- Export FT601Connection from v7/hardware.py and v7/__init__.py
- Add 7 FT601Connection tests (91 total in test_GUI_V65_Tk.py)
Rename radar_dashboard.py -> GUI_V65_Tk.py and add core feature parity
with the v7 PyQt dashboard while keeping Tkinter as the framework:
Replay mode:
- _ReplayController with threading.Event-based play/pause/stop
- Reuses v7.ReplayEngine and v7.SoftwareFPGA for all 3 input formats
- Dual dispatch routes FPGA control opcodes to SoftwareFPGA during
raw IQ replay; non-routable opcodes show user-visible status message
- Seek slider with re-emit guard, speed combo, loop checkbox
- close() properly releases engine file handles on stop/reload
Demo mode:
- DemoTarget kinematics scaled to physical range grid (~307m max)
- DemoSimulator generates synthetic RadarFrames with Gaussian blobs
- Targets table (ttk.Treeview) updates from demo target list
Mode exclusion (bidirectional):
- Connect stops active demo/replay before starting acquisition
- Replay load stops previous controller and demo before loading
- Demo start stops active replay; refuses if live-connected
- --live/--replay/--demo in mutually exclusive CLI arg group
Bug fixes:
- seek() now increments past emitted frame to prevent re-emit on resume
- Failed replay load nulls controller ref to prevent dangling state
Tests: 17 new tests for DemoTarget, DemoSimulator, _ReplayController
CI: all 4 jobs pass (167+21+25+29 = 242 tests)