# I2C-Lab — I2C 总线监控调试台 > 更新:2026-10-02。由 **RP2040 probe 固件**(`firmware/`,pico-sdk C,刷入 > BPI-Pico-RP2040)+ **PC 端 GUI**(`src/` / 打包版 `release/I2C-Lab.exe`)组成。 > 在任意 I2C 总线上**纯被动实时监听**:事务流解码 + 逻辑分析仪式波形快照。 > 前身 I2C-Inject(LT8619C 寄存器择机注入)保留在仓库备查;本工具是其 > "完整 I2C 调试台"路线的第一阶段(监控),主机读写与从机模拟见 §7 路线。 --- ## 1. 它能做什么 | 能力 | 说明 | |---|---| | **实时事务流** | START→STOP 完整解码: 7bit 地址/RW/每字节 ACK/NAK/数据/收尾方式(含 repeated-START 标记) | | **地址过滤** | 只看关心的地址(十六进制空格分隔), 其余只计数不入表 | | **波形快照** | 一次抓取最近 256~16384 个 SDA/SCL 边沿, 逻辑分析仪视图: 滚轮缩放(光标锚点)/拖动平移/双击适配/START-STOP 刻线/事务标签 | | **CSV 导出** | 全量事务(≤2 万条滚动池)导出, Excel 直接打开 | | **固件计数** | 边沿数/事务数/环形覆盖丢包/疑似丢沿, 判断总线活动与负载 | | **演示模式** | 无硬件看界面: 模拟 LT8619C demo 板 ~500ms 轮询流量 | **被动性保证**: probe 两脚为纯输入(PIO 只读电平), 不加上拉、不驱动、 不改总线时序——挂在运行中的 demo 板上零干扰(与 I2C-Inject 同一接线规矩)。 ## 2. 硬件准备 | BPI-Pico-RP2040 | 目标总线 | |---|---| | GP8(物理脚 11) | SDA | | GP9(物理脚 12) | SCL | | GND | GND | - **不接 VCC、不外加上下拉**(总线由目标板自带上拉) - 独立台架总线(无主)另说: 需 4.7kΩ 上拉×2 到 3.3V 才有静态高电平 - 固件把系统时钟超到 250MHz(vreg 1.15V), 100/400kHz 总线余量充足; 官方 USB 枚举不受影响 ## 3. 刷固件(一次性) 1. 按住 BOOTSEL 上电, 出现 `RPI-RP2` U 盘 2. 把 `release/firmware/i2c_lab.uf2` 拖进去, 板子自动重启 3. 设备管理器出现 `USB 串行设备`(VID 2E8A)即就绪; LED 上电快闪 3 次后, **常亮 = 监控流开启** 重新构建固件见 `firmware/` 源码与 §6。 ## 4. GUI 使用 双击 `I2C-Lab.exe`(或 `python src/main.py`; `--demo` 进演示模式): 1. **固件串口卡**: 选带 `[RP2040]` 标记的端口 → 连接(日志出现版本横幅) 2. **监控卡**: 「开始监控」→ 事务表开始滚动; 「暂停滚动」冻结表格方便读 3. **地址过滤**: 如 `32 50`(十六进制); 空格分隔多个; 留空看全部 4. **波形卡**: 设边沿数(默认 2048) → 「抓取波形」→ SCL/SDA 双线时序图; 滚轮缩放, 拖动平移, 双击适配全宽; 绿/红虚线 = START/STOP 5. **导出CSV**: 保存当前全量事务池(不只表内可见行) 6. 主题: 跟随系统/浅色/深色(DLPilot/SerialMate 同款三件套) 表格列: `# | t0(us) | 时长us | 地址 | RW | ACK | 数据 | 收尾`。 地址 NAK 红色、截断/半字节断橙色、超 16 字节数据显示省略号(悬停看全量)。 ## 5. 固件串口命令(可直接用串口终端调) 命令行一行一回, `=` 正常 / `!` 告警(全仓约定): ``` ? 帮助 v 版本/时钟/角色 mon start 开 T 行事务流(监控中) mon stop 停流 stats 计数: edges/trans/trans_drop/susp/ring_ovf/最近边沿距今 wave [n] 倒出最近 n(默认1024, 上限16384)个边沿: W 行 + 'W.' 收尾 boot 重进 BOOTSEL(免按按键) ``` T 行语法(与 PC 端 `i2cdec.py` 互为权威, 自测往返覆盖): ``` T flags: '-' stop | 'r' repeated-START 收尾 | 'c' 流截断 | 'p' 半字节断 可追加 'L' = 长事务截断(>56 字节只保留前段) acks : n+1 个 'A'/'N', 首个是地址应答 W pins bit0=SDA bit1=SCL ``` ## 6. 重新构建固件 依赖(本机已装齐, 新机器对照): - pico-sdk 2.3.1 + tinyusb 子模块(锁定提交), Arm GNU 13.x, CMake ≥3.16, Ninja - pioasm 由 SDK 构建时自动编译; **宿主若无 C++ 编译器**(如本机), 预置 `firmware/build/pioasm/CMakeCache.txt` 的 `CMAKE_CXX_COMPILER` 为分号列表 形式的 zig(`pip install ziglang` 后指向 ziglang/zig.exe, 见 AGENTS.md 踩坑表) - SDK 2.x 的 UF2 依赖 picotool(要拉 github); 本仓改用 `make_uf2.py` (ELF→objcopy→bin→UF2, 与真机 UF2 逐字段核对 + 往返自检) ```powershell cd firmware cmake -B build -G Ninja -DPICO_SDK_PATH=D:/toolchain/pico-sdk ` -DPICO_TOOLCHAIN_PATH=D:/toolchain/arm-gnu-toolchain-13.3.rel1 ` -DPICO_BOARD=pico cmake --build build -O binary build\i2c_lab.elf build\i2c_lab.bin python make_uf2.py build\i2c_lab.bin build\i2c_lab.uf2 copy build\i2c_lab.uf2 ..\release\firmware\ ``` ## 7. 路线(与 I2C-Inject 的关系) - [x] **v0.1 监控**(本版): 纯被动监听 + 事务流 + 波形快照 - [ ] **主机模式**: probe 作为 I2C 主机发起读写/总线扫描(复活 I2C-Inject 的 择机注入语义——避让主控轮询、静置窗口注入、读回校验), GUI 加寄存器读写卡 - [ ] **从机模拟**: probe 应答主机, 应答内容由 PC 端配置(RP2040 硬件 I2C 从机 + 应答表), 用于顶替传感器/MCU 验证驱动 - [ ] 监控增强: 字段级协议插件(如 LT8619C bank/寄存器语义注释)、触发抓取、 长时记录落盘 ## 8. 故障排查 - 连接后无 T 行: `stats` 看 edges 是否增长; 不增长查接线/共地/上拉 - 事务乱码: 确认 SDA/SCL 没接反(GP8=SDA!); `wave 512` 看原始边沿 - `trans_drop`/`susp` 持续增长: 总线负载过高或毛刺多, 减小监控过滤范围 - 波形抓取期间的事务流有缺口: 正常(`wave` 快照优先, 见固件注释) ## 9. 目录内容 | 位置 | 用途 | |---|---| | `src/` | PC 端: main.py(GUI)/i2cdec.py(解码权威)/probelink.py(链路)/waveview.py(波形)/theme.py + 自检/打包/发布脚本 | | `firmware/` | probe 固件: main.c + bus_watch.pio + CMakeLists + make_uf2.py + pico_sdk_import.cmake | | `assets/` | 图标(沿用 I2C 橙色母题) | | `release/` | I2C-Lab.exe + firmware/i2c_lab.uf2/.bin(交付物本地保留,不入库); zip 不入库 |