文件
phonerail/firmware/HANDOFF.md
T
zhou yang和Claude Opus 5 9eb1b39da6 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
2026-09-06 19:11:10 +08:00

4.5 KiB
原始文件 Blame 文件历史

交接

更新: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) 这两个常量。