Files
HW-Debug-Tools/agent.md
T
hulk c26d2cdbaa feat: 新增 SerialMate 串口调试助手 v0.1.0
- 协议帧构成令牌序列可定制(包头/板ID/LEN口径/5种CRC x 3种覆盖), 默认兼容 DLPilot 光机协议
2026-09-27 18:52:54 +08:00

209 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# agent.md — 项目开发需求与进度管理
> 按 `C:\Users\Lenovo\.zcode\AGENTS.md`(用户级默认指令·默认工作约定)维护:
> 记录项目约定与开发进度——已完成功能清单、已提出但尚未实现的计划——随开发持续更新。
> 工程约束与构建规程在各工具 `AGENTS.md`;使用说明在根与各工具 README。
> 内容以仓库工件为准,每次完成开发或有新需求提出后同步更新本文。
## 1. 项目定位与约定
- 本仓库是 **LT8619C(HDMI→RGB888)→ DLPC3421 投影转接板**的调试上位机工具集,
服务上游固件仓 `hulk/LT8619C_DLPC3421_HDMI`(本机路径
`E:\Hulk-Coding\LT8619C_DLPC3421_HDMI`,同 Gitea 实例 gitea.hulk.wang)。
光机 RS485 协议**唯一权威**是上游仓 `protocols.md`,本仓不维护协议副本。
- 工具链(全仓统一):Python 3.14;GUI 用 PySide6 + PySide6-Fluent-Widgets,解析/协议
模块纯标准库;PyInstaller onefile 打包;发布流水线 build_exe → package_release →
publish_gitea(`GITEA_TOKEN` 用户级环境变量;实例 TLS 间歇抽风,实际请求加
`--insecure`,详见 `DLPilot/AGENTS.md` §5)。
- 结构约定:每个工具三区目录(**src/ 人写 / assets/ 可再生 / release/ 交付**)+ 双文档
(README 使用说明 / AGENTS.md 工程约束与进度)。各工具独立开发、独立打标签发布,
Release 列表按时间倒序混排于同一页面:
- **DLPilot**(原 HDMI-Tool)="3D 光固化光机调试台":HDMI 源端(EDID/分辨率/
测试图案投屏)+ 光机控制(RS485→GD32E230 网关→DLPC3421)+ 电源检查。
- **EDID-viewer**:Windows 显示器 EDID 只读查看器(Fluent UI)。
- **SerialMate**:RS485/串口调试助手,帧格式(包头/板ID/LEN/CRC)可定制,
默认兼容 DLPilot 光机协议;payload 字符串/HEX 显示、4 通道曲线、payload
自动包装发送。
- **I2C-Inject**:RP2040 固件 + PC GUI,demo 板 I2C 总线择机注入读写寄存器。
**2026-09-25 起暂停开发**,代码与固件保留备查。
- 镜像约定:`EDID-viewer` 主目录(`E:\Hulk-Coding\LT8619C_Debug_Tools\EDID-viewer`)
改动后需 robocopy /MIR 同步到 `E:\Hulk-Coding\LT8619C\_Debug\_Tools\EDID-viewer`
(排除 .venv/build/__pycache__/.git,zip 不同步)。
- 发布约定:源码与打包产物(exe、运行配置)入库;发布 zip 不入库,只上传 Gitea Release。
## 2. 开发进度(已完成功能清单)
### 2.1 DLPilot — 最新发布 v0.4.0(2026-09-24)
- HDMI 源端:EDID 查看/逐字节解析、分辨率切换、智能显示拓扑(仅拉回转接板屏)、
纯色/黑白/测试卡全屏投屏、自定义槽位(pattern_slots.json)。
- 光机控制:RS485 链路(`dlpc_rs485.py` 帧协议+线程)、开关光机/设光强/TEC 控温/
查温度电流,串口参数化。
- 电源检查:PD 自检(M301→M302→M303 状态机)、FPDO 挡位判定、功率检测
(M303+M304+M305 → V/mA/W 两位小数)。
- 界面:PySide6-Fluent-Widgets 双栏仪表盘(v0.4.0 起),Light/Dark/System 主题
(Fluent 主题 + Qt 调色板 + QSS + DWM 标题栏三件套同步)。
- 发布:v0.1.0(HDMI-Tool)→ v0.2.0 → v0.3.x → v0.4.0 均已上传 Gitea Release
(v0.3.6 未单独发布,功能被 v0.4.0 覆盖);远端标签与附件已核对。
### 2.2 EDID-Viewer — 最新发布 v0.1.0(2026-09-25)
- 解析:EDID 1.x 基础身份/时序、CTA(音频 SAD/HDMI VSDB/CEC/HF-VSDB)、HDR 与
色彩能力、逐块校验与越界诊断(`edid.py` 纯标准库 + 9 项单测,含随机畸形数据
无崩溃检查)。
- 数据获取:Windows WMI 只读枚举活动设备(HDMI/DP/内屏连接类型);离线
`.bin/.edid/.hex/.txt` 导入;BIN 与 JSON 报告导出。
- 界面:Fluent 卡片布局、分组页签(设备与能力/时序/原始 HEX/完整 JSON)、右上角
"关于"(v0.1.0)。
- 主题:Light/Dark/dark1/dark2/跟随系统,三件套同步 + QSettings 持久化 +
系统明暗变化响应。
- 工程化:目录与发布流水线对齐 DLPilot(onefile exe 入库);标签
`EDID-Viewer-v0.1.0` 与 Release 附件(66,483,477 字节)已核对。
### 2.3 SerialMate — v0.1.0(2026-09-27,首版)
- **更名**:原名 SerialAssistant(目录/exe/文档/配置同步更名;旧配置
serial_assistant.json 首次启动自动迁移为 serial_mate.json;图标与名字
无绑定为波形+RS485 母题)。用户确认 "SerialMate 吧"(2026-09-27)。
- 协议:**帧构成令牌序列可定制**(`HDR ID LEN PAYLOAD CRC` + 十六进制字面量
同步头,收发共用布局仅包头分方向;支持字段换序/无板ID/多字节同步头,LEN
口径 payload 长度/到帧尾/整帧三种)、5 种 CRC 算法 × 3 种覆盖范围,默认与
DLPilot 光机 RS485 协议一致(D5/B5/01/SUM8/不含包头);增量解析前缀逐位
对齐 + CRC 失败逐字节重同步;自测 64 项全 PASS(DLPilot 实测帧向量 +
CRC 标准校验值 + 布局换序/LEN 口径向量 + 布局模糊往返)。
- 链路:串口参数热切换、半双工友好发送队列(未连接丢弃)、解析/透传双模式
热切、`loop://` 虚拟回环自检 13 项全 PASS(组帧→发送→接收→解析→曲线提取)。
- GUI(PySide6-Fluent-Widgets,用户指定沿用 Qt 方案):帧构成/LEN 口径可视化
编辑,payload 字符串/HEX 切换(半透明底色高亮)、原始帧 hex、时间戳、日志
保存;4 通道曲线(三种提取 + 倍率,**弹窗独立**:时间窗滑笔回看、纵轴刻度、
悬停读值、暂停渲染/自动Y/滚轮缩放/拖动 Y 轴);发送自动包装(输入 payload
自动组帧,`/` 分隔多条依次发)、HEX 直发、周期发送、组帧实时预览、历史
回溯、回车发送;主题跟随系统;标题栏版本号 + 关于弹窗 + 图标(波形 RS485)。
- 板型档案(2026-09-27 实机反馈追加):不同板子的"协议参数+命令预设表"存为
命名档案(board_profiles.json,不入库,首次运行生成默认 DLPilot 板型),
发送卡一键切换/新建/存为/删除/表格编辑/重载。
- 发布:SerialMate.exe 已入库(随帧构成功能重建),zip/Release 未发布
(待用户验收后走 package_release + publish_gitea)。
### 2.4 I2C-Inject — ⏸ 暂停开发(2026-09-25)
- 已完成:RP2040 注入器固件(MicroPython,内置 viper 总线嗅探)、PC 端 GUI、
demo 板寄存器语义实测(0x606E bit5=镜像 D[7:0]、0x606D 整组顺序,逻辑分析仪
双色交叉验证)。
- 状态:暂停开发,代码与固件保留备查,README 顶部有状态横幅。
## 3. 开发需求与计划(已提出、尚未实现)
### 3.1 DLPilot
- 【待素材】校准图案槽位预置为空:第二排 5 个槽位为 3D 光固化测试/校准图预留
(`file: null`);素材到位后 assets/ → 生成脚本入库 → 更新 slots → 重新打包。
- 【待真机帧·低优先】M305 回归向量是按协议推演的(selftest_rs485.py:90 起,
0x8CA0=36000mW 为推演值):真机功率显示已实测对接,仅剩把自测向量换成真机抓包,
让无硬件回归更贴近真机。
- 【新需求·已确认可行(2026-09-25)】画面镜像(横/纵独立翻转,任意来源画面):
投影观看方向(正投/背投/吊装)需要源信号预先翻转。DLPC3421 原生支持——I2C 14h
"写入显示图像方向"(b1=长轴翻转、b2=短轴翻转,两轴独立;15h 读回;b0 旋转仅竖排源
且 DLPC3421 不支持)。实施分两段:
- 上游固件(协议权威在上游仓):`dlpc3421.h` 已定义 14h/15h 命令号但驱动未实现——
照 `dlpc3421_set/get_mirror_lock_control` 模式补 set/get 函数,再暴露为 M 命令
(现有 M981~M983 是只读调试命令,可续编 M984=设置/M985=读取,命名以上游为准),
登记进 protocols.md;上电/软重启后是否自动恢复保存的方向由固件决定。
**命名陷阱**:现有 `set/get_mirror_lock_control`(39h"镜片锁定控制")是出厂 DMD
接口锁定校准用,不是图像镜像,勿混用。
- 上位机 DLPilot:`dlpc_rs485.py` 加命令封装,光机卡加"水平镜像/垂直镜像"开关并
读回回显;用方向不对称图案(如 bw_sweep/文字图)实测确认长轴/短轴与横/纵的对应。
- 备选(若固件暂不动):DLPilot 自投图案/自定义图片可在 Qt 渲染时翻转(仅覆盖测试
内容);任意桌面内容 Windows 标准 API 只有 180°(=两轴同时),单方向翻转做不到。
### 3.2 EDID-Viewer
- EDID 对比、字节差异与固件数组导出。
- HDMI Forum VRR/ALLM/FRL/DSC、DisplayID 与高级色彩数据解析(第一版有意不解,
保留原始块供分析)。
- 与实际输出时序和桥接芯片寄存器联合诊断。
- 实机验收缺口:HDMI 热插拔、多屏、跨屏 DPI、最大化/恢复与导入导出完整交互
(见 `EDID-viewer/VALIDATION.md`)。
### 3.3 SerialMate
- 【待真机】光机实机收发与温度曲线实测(M201 ×0.1 提取),当前仅回环验证。
- 【无图标】assets/serial-mate.ico 未生成(build_exe.py 已预留路径)。
- 发送批处理脚本化(延时/循环/等待应答);曲线数据导出 CSV。
### 3.4 I2C-Inject
- 暂停开发期间不列计划;恢复时以其 README 现状为准。
### 3.5 明确不做(决策,非待办)
- **0x606E 的 0x40/0x80 位交换不再单独实测**(2026-09-25 用户确认:当前行为正常、
符合预期,bit5 实测基线已够用;原【待硬件】项关闭)。
- TI 原始 I2C 命令透传不做:GD32 网关固件只收 ASCII M 命令集(v0.2.0 显式决策)。
- DLPilot 不引入 pyserial/Pillow 硬依赖:保持 try-import + HAS_* 标志 + 缺失降级。
- EDID-Viewer 不承诺实时 DDC 抓取:数据来自 Windows/显卡驱动,可能缓存或覆盖。
## 4. 决策史:时间线与踩坑(勿重蹈)
**阶段 0 · 寄存器语义实测期(09-03)**:I2C-Inject + HDMI-Tool 首版落库;0x606E
位交换 / 0x606D 整组顺序经 demo 板 LA 双色交叉实测确立(`la_wave_analyzer*.py`
即该过程产物)。
**阶段 1 · 工程化与发布流水线(09-10)**:确立三区目录 + 双文档;打通
build_exe → package_release → publish_gitea,发布 HDMI-Tool v0.1.0。
**阶段 2 · 光机 RS485 控制集成(09-11,v0.2.0)**:新增 `dlpc_rs485.py`(帧构造/
增量解析/译码表/DLPC485 链路类,模式照搬 I2C-Inject 的 Injector);启动拓扑改智能判定。
**阶段 3 · GUI 重构与产品化(09-12,v0.3.0)**:CustomTkinter 双栏仪表盘
(规格 `UI参考布局.svg`);更名 HDMI-Tool → DLPilot;TEC 控制与温度实时显示。
**阶段 4 · 体验打磨(09-14,v0.3.1~0.3.3)**:投屏退出语义两轮更名;标题栏版本号;
修复 USB 拔出后同参数重连失效。
**阶段 5 · 电源检查卡(09-17~18,v0.3.4~0.3.6)**:电源自检状态机、功率检测、
M30x 二进制载荷封装(详见踩坑 1~3、10)。
**阶段 6 · DLPilot Fluent UI 重写(09-24,v0.4.0)**:PySide6-Fluent-Widgets 替换
CustomTkinter;补齐折叠、PD 状态颜色、Light 调色板与 Qt 单文件 DLL 加载。
**阶段 7 · EDID-Viewer 独立成工具(09-23~25,v0.1.0)**:从 DLPilot 的源端 EDID
需求独立;目录与流水线对齐;同期 I2C-Inject 标记暂停开发,根 README/agent.md
按三工具更新。
| # | 问题 | 最初做法 → 最终做法 / 教训 |
|---|---|---|
| 1 | 电源自检成功判定 | 先按 ASCII `ok` 前缀判成功 → 实机 M301 回包 payload=`PD` 无前缀被误判错误(9772a2b)→ **改按帧 TYPE=0xF0 译码分类**。教训:M30x 系列回包不能按文本判 |
| 2 | 功率值来源 | 先用 M303×M304 计算 P=UI 占位显示(2b7d103)→ 固件提供 M305 直读 u32 mW 后改为三步序列直读(9b29b6a) |
| 3 | 二进制载荷三连坑 | ① `Frame.payload` 解出乱码 → 用 `payload_bytes()` 取原始字节;② M305 是 LEN=4,复用双字节解析会错 → 按 kind 校验长度;③ 日志行含 NUL 复制被截断 → 二进制载荷日志行以 hex 展示(e354423) |
| 4 | "串口断不开" | 表象是断开逻辑 bug,实际根源是**双实例互抢串口** → 单实例锁 + 串口占用提示(e87bf14) |
| 5 | 窗口最大化卡顿 | CTkScrollableFrame+40 余个逐行 Label 最大化逐控件重绘 → 换 CTkTextbox 整体重排,开销低一个量级(30bc224) |
| 6 | 启动强制扩展拓扑 | 无条件 `SetDisplayConfig` 会打扰用户自选拓扑 → 仅当未激活显示器 EDID 厂商字节为转接板签名 `61 93`("XLS") 时才拉回(d9ecff4) |
| 7 | GUI 框架 | tkinter → CustomTkinter(84838e3)→ v0.4.0 PySide6-Fluent-Widgets;旧文件仅供历史对照 |
| 8 | 投屏退出按钮文案 | "恢复桌面"→"停止投屏"→"停止测试图像"(3f35ad2→b167ce3):最终语义是关测试图窗口,与拓扑恢复无关 |
| 9 | USB 拔出后重连失效 | 掉线分支未清 `_open_key`,重连被"参数未变"跳过 → 掉线同步清缓存(51e2f1c) |
| 10 | 电源自检卡死 | 帧路由引用未定义变量 `payload`(3f36ead),改名/重构时注意帧回调作用域 |
| 11 | Gitea 发布 | urllib 间歇 `SSL: UNEXPECTED_EOF` → 必须 `--insecure`;`/releases/tags/{tag}` 的 assets 是纯数组而 `/releases/{id}` 是 `{items:[...]}`,publish_gitea.py 已兼容两种形状,勿"简化";自动重试已加(f0f8073) |
| 12 | Fluent Light 主题发黑 | 只调 `setTheme` 仅刷新 Fluent 控件,QMainWindow/原生 QTabWidget/QStatusBar/标题栏仍跟系统深色 → **三件套**:setTheme + QPalette/应用级 QSS + DWM 属性 20/35/36(EDID-Viewer `theme.py`,DLPilot 同源) |
| 13 | PyInstaller 传 .spec 报错 | 给 .spec 再传 `--specpath` 报 "makespec options not valid" → spec 由 build_exe.py 生成后只传 distpath/workpath |
| 14 | onefile 冒烟"没窗口" | onefile 引导父进程 MainWindowTitle 恒为空,轮询父进程误判失败 → 按进程名找子进程窗口(EDID-Viewer 实测 ~2s 起窗) |
## 5. 快速上手(完整规程见各工具 AGENTS.md)
```powershell
# DLPilot(完整清单:DLPilot/AGENTS.md §5/§7)
cd DLPilot/src
python -m compileall -q . ; python selftest_rs485.py # 编译检查 + 光机协议回归
python hdmi_gui.py --seconds 5 # GUI 冒烟
python build_exe.py ; python package_release.py 0.4.0 # 打包 + 组装 zip
python publish_gitea.py ../release/DLPilot-v0.4.0-win64.zip --replace --insecure
# EDID-Viewer(完整清单:EDID-viewer/AGENTS.md)
cd EDID-viewer/src
python -m unittest # 9 项解析测试(改 edid.py 后必跑)
python build_exe.py ; python package_release.py 0.1.0 # 打包 + 组装 zip
python publish_gitea.py ../release/EDID-Viewer-v0.1.0-win64.zip --insecure
# SerialMate(完整清单:SerialMate/AGENTS.md)
cd SerialMate/src
python selftest.py ; python selftest_loop.py # 协议回归 + 链路回环(改协议/链路后必跑)
python main.py --seconds 5 # GUI 冒烟
python build_exe.py ; python package_release.py 0.1.0 # 打包 + 组装 zip
python publish_gitea.py ../release/SerialMate-v0.1.0-win64.zip --insecure
```
上游协议/寄存器语义问题先查上游仓 `protocols.md` 与 `doc/architecture/`;
本仓改动约束以两个工具的 AGENTS.md 为准——**其中领域语义的测试值
(55/AA/FF、640x360、800x600@60)有明确用途,勿顺手改**。