Files
HW-Debug-Tools/DLPilot/release/README.md
T

257 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.
# DLPilot — HDMI 源端调试 + 光机控制工具
> LT8619C(HDMI→RGB888)→ DLPC3421 投影转接板调试配套的 PC 端工具:
> HDMI **源端**(EDID 查看、分辨率切换、纯色/测试图案投屏)+ **光机控制**
> (RS485 直连板上 GD32 网关,开关光机/设光强/查温度电流)。
>
> - **只想用工具**:到 [Gitea Releases](https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools/releases)
> 下载 `DLPilot-vX.Y.Z-win64.zip`,解压双击 `DLPilot.exe` 即可(Windows 10/11 x64,免安装、无需 Python)。
> - **要改代码/重新打包**:见 §8、§9。
>
> 更新:2026-09-24
---
## 1. 功能总览
| 功能 | 说明 |
|---|---|
| EDID 查看 | 枚举各显示输出口,从注册表读取 EDID 原始数据,按 EDID 1.4/CEA-861 解算:厂商/型号/尺寸/Gamma/输入类型/支持模式(DTD/已建立/标准/CEA-VIC)/首选时序完整参数/校验和 |
| EDID 逐字节解析 | "EDID 原始数据"框右上"逐字节解析"按钮:按偏移逐字段展开基础块与 CTA-861 扩展块,每字段附原始字节 hex;命令行等价 `--edid-fields` |
| 分辨率切换 | "分辨率"下拉列出显卡按该屏 EDID 提供的全部模式;**应用**=临时切换(不写注册表,重启/恢复即还原),**恢复**=回到本次会话切改前的模式 |
| 测试图案投屏 | 全屏投到所选显示器,测试卡区域可选 `640x360 / 800x600 / full 铺满`;内置 纯红/纯绿/纯蓝/黑白棋盘格/网格线 + R/G/B 三行 55/AA/FF 纯色值按钮 + 3 个自定义图片栏位 |
| 界面 | PySide6-Fluent-Widgets 双栏仪表盘(左列 HDMI 源端 / 右列 光机控制),顶栏可切换 Dark/Light/System |
| 光机控制 | RS485 → 板载 GD32E230 网关 → DLPC3421:开关光机(可定时)、设光强、查电流/温度/版本、TEC 控制、软件重启;光强/定时提供快捷滑条;收发日志带协议译码(见 §5) |
| 智能显示拓扑 | 仅当检测到转接板(EDID 厂商 "XLS")接入但未进入桌面(Windows 卡在"仅电脑屏幕")时才强制扩展把它拉回;你主动选的"仅第二屏幕"等拓扑不会被改动 |
| 命令行模式 | 全部功能可脚本化调用,供自动化测试(见 §6、§7) |
| 波形分析脚本 | 逻辑分析仪 CSV 波形按占空比签名分段,输出行结构/占空比/消隐明细(见 §7.3) |
## 2. 下载与安装
1. 打开 [Releases 页面](https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools/releases),取最新的
`DLPilot-vX.Y.Z-win64.zip`;
2. 解压到**任意可写目录**(自定义图片与栏位配置会写到 exe 旁边);
3. 双击 `DLPilot.exe`。首次启动比脚本慢一两秒(onefile 解压),属正常现象。
包内包含:
```
DLPilot/
├── DLPilot.exe 主程序(单文件自包含, 光机控制的 pyserial 已内置)
├── pattern_slots.json 预置自定义栏位 + 串口记忆
├── bw_*.png ×5 640x360 黑白测试图
├── solid_*.png ×10 800x600 纯色测试图
└── README.md 本说明
```
## 3. GUI 使用
主窗口为双栏仪表盘(布局设计稿:`UI参考布局.svg`),默认跟随系统深/浅色外观
(顶栏可切换 Dark/Light/System),顶栏右侧"关于"按钮内含软件信息:
```
左列(HDMI 源端) 右列(光机控制 RS485)
┌ 显示器选择区域 [刷新] ┐ ┌ 串口选择 + 波特率/8-N-1 参数/连接 ┐
├ 支持的模式: 分辨率[应用][恢复] + 明细 ┐ ├ 电源检查 — PD自检/FPDO挡位/功率读数 ┤
├ EDID 信息 ┘ ├ 串口数据 — 收发日志(译码+hex) ┤
├ 测试图案 / 纯色 / 校准图案 / 测试卡区域 │ ├ 光机命令 — 快捷按钮+TEC │
├ EDID 原始数据 [逐字节解析] ┘ │ 预设下拉 / 温度电流读取 / 自定义 │
└─────────────────────────────┘ └ 快捷滑条 — 光强/定时/TEC温度 ┘
```
1. 左上显示器下拉选择目标屏(多屏时注意别选成主屏),"刷新"重新枚举;
2. **切分辨率**:"支持的模式"卡片里选模式 → "应用";测完点"恢复";
3. **投测试图**:"测试图案"卡片先选**测试卡区域**(640x360 / 800x600 / full)→
点图案按钮全屏投放(新图案自动替换旧图案),按 **ESC** 或点"停止测试图像"退出;
R/G/B 纯色按钮(55/AA/FF,按通道着色)
用于 RGB 位交换类测试;自定义图片点齿轮按钮配置(图片自动复制到 exe 旁),
"校准图案"一排为 3D 光固化测试/校准图预留槽位;
4. **光机控制**:右列选串口与参数(波特率/数据位/校验/停止位,默认 115200 8-N-1)→ 连接 →
快捷按钮/预设下拉/自定义输入(回车即发);"查DMD温度""查LAMP温度"读温度
(应答实时填入按钮旁的显示框);快捷滑条:光强拖动后"下发电流值",
定时毫秒后"开光机(定时)"(0=不限时 M730S0),TEC 凝露点滑条/输入框
(200-350 即 20.0-35.0°C)后"下发温度值";数值框输入后回车自动限幅同步;
5. 测试卡区域、自定义栏位与串口记忆(含参数)自动保存在 exe 旁的 `pattern_slots.json`。
## 4. 典型测试场景
```
1. HDMI 接转接板 → 启动 DLPilot → 刷新 → 选中板卡显示器
2. 板卡 shadow EDID 首选 640x360@60 → 测试卡区域选 640x360(与光机面板原生 1:1)
3. "光机控制"连接串口 → M999 查版本确认链路通 → M730S0 开光机
4. 点 R/G/B 行纯色按钮投图 → 目视/逻辑分析仪核对 RGB888 输出
- 纯红/绿/蓝:验证通道映射(R=D[23:16], G=D[15:8], B=D[7:0])
- 55/AA 对:验证位交换(0x606E)——图像应为 50% 灰阶占空比
5. M731S100 设光强 → M732 查电流读回复核 → M730S1 关光机
```
寄存器语义(0x606E 位交换 / 0x606D 整组顺序)与光机协议的判读基线见上游主仓库
[LT8619C_DLPC3421_HDMI](https://gitea.hulk.wang/hulk/LT8619C_DLPC3421_HDMI) 的 `doc/architecture/`。
## 5. 光机控制(RS485 → GD32 网关 → DLPC3421)
物理链路:PC 经 **USB-RS485 转换器**接板卡 A/B 端子,板上 GD32E230 做 RS485→I2C 网关
控制 DLPC3421(I2C 地址 0x1B)。串口参数 **115200, 8N1**,协议细节以上游固件仓
`protocols.md` 为准:命令帧 `D5 01 LEN <ASCII命令> CRC`、响应帧 `B5 TYPE LEN <payload> CRC`,
CRC 为第 2 字节起累加和取低 8 位。
GUI"光机控制"区:选串口 → 连接 → 点快捷按钮或命令下拉/自定义输入发送;串口下拉显示
"COMx + 设备描述",CH344 等多路适配器每一路描述不同(如 serial-A/B/C/D),据此选口;
多口描述相同时自动附物理位置消歧。日志区实时显示 `→ 命令` / `← 译码结果 (原始 hex)`,
错误自动附释义(如 `err:3(I2C NACK)`)。
"电源检查"卡:**电源自检**依序发 M301(协议)→M302(挡位最大电流)→M303(实测母线电压),
按实测电压就近判定 PD 固定挡(5/9/12/15/20/28V,容差 ±5%):**12V 挡且 ≥3A 绿底
"FPDO: 12V@3A"**;挡位不符(如 9V 挡)**红底**显示实际挡位;不落在任何标准挡显示
**ERR**(CH224Q 电压配置寄存器只写不可读,挡位只能靠实测判定)。**功率检测**依序发
M303+M304+M305,读数框显示 电压(V) / 电流(mA) / 功率(W,mW 换算两位小数)。
| 命令 | 功能 | 响应示例 |
|---|---|---|
| `M730S0` / `M730S1` | 开 / 关光机 | `ok` |
| `M730S0T2000` | 开光机并定时 2000ms 自动关(≤32700) | `ok`(期间 M737 延迟应答) |
| `M731S100` | 设光强 54-800(RGB 同值,写后读回复核) | `ok` / `err:R..G..B..` |
| `M732` | 查三路电流设置值(0-65535) | `okR110G110B110` |
| `M201` / `M202` | 查 DMD / LAMP 温度(0.1°C) | `okTL:246` = 24.6°C |
| `M301` | 查电源协议(CH224Q 握手结果) | ASCII:`PD` / `QC3.0` / `EPR` … |
| `M302` | 查 PD 挡位最大电流(u16 大端 **mA**,50mA/LSB 固件已换算) | 0x0BB8 = 3000 mA = 3 A |
| `M303` | 查母线电压(SQ52205 实测,**2 字节大端二进制载荷**) | 0x2EF4 = 12020 mV = 12.02 V(12V 轨窗口 11400~12600) |
| `M304` | 查负载电流(SQ52205 实测,**2 字节大端二进制载荷**) | s16 补码 mA:0x0034=+52;FF 06=−250(正=正向) |
| `M305` | 查负载功率(SQ52205 实测,**4 字节大端二进制载荷** u32) | mW→显示 W 两位小数:0x00008CA0=36000 mW=36.00 W(量程 0~295000 mW) |
| `M999` | 查固件版本 | `okv20.0.0.1` |
| `M737` | 查投光是否结束(投光中延迟应答) | `ok` |
| `M7S0` / `M7S1` | TEC 自动控温开 / 关(注意 S0=开) | `ok` |
| `M8S330` | TEC 凝露点 33.0°C(200-350,0.1°C) | `ok` / `err:OL` |
| `M1` | 协议握手 | `ok` |
| `M888` | 软件重启 | `ok` 后 100ms 复位 |
注意:**DLPC3421 启动完成前 M730/M731/M732 被就绪门禁拒绝**(回 0xFF),上电后稍等几秒再发。
命令行等价(源码方式):
```
python hdmi_gui.py --port COM9 --dlpc-cmd M730S0 --dlpc-cmd M999
逐条发送并打印译码响应
```
## 6. 命令行模式(hdmi_gui.py)
exe 版无控制台,`--dump/--edid-fields` 的输出不可见(`--dlpc-cmd` 仍可执行,靠退出码判断),
调试请用源码方式:
```
python hdmi_gui.py --dump 控制台输出 EDID 解算
python hdmi_gui.py --edid-fields 控制台输出 EDID 逐字节字段解析表
python hdmi_gui.py --test-pattern Blue --area 800x600 --seconds 5
出图 5 秒自动退出
python hdmi_gui.py --test-pattern Custom1 投自定义栏位 1
python hdmi_gui.py --port COM9 --dlpc-cmd M730S0 RS485 发光机命令(可多次)
python hdmi_gui.py --seconds 5 GUI 冒烟测试, 5 秒自动关
--test-pattern {Red,Green,Blue,Checker,Grid,Custom1..3}
--area {640x360,800x600,full} --monitor N --seconds S
--port COMx --baud 115200 --dlpc-cmd CMD(可重复; 任一命令失败退出码 1)
```
## 7. 辅助脚本(src/ 下)
### 7.1 hdmi_source.bat / .ps1 — 源端命令行工具
与 GUI 互补,适合脚本串联:
```
tools\hdmi_source.bat -List 枚举显示器与支持分辨率(验证 EDID)
tools\hdmi_source.bat -Monitor 1 -Mode 800x600 切模式
tools\hdmi_source.bat -Mode 800x600 -Pattern -Restore
切模式→出图案→退出后自动恢复
```
### 7.2 gen_bw_patterns.py / gen_solid_colors.py — 测试图生成
需 Pillow(`py -m pip install pillow`)。重新生成 `assets/` 下全部图案:
- `gen_bw_patterns.py` → 640x360 黑白图 ×5:
`bw_star.png` 西门子星(极限分辨率)、`bw_sweep.png` 频率扫描条纹(24px→3px)、
`bw_checker_sweep.png` 渐变棋盘(2→32px)、`bw_zoneplate.png` 波带片(各向混叠)、
`bw_testcard.png` 综合测试卡(灰阶/刻度/细棋盘/线宽组);
- `gen_solid_colors.py` → 800x600 纯色图 ×10(R/G/B 各 55/AA/FF + 三原色),
与 GUI 内置纯色按钮同源,供自定义栏位或其他工具加载。
### 7.3 la_wave_analyzer.py / la_wave_analyzer3.py — 逻辑分析仪波形判读
分析 Kingst VIS 导出的边沿流 CSV(列:`Time[s], 通道A, 通道B[, 通道C]`,
10ns 分辨率),按 50ms 窗口占空比签名自动分段,输出每段的签名(FF/55/AA/00)、
时长、行周期/有效区宽度/消隐(按 40MHz 像素时钟折算):
```
python la_wave_analyzer.py <capture.csv> # 2 通道(默认判读 B 口 D0/D1)
python la_wave_analyzer3.py <capture.csv> # 3 通道(RGB 三组同拍, ch8/9/10)
```
### 7.4 selftest_rs485.py — 光机协议自检(无硬件)
对照上游 `protocols.md` 实测帧向量回归帧构造/解析/译码:`python selftest_rs485.py`,
全部通过退出码 0。改 `dlpc_rs485.py` 后必须跑一遍。
## 8. 目录结构与从源码运行
```
DLPilot/
├── src/ # 源代码(人工维护区)
│ ├── hdmi_gui.py # 入口与命令行模式(argparse 分发)
│ ├── app_fluent.py # PySide6-Fluent-Widgets 主界面(双栏仪表盘)
│ ├── app_gui.py # 历史 CustomTkinter 界面(保留,不由入口加载)
│ ├── display_win.py # Win32 显示器枚举/分辨率/智能拓扑(纯标准库)
│ ├── edid_parse.py # EDID 1.4/CEA-861 解析(纯标准库)
│ ├── patterns.py # 测试图案全屏投屏窗口
│ ├── config.py # 运行目录与 pattern_slots.json 配置
│ ├── dlpc_rs485.py # 光机 RS485 协议与串口链路
│ ├── selftest_rs485.py # 光机协议自检(无硬件回归)
│ ├── build_exe.py # PyInstaller 打包 → release/
│ ├── package_release.py # 组装发布 zip(exe+图案+说明)
│ ├── publish_gitea.py # 上传到 Gitea Release
│ ├── hdmi_source.ps1/.bat # 源端分辨率/图案命令行工具
│ ├── gen_bw_patterns.py # 生成 assets/bw_*.png
│ ├── gen_solid_colors.py # 生成 assets/solid_*.png
│ ├── la_wave_analyzer*.py # 逻辑分析仪 CSV 波形判读
│ └── logos/ # 图标源(svg/png/ico + make_ico.py)
├── assets/ # 生成的测试图案(gen_*.py 产物, 随发布包分发)
│ ├── bw_*.png ×5 # 640x360 黑白系列
│ └── solid_*.png ×10 # 800x600 纯色系列
├── release/ # 构建与发布产物(机器生成区, 不手改)
│ ├── DLPilot.exe # 打包单文件版(改动跟随源码提交入库)
│ ├── pattern_slots.json # exe 运行配置(栏位预置 + 串口记忆)
│ ├── *.png / README.md # 附属文件平铺副本(由 package_release.py 从 assets/ 同步)
│ └── *.zip # 发布包(不入库, 上传 Gitea Release)
├── README.md # 本说明
├── AGENTS.md # 面向 AI/Agent 的工程档案(结构/约定/构建规程)
└── UI参考布局.svg/.png # 界面布局设计稿(app_fluent.py 双栏布局参考)
```
从源码运行:`python src/hdmi_gui.py`,需 Python ≥3.10;EDID/命令行纯标准库;
GUI 需 PySide6-Fluent-Widgets(`py -m pip install PySide6-Fluent-Widgets`);光机控制需 pyserial;
自定义图片要 JPG/BMP/WebP 需可选 Pillow。
## 9. 构建与发布
```powershell
cd src
python selftest_rs485.py # 光机协议回归(改 dlpc_rs485.py 后必跑)
python build_exe.py # 打包 → ../release/DLPilot.exe(自动装 PyInstaller;
# 内置 pyserial/PySide6-Fluent-Widgets, Fluent 主题资源自动收集)
python build_exe.py --debug # 额外出一个带控制台的调试变体(--dump 可见输出)
python package_release.py 0.2.0 # 组装 release/DLPilot-v0.2.0-win64.zip
python publish_gitea.py DLPilot-v0.2.0-win64.zip --insecure # 上传 Gitea Release(需 GITEA_TOKEN)
```
## 10. 注意事项 / FAQ
- **光机没反应排查**:① 串口/波特率(115200 8N1)与 A/B 接线;② 先发 `M999` 验证链路;
③ 开光机回 0xFF 是 DLPC 就绪门禁——上电后等几秒;④ USB-RS485 转换器半双工,
发送时板上回包不会回环(正常);
- **exe 放只读目录会怎样**:自定义图片与 `pattern_slots.json` 写在 exe 旁边,只读目录会导致配置存不下;
- **重新打包后图标没变**:Windows 图标缓存,`ie4uinit -show` 或改个名即可;
- **多屏序号**:切分辨率前先确认显示器序号(GUI 下拉框与 `hdmi_source.bat -List` 输出一致);
- **残留进程**:修改源码重新打包前先结束残留的 DLPilot 进程(`build_exe.py` 会自动 taskkill);
- **改 logo**:改 `src/logos/logo_ph_orange.svg` → `python src/logos/make_ico.py` → 重新打包;
- **配置互不影响**:exe 与源码脚本各自按所在目录保存 `pattern_slots.json`,两份安装互不干扰。