# 交接 更新:2026-09-06 完成任务包 **A3**(INA226 驱动 + 六片地址表) ## 一句话现状 六片 INA226 的地址表钉死在代码里(`0x40/41/44/45/42` + 输入侧 `0x43`), 驱动能认件(MFG/DIE ID)、写 Config+CAL 并回读校验、读出 V / I / 分流 / 功率, 电流**有符号**(反灌为负)。4 条 ctest(34 个用例)全绿,`idf.py build` 通过。 ## 下一步 **A4**:DAC63204 驱动 + `rail_set_mv()`(需求 §10.5 全节)。 三条断言:①4020 mV 被拒(SR-13)②**写更大的码值输出更低**(反向关系)③3900 mV ↔ Vd 0.548 V。 地址 `0x4A`(U6:CH1~3)/ `0x4B`(U7:CH4~5),同样查表不要算。 ## 本次新增/修改的文件 - `components/drv/include/ina226.h` — 寄存器、量程常量、地址表、采样结构(唯一对外契约) - `components/drv/ina226.c` — 驱动本体(≈170 行,只经 `hal_i2c_*`) - `components/drv/CMakeLists.txt` — 新 IDF 组件 `drv`,`REQUIRES phonerail_hal` - `test/test_ina226.c` — 17 个用例 - `host/CMakeLists.txt` — 加 `PHONERAIL_DRV_SRCS` 与 `drv/include` - `main/CMakeLists.txt` — `REQUIRES phonerail_hal drv` ## 验收命令与结果 ``` $ bash host/test.sh 100% tests passed, 0 tests failed out of 4 # +test_ina226(17 个用例) $ .\build_idf.ps1 # PowerShell phonerail.bin binary size 0x32550 bytes. ... 0xcdab0 bytes (80%) free. Project build complete. # build/esp-idf/drv/.../ina226.c.obj 确认编到了 ``` ## 踩到的坑(只写会再犯的) - **别依赖 I²C 寄存器指针自增**:sim 的假器件**会**自增,INA226 按 datasheet **不会**。 「一次 write_read 连读 0x01~0x04」在宿主机上全绿,到板上四个量会读成同一个。 驱动每次读之前重写指针,`test_pointer_is_rewritten_before_every_read` 盯着这条。 (指针不自增这条**未在实物上验过**,B1 上板时确认。) - **`write_verify()` 之后 `last_write` 是那次回读的指针字节(len 1),不是刚写的三字节。** 按「最后一次写就是我写的数据」写断言会红一次 —— 改看 `n_write`/`n_read` 计数。 - cygwin 并行链接偶发 `Error running link command: Subprocess aborted`(这次是 test_version)。 **重跑一次就好**,不是代码问题,别去查。 ## 这个驱动的几条约定(写 A7 / A10 之前看一眼) - **地址查表**:`ina226_rail_addr(rail)`,rail 是 **1~5**(不是 0~4),越界 abort。 `ina226_all_addr[6]` 供扫描用;`ina226_addr_table_ok()` 做启动自检(含与 DAC 0x4A/0x4B、PCA9555 0x20、LM75 0x48 的撞车检查)。 - **单位**:`bus_mv` / `shunt_uv` / `current_ua` / `power_mw`,全是 `int32_t`。 电流 LSB 0.5 mA ⇒ `current_ua` 一定是 500 的整数倍;−60 mA(SW-8 判据)= `-60000`。 - **巡检走 `ina226_read_vi()`**(只读母线电压 + 电流,两次事务)—— §10.3 那 8 % 的 I²C 占用是按「每片每 20 ms 两次事务」算的,读四个量会翻倍。 - **`HAL_ERR_BUS` 在这个驱动里有特定含义**:器件应答了但内容不对 (probe 的 ID 不匹配 = 贴错件/地址跳线焊错;init 的回读不一致;check 的 CAL 丢了)。 和「没这个器件」的 `HAL_ERR_NAK` 是两回事,降级矩阵(A15)要分开处理。 - **CAL 丢了不会报错,只会让 Current/Power 恒读 0**,看上去像「这台手机不耗电」。 所以有 `ina226_check()`,巡检里定期查一次、不一致就 `ina226_init()` 重来并记事件。 - Config 定为 **0x4327**(AVG=4、VBUSCT=VSHCT=1.1 ms、连续测量分流与母线), 转换周期 8.8 ms < t_safety 的 20 ms。改这个值前先算一遍这个不等式。