文件
zhou yang和Claude Opus 5 2bfe308b30 初始导入:PhoneRail 五路手机直供电源板
原理图/PCB 已在 EasyEDA 里做到 12 页跨页 0 漏接,固件刚完成骨架包 A1。
这次是把已有的一切一次性纳入版本控制,没有改动任何设计内容。

纳入:
- 设计与需求文档、PROGRESS.md、小米8 参考原理图 PDF 与追脚脚本
- .claude/ 下的 EasyEDA 桥接工具链与几何/网表缓存(eda-parts.json、
  pcb-parts.json、pcb-pads.json、p2-ch1.json 等,是重画各页的唯一事实来源)
- 117 张验证截图(本项目所有方向问题都是靠人眼看截图发现的,属于证据不是垃圾)
- firmware/ 的 A1 骨架与 site/ 文档站源码

.gitignore 排除:构建产物(firmware/build、host/build、sdkconfig)、
site/node_modules、__pycache__、桥接日志 _bridge.log、脚本自标的 *.stale。

.gitattributes 默认 `* -text`:现有 .py/.json 大多是 CRLF,原样存,
不让 git 重写行尾。唯一例外是 *.sh 强制 LF —— 带 \r 的 shell 脚本 bash 跑不了。

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QYuExfgyYa6DzRRcUso8M8
2026-09-06 18:18:14 +08:00

112 行
4.8 KiB
Python

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# -*- coding: utf-8 -*-
u"""C2-HUB 补一个上游 VBUS 检测分压:VBUS_UP(5V) -> 10k/20k -> UP_VBUS_DET -> 下板 IO44。
用法: /c/Python314/python .claude/c2_vbusdet.py [--push]
为什么要分压:J23 的 VBUS 是 5V,而排针那头接的是 ESP32 的 IO44(3.3V 域)。
10k/20k 得到 5×20/30 = 3.33V;USB 上限 5.25V 时是 3.5V,仍在 ESP32 的
绝对最大值 3.6V 以内,而且远高于 VIH(≈2.48V)。
主机没插时 VBUS=0 -> 读到 0,这正是这个信号要的判据。
"""
import json
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
from eda import run
PAGE = '472c9bdbd7180ac4' # C2-HUB
LIB = '0819f05c4eef4c71ace90d822a990e87'
R10K = 'c3b9baa5ef2e4070a4c0f9e9cd04fe6e' # C25744
R20K = '3a163ef2745c43cd822f855b5ea3efa4' # C25765
Y = 120
R721, R722 = (880, Y), (980, Y) # 上臂 10k / 下臂 20k
EXPECT = {'R721': [(860, Y), (900, Y)], 'R722': [(960, Y), (1000, Y)]}
def call(js, timeout=180):
r = run(js, timeout=timeout)
if not r.get('success'):
raise RuntimeError(json.dumps(r, ensure_ascii=False)[:800])
return r['result']
def main():
if '--push' not in sys.argv:
print(u'待加:R721 10k / R722 20k + VBUS_UP 端口 + UP_VBUS_DET 端口 + 地旗(加 --push)')
return
call("""
await eda.dmt_EditorControl.openDocument('%s'); await new Promise(r=>setTimeout(r,900));
const n=(await eda.dmt_Schematic.getCurrentSchematicPageInfo()).name;
if (n!=='C2-HUB') throw new Error('page='+n);
// 重跑安全:先把上一轮加的东西删掉
for (const c of await eda.sch_PrimitiveComponent.getAll()){
const t=c.getState_ComponentType();
if (t==='part' && ['R721','R722'].includes(c.getState_Designator())){
await eda.sch_PrimitiveComponent.delete(c.getState_PrimitiveId()); continue; }
if (t!=='netflag' && t!=='netport') continue;
let nn=''; try{nn=c.getState_Net()||''}catch(e){}
const x=Math.round(c.getState_X()), y=Math.round(c.getState_Y());
if (x>=700 && y<=180 && (nn==='UP_VBUS_DET' || nn==='GND' || nn==='VBUS_UP'))
await eda.sch_PrimitiveComponent.delete(c.getState_PrimitiveId());
}
for (const w of await eda.sch_PrimitiveWire.getAll()){
const a=w.getState_Line(); let hit=false;
for (let i=0;i<a.length;i+=2) if (a[i]>=700 && a[i+1]<=180) hit=true;
if (hit) await eda.sch_PrimitiveWire.delete(w.getState_PrimitiveId());
}
return 1;
""" % PAGE)
call("""
for (const [d,uuid,x,y] of %s){
await eda.sch_PrimitiveComponent.create({libraryUuid:'%s', uuid}, x, y, undefined, 0, false, true, true);
for (const c of await eda.sch_PrimitiveComponent.getAll()){
if (c.getState_ComponentType()!=='part') continue;
if (Math.round(c.getState_X())!==x || Math.round(c.getState_Y())!==y) continue;
await c.toAsync().setState_Designator(d).done();
}
}
return 1;
""" % (json.dumps([['R721', R10K, R721[0], R721[1]],
['R722', R20K, R722[0], R722[1]]]), LIB))
pins = call("""
const out={};
for (const c of await eda.sch_PrimitiveComponent.getAll()){
if (c.getState_ComponentType()!=='part') continue;
const d=c.getState_Designator();
if (d!=='R721' && d!=='R722') continue;
out[d]=(await c.getAllPins()).map(p=>[Math.round(p.getState_X()),Math.round(p.getState_Y())]);
}
return out;
""")
bad = [u'%s 期望 %s 实测 %s' % (d, EXPECT[d], sorted(map(tuple, pins.get(d, []))))
for d in EXPECT if sorted(map(tuple, pins.get(d, []))) != EXPECT[d]]
if bad:
raise SystemExit(u'引脚坐标对不上:\n ' + '\n '.join(bad))
print(u'引脚坐标核对通过')
W = [[800, Y, 860, Y], # VBUS_UP -> R721
[900, Y, 960, Y], # R721 -> R722(中点就在这一段上)
[930, Y, 930, 60], # 中点 -> UP_VBUS_DET
[1000, Y, 1050, Y], [1050, Y, 1050, 90]]
PT = [['BI', 'VBUS_UP', 800, Y, 180], ['BI', 'UP_VBUS_DET', 930, 60, 0]]
F = [['Ground', 'GND', 1050, 90, 0]]
TX = [(700, 175, u'上游 VBUS 检测:5V 经 10k/20k 分到 3.33V 送 IO44(§22.2)。主机没插时读 0。', 10)]
call("for (const s of %s) await eda.sch_PrimitiveWire.create(s); return 1;" % json.dumps(W))
call("for (const p of %s) await eda.sch_PrimitiveComponent.createNetPort(p[0],p[1],p[2],p[3],p[4],false); return 1;"
% json.dumps(PT))
call("for (const f of %s) await eda.sch_PrimitiveComponent.createNetFlag(f[0],f[1],f[2],f[3],f[4],false); return 1;"
% json.dumps(F))
call("for (const t of %s) await eda.sch_PrimitiveText.create(t[0],t[1],t[2],0,null,null,t[3],false,false,false,0); return 1;"
% json.dumps([list(t) for t in TX], ensure_ascii=False))
print(u'推送完成')
if __name__ == '__main__':
main()