# Ameba Control Panel (PySide) ## Goal Build a PySide-based desktop app titled **“Ameba Control Panel”**. It serves three Ameba families—AmebaPro3 (RTL8735C), AmebaPro2 (RTL8735B), AmebaSmart (RTL8730E)—each on its own tab. The app must prioritize responsive UART interactions, smooth log rendering, and safe concurrent execution. ## Architecture & Design - Use an explicit OOP structure: separate UI widgets (views), controllers (signal/slot glue), and services (serial I/O, command history, process runners). No “minimal” scripts—prefer clearly named classes and modules. - Tabs: one tab per device class; each tab owns its own controller/service instances (no shared mutable state across tabs). - Event loop: base on PySide6 (Qt 6). Encapsulate threading via `QThread`/`QObject` workers for serial I/O; use `multiprocessing` (or `concurrent.futures.ProcessPoolExecutor`) for heavy parsing or binary tasks to keep the UI thread idle. - Allow optional C/C++ extensions (e.g., pybind11) for high-throughput UART parsing; isolate behind a Python service interface so the GUI remains unchanged if the extension is absent. ## Per-Tab Requirements - Connection controls: COM port dropdown (full system path/name), baudrate dropdown+editable field (populate with common values; default 1500000). Connect/Disconnect toggle shows live status. - UART console: fast-rendering log view with timestamps per line; color-differentiate TX vs RX (no text prefixes); must support copy/paste, multi-range selection, and full scrolling (vertical and horizontal). Provide `Clear`, `Save`, and `Copy` actions. Maintain an in-memory ring buffer to avoid UI lag on high traffic. (Current build hides TX lines in the UI log; only RX/INFO show.) - Find/search: non-blocking search over buffered logs; case-sensitive toggle plus case-insensitive default; highlight matches; provide Find/Next/Previous/All actions. Perform search in a worker to avoid UI stalls and apply highlights on completion. - Command entry: text input + `Send` button + Enter to send. On send, append to history unless it is a duplicate of the most recent entry (skip duplicates). - Command history pane on the left: scrollable (vertical and horizontal), single-click focuses and loads the command into the input bar; double-click sends immediately without duplicating the entry; `Delete` key removes the selected record. Persist history per device tab under `%LocalAppData%/AmebaControlPanel//history.txt`. - Background port refresh on change events; only mutate the COM list when a port is added or removed. Maintain a stable, non-reordered dropdown: preserve existing order/selection and insert newcomers deterministically (e.g., append sorted new ports). Log connection state changes in the console. (Port additions are intentionally not logged; removals are.) - Command-list loader: file Browseer accepts `.txt` with one command per line; `Load CmdList` button streams commands out automatically with a user-configurable per-command delay and per-character delay. ## Logging & Performance - Timestamp format `YYYY-MM-DD HH:MM:SS.mmm`. Store both full archive and UI tail (e.g., last 100k lines) for quick redraws. - Use a batched append pipeline: gather serial lines in a thread-safe queue; UI thread flushes at short intervals (e.g., 30–60 Hz) to keep scrolling smooth. - Multi-select copy should concatenate selected ranges with timestamps preserved. ## Concurrency Rules - Serial read/write happens in dedicated `QThread` workers; UI never blocks on I/O. - Use signals for crossing threads; avoid direct widget access from workers. - For CPU-heavy tasks (parsing, file save), delegate to a `ProcessPoolExecutor`; C/C++ extensions (e.g., pybind11 modules) are encouraged where performance-critical, keeping a Python fallback. - Ensure clean teardown: on tab close or app exit, stop workers, flush queues, and close ports gracefully. ## Backend Interfaces - Serial service API: `open(port, baud)`, `close()`, `write(bytes)`, `signal line_received(str, direction)`, `signal status_changed(state)`. - History service: `load()`, `save(entries)`, `add(entry)`, `delete(entry)`. - Optional C/C++ module: provide drop-in replacements for line framing or log buffering; keep a pure-Python fallback. ## Current Implementation Notes (2026-02-05) - UART writes default to `\r\n` (CRLF) line endings to satisfy Ameba monitor commands. - Flash action closes the DUT UART, runs `flash_amebapro3.py`, reconnects, then triggers an auto “Normal mode” step after ~100 ms while keeping the port open. - Download mode, Normal mode (manual button), and Device Reset now run without closing/reopening the DUT UART; connection state stays steady. - TX log lines are suppressed in the UI; RX/INFO still render with timestamps and colors. - Port additions are not logged; port removals are. - In frozen/packaged builds, the flash helper runs **in-process** (inline) using the bundled Python runtime; no external Python is required. Non-frozen/dev builds still shell out to the system interpreter. - When packaging, include hidden imports `pyDes`, `colorama`; `package_exe.py` already adds these. ## Snapshot for PySide Rewrite (layout + behavior) - Tabs: three device tabs, each fully isolated (own controller/services). Keep the per-tab state separation when porting. - Layout (per tab): - Top rows: DUT COM dropdown + Refresh + Baud + Connect toggle; Control COM dropdown + Baud; Mode buttons (Normal/Download/Reset) aligned right. - Flash rows: App path + Browse, Boot path + Browse + Flash. - Bottom split: left fixed-width history list (~220 px); right column with Log view, Find row (input + case toggle + find/next/prev/all), Command-list row (file path + Browse + per-cmd delay + per-char delay + Load), Command entry row (input + Send). - Styling: light “Fusion” palette; monospaced log font (JetBrains Mono/Consolas fallback), modest padding/margins; log colors—RX green-ish (#1b5e20), TX (currently hidden) blue-ish (#0d47a1), INFO gray (#424242); timestamps `YYYY-MM-DD HH:MM:SS.mmm`. - Logging pipeline: serial worker enqueues lines into `SimpleQueue`; a Qt timer flushes every ~30 ms, appends to the log view, maintains tail buffer via `LogBuffer` (max ~10k lines in UI tail, full archive available for save); perf label shows lines/sec and queue depth updated ~1 Hz. - Search: uses Qt document find for next/prev; “Find all” scans full log text, highlights matches. - History: single-click loads into input; double-click sends immediately; Delete key removes; duplicates skipped on consecutive add; persisted per device under `%LocalAppData%/AmebaControlPanel//history.txt`. - Command send: Enter or Send button; CRLF appended; TX hidden from UI log. - Command list playback: loads .txt (one command/line); per-command delay (ms) and per-char delay; stops if disconnected; appends to history without duplicate of last. - Port refresh: 2s timer; stable ordering; auto-reconnect when previously active port returns; logs removals only. - Flash/mode/reset: uses `Flash/flash_amebapro3.py`; in packaged build runs inline (no external python) with stdout/stderr piped to log; flash closes DUT UART, reopens, auto Normal-mode after 300 ms; mode/reset keep UART open. ## UI Layout (per tab) - Top bar uses three rows: **Row 1** houses the COM port dropdown (full path/name), baudrate input, and the right-aligned `Normal Mode`, `Download Mode`, `Device Reset` buttons. **Row 2** holds the application filepath bar (editable, shows full path/name) with its Browseer. **Row 3** holds the bootloader filepath bar with its Browseer and the `Flash` button (flashes app + bootloader via UART). - Bottom split: left pane is the command history list (fixed ~220px) with delete/load/save; right pane is the console/log area with the log view, a dedicated find bar immediately below the log (case toggle + find/find next/prev/all), then a row for the command-list loader (filepath input + Browseer + delay + `Load CmdList`) directly above the bottom command input row (text field left, `Send` button right). - Apply a light theme; use consistent spacing/padding; fonts legible and monospaced for log areas. - COM port dropdown should show port name plus description; actions use the underlying device path. - File Browseers must expose an editable input bar showing the selected file name and full path; the application/bootloader filepath bars, their Browseer buttons, and the `Flash` button sit on the second row alongside the COM port dropdown and baudrate input. - Command list filepath input + file Browseer and its controls live in the bottom section, on the row above command entry; the Browseer still appears to the left of the cmd delay controls. - Flash/Mode/Reset actions call `Flash/flash_amebapro3.py`: - Flash: `--boot --app -t -p -B ` (baudrate matches DUT COM port, Close the UART before invoking (tool needs exclusive handle) and reconnect afterward if it was previously connected.) - Download Mode: `--download-mode 1 -t -p -B ` (baudrate matches DUT COM port) - Normal Mode: `--download-mode 0 -t -p -B ` (baudrate matches DUT COM port) - Device Reset: `--reset -t -p ` (baudrate matches DUT COM port) - Log text color adapts to theme: white on dark, black on light; RX/TX/INFO colors adjust accordingly. ### Layout sketch (not to scale) ``` Top Row 1: [ DUT COM dropdown | Baudrate | Connect/Disconnect | Refresh] Top Row 2: [ Control Devices COM dropdown | Baudrate | Connect] ]---- [ Normal Mode ][ Download Mode ][ Device Reset ] Top Row 3: [ Application filepath input ]---- [ Browse ] Top Row 4: [ Bootloader filepath input ]----[ Browse | Flash ] Bottom Left Pane: Command History list (fixed ~220px width, no wrap, left & right scrollable) Bottom Right Pane: [ Log view ] [ Find row: text input ---------------------- case toggle | find | next | prev | all ] [ Command-list row: Command File filepath | Browse | Delay | Load ] [ Command entry row: text input --------------------------- | Send ] ``` ## Testing & Diagnostics - Add simple perf counters (lines/sec, queue depth) displayed in status bar or debug overlay to verify “fast enough” logging. ## Packaging - Target Python 3.11+ with PySide6. Provide `requirements.txt` and a short `README` snippet for running. - Keep C/C++ extension optional; guard imports and present a clear message if missing. - Add a `script/` directory containing: - `auto_run.py`: launches the GUI with any needed environment bootstrapping (PYTHONPATH, dll search path, etc.). - `package_exe.py` (or `.bat`/`.sh` wrapper) to build a standalone executable (e.g., via PyInstaller) bundling all Python deps, C/C++ extensions, and helper scripts; ensure the packaged env includes needed DLLs and preserves the light theme assets. When bundling, include the entire `Flash/` folder (e.g., PyInstaller `--add-data "Flash;Flash"` on Windows pathsep rules) so `flash_amebapro3.py` is available inside the frozen bundle.