A4:DAC63204 驱动 + rail_set_mv()
调压是**反向**的(DAC 码越大输出越低),所以整块换算只在 rail_mv_to_code() 里出现一次那个减法,除 rail.c 外任何地方都不许碰 dac63204_write_code()。 范围 3524~4010 mV,越界即拒(SR-13,第四道限制),4010 = Vd 0。 通道映射按 §26.18 重排过,五路里四路对不上「前三路在 U6、通道号 = rail−1」: CH1→U6.OUT2 / CH2→U6.OUT0 / CH3→U7.OUT0 / CH4→U6.OUT1 / CH5→U7.OUT1。 四通道电气对等 ⇒ 接错了板子照样正常工作,只是调错了路。设计文档 §17.2 那张 过期的通道表一并改掉了。 驱动只经 hal_i2c_*:认件(DEVICE-ID=01h,53204/43204 当 BUS 错拒掉)、 开内部基准 → 写增益 2× → 写安全码 → 才给用到的通道上电(COMMON-CONFIG 因此写两次: 复位码 0 就是输出上限 4.010 V),未用通道 FBx 悬空一律保持 Hi-Z。 三个「一定会被写出来的错」逐个改进去验过测试拦得住:反向关系写反 → test_rail 红; 忘了码左对齐、通道按 rail−1 算 → test_dac63204 红。 留给下次的两条:越界请求还没记事件(TODO(A11));两点标定还没做, 现在走理论公式,将来顶替的是 RAIL_VOUT0_UV / RAIL_DAC_SPAN_UV 两个常量。 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QYuExfgyYa6DzRRcUso8M8
这个提交包含在:
+45
-38
@@ -1,56 +1,63 @@
|
||||
# 交接
|
||||
更新:2026-09-06 完成任务包 **A3**(INA226 驱动 + 六片地址表)
|
||||
更新:2026-09-06 完成任务包 **A4**(DAC63204 驱动 + `rail_set_mv()`)
|
||||
|
||||
## 一句话现状
|
||||
六片 INA226 的地址表钉死在代码里(`0x40/41/44/45/42` + 输入侧 `0x43`),
|
||||
驱动能认件(MFG/DIE ID)、写 Config+CAL 并回读校验、读出 V / I / 分流 / 功率,
|
||||
电流**有符号**(反灌为负)。4 条 ctest(34 个用例)全绿,`idf.py build` 通过。
|
||||
五路输出电压能设了:`rail_set_mv(rail, mv)` 是唯一入口(rail 是 **1~5**),
|
||||
内部走 mV → Vd → 12 位码,**码越大电压越低**;4010 mV 以上、3524 mV 以下一律拒。
|
||||
两片 DAC 认件(DEVICE-ID=01h)、开内部基准、增益 2×、只给用到的通道上电,
|
||||
上电即 3.90 V。6 条 ctest(46 个用例)全绿,`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),同样查表不要算。
|
||||
**A5**:74HC595 24 位链 + 影子寄存器单一写入点(需求 §10.6「影子寄存器」那段 +
|
||||
设计文档 §17.2 的位表)。两条断言:①改 CH1 按键不动 CH2~5 的位 ②字节顺序 U33→U22→U21。
|
||||
⚠️ 位表也被 §26.18 重排过(`.claude/pinmap.py` 的 `P3B` / `P6` 两节是真表),
|
||||
和这次的 DAC 通道一样,**别照 §17.2 的旧表写**。
|
||||
|
||||
## 本次新增/修改的文件
|
||||
- `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`
|
||||
- `components/drv/include/dac63204.h` — 寄存器、位域、五路→(片,通道)映射(唯一对外契约)
|
||||
- `components/drv/dac63204.c` — 驱动本体(≈180 行,只经 `hal_i2c_*`)
|
||||
- `main/rail.h` / `main/rail.c` — mV ↔ 码的**唯一**换算与 `rail_set_mv()` / `rail_get_mv()`
|
||||
- `test/test_dac63204.c`(21 个用例)/ `test/test_rail.c`(12 个用例)
|
||||
- 三处 CMakeLists + `main/phonerail.h`(版本 `0.1.0-a4`)
|
||||
- `../需求文档.md` §10.5、`../五路直供电源板设计.md` §17.2 — 记落地 + **修掉过期的通道分配表**
|
||||
|
||||
## 验收命令与结果
|
||||
```
|
||||
$ bash host/test.sh
|
||||
100% tests passed, 0 tests failed out of 4 # +test_ina226(17 个用例)
|
||||
100% tests passed, 0 tests failed out of 6 # +test_dac63204(21) +test_rail(12)
|
||||
|
||||
$ .\build_idf.ps1 # PowerShell
|
||||
phonerail.bin binary size 0x32550 bytes. ... 0xcdab0 bytes (80%) free.
|
||||
Project build complete. # build/esp-idf/drv/.../ina226.c.obj 确认编到了
|
||||
Project build complete. # dac63204.c.obj 与 rail.c.obj 都在;bin 与 A3 同样大是正常的
|
||||
#(还没人调它们,链接器把符号丢了)
|
||||
|
||||
# 三个「一定会被写出来的错」逐个改进去跑过,确认测试拦得住:
|
||||
# 反向关系写反 -> test_rail 红;忘了左对齐 / 通道按 rail-1 算 -> test_dac63204 红
|
||||
```
|
||||
|
||||
## 踩到的坑(只写会再犯的)
|
||||
- **别依赖 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)。
|
||||
**重跑一次就好**,不是代码问题,别去查。
|
||||
- **12 位码在 `DAC-X-DATA` 里左对齐**(bit15-4,低 4 位 don't care)。忘了 `<< 4`
|
||||
不报错,只让输出变成 1/16 —— 而在本板上那是「五路都 4.010 V 满电」,看不出异常。
|
||||
- **两种步长**:`DAC-X-VOUT-CMP-CONFIG` 每通道跨 6(03/09/0F/15),`DAC-X-DATA` 连续(19~1C)。
|
||||
- **上电顺序**:`EN-INT-REF` 要先写(datasheet 明说增益设定之前必须已置位),
|
||||
安全码要在通道上电之前写(复位码 0 = Vd 0 V = 输出上限 4.010 V)。
|
||||
所以 `COMMON-CONFIG` 写两次。sim 只留寄存器终值看不到中间态,
|
||||
顺序是靠「`CC_REF_ONLY` 里四路输出全按住」+「`n_read` 计数」两条间接钉的。
|
||||
- **未用通道不许上电**:FBx 悬空时电压输出是开环运放(datasheet 表 5-1)。
|
||||
U6 用 OUT0/1/2、U7 只用 OUT0/1,所以 `COMMON-CONFIG` 是每片一个值,不是常量。
|
||||
- **cygwin 的偶发 `Subprocess aborted` 不止发生在链接**:这次 ctest 跑测试时
|
||||
`test_hal_sim` / `test_ina226` 同时挂了一次,重跑就全绿。**别去查代码。**
|
||||
|
||||
## 这个驱动的几条约定(写 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。改这个值前先算一遍这个不等式。
|
||||
## 这个驱动 / 这一层的几条约定(写 A7 / A10 / A12 之前看一眼)
|
||||
- **除 `rail.c` 外,任何地方都不许调 `dac63204_write_code()`。** 反向关系只在
|
||||
`rail_mv_to_code()` 里出现一次(那个减法),多一处就多一处写反的机会。
|
||||
- **查表不要算**:`dac63204_rail_addr()` / `dac63204_rail_ch()`,rail 是 1~5,越界 abort。
|
||||
CH1→U6.OUT2 / CH2→U6.OUT0 / CH3→**U7**.OUT0 / CH4→U6.OUT1 / CH5→U7.OUT1(§26.18)。
|
||||
四通道电气对等 ⇒ **接错了板子照样正常工作,只是调错了路**,功能测试测不出来。
|
||||
- **单位**:`rail_set_mv/rail_get_mv` 用 mV,`rail_code_to_vd_uv()` 用 µV。一个码在输出端
|
||||
只值 **0.119 mV**,往返误差 ≤ 1 mV 正常。`rail_get_mv()` 读的是**设定值不是实测**(实测走 INA226)。
|
||||
- **不要用 `rail_set_mv()` 做保护**(需求 §10.5 规矩 2):异常处理是 `EFUSE_EN` 的活。
|
||||
- **越界请求现在只返回 `HAL_ERR_ARG`,还没记事件** —— SR-13 要求记,`rail.c` 里
|
||||
留了 `TODO(A11)`,事件环形缓冲做完要回来补。
|
||||
- **标定还没做**(需求 §10.5 规矩 3):现在走理论公式,误差约 ±40 mV。
|
||||
将来两点标定要顶替的是 `RAIL_VOUT0_UV`(4010018) 与 `RAIL_DAC_SPAN_UV`(486416) 这两个常量。
|
||||
|
||||
在新工单中引用
屏蔽一个用户