# 交接 更新:2026-09-06 完成任务包 **A4**(DAC63204 驱动 + `rail_set_mv()`) ## 一句话现状 五路输出电压能设了:`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` 通过。 ## 下一步 **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/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 6 # +test_dac63204(21) +test_rail(12) $ .\build_idf.ps1 # PowerShell phonerail.bin binary size 0x32550 bytes. ... 0xcdab0 bytes (80%) free. Project build complete. # dac63204.c.obj 与 rail.c.obj 都在;bin 与 A3 同样大是正常的 #(还没人调它们,链接器把符号丢了) # 三个「一定会被写出来的错」逐个改进去跑过,确认测试拦得住: # 反向关系写反 -> test_rail 红;忘了左对齐 / 通道按 rail-1 算 -> test_dac63204 红 ``` ## 踩到的坑(只写会再犯的) - **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 / 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) 这两个常量。