文件
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

93 行
3.8 KiB
Python

# -*- coding: utf-8 -*-
u"""P4B-HUB 放元件(只放,不连线)。放完用 fetch_pins 读回真实引脚坐标。
用法: /c/Python314/python .claude/p4b_place.py
"""
import io, json, os, sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
from eda import run
PAGE = '7a469c6f43d6d0c8'
LIB = '0819f05c4eef4c71ace90d822a990e87'
P = {c: v['uuid'] for c, v in json.load(io.open(os.path.join(HERE, 'eda-parts.json'),
encoding='utf-8'))['parts'].items()}
# (位号, 立创号, x, y, rotation)
PARTS = [
# ── Hub 本体 ──
('U32', 'C478081', 500, 500, 0),
('Y1', 'C2762192', 880, 660, 0), # 24MHz 晶振
('C740', 'C1547', 950, 700, 90),
('C741', 'C1547', 950, 620, 90),
('R708', 'C25752', 1120, 600, 270), # RBIAS 12k 1%
('C742', 'C52923', 220, 380, 270), # VDD18(25) 1uF
('C743', 'C52923', 1070, 585, 270), # VDD18PLL(62) 1uF
# 端口 6/7 禁用上拉
('R714', 'C25744', 830, 545, 0),
('R715', 'C25744', 830, 565, 0),
# RESET_N 上拉
('R716', 'C25744', 960, 330, 270),
# VBUS_DET 分压
('R709', 'C25741', 1000, 300, 270),
('R710', 'C25741', 1000, 220, 270),
# 跳线下拉(这四个脚复位后是输出,必须串电阻,不能直接接地)
('R711', 'C25744', 880, 330, 270), # CFG_SEL0 / SCL
('R712', 'C25744', 920, 330, 270), # CFG_SEL1 / HS_IND
('R719', 'C25744', 840, 330, 270), # NON_REM1 / SDA
('R720', 'C25744', 1040, 330, 270), # NON_REM0 / SUSP_IND / LOCAL_PWR
# 3V3 去耦(PCB 上要贴到各电源脚,§10)
('C744', 'C1525', 620, 210, 270), ('C745', 'C1525', 660, 210, 270),
('C746', 'C1525', 700, 210, 270), ('C747', 'C1525', 740, 210, 270),
('C748', 'C1525', 780, 210, 270), ('C749', 'C1525', 820, 210, 270),
('C750', 'C1525', 860, 210, 270),
('C751', 'C440198', 900, 210, 270), # 3V3 储能 10uF
# ── 上游 USB-C ──
('J23', 'C165948', 980, 760, 0),
('R717', 'C25905', 1120, 700, 270), # CC1 下拉 5.1k
('R718', 'C25905', 1120, 640, 270), # CC2 下拉 5.1k
# ── 12V -> 5V(§9.4)──
('U30', 'C5210749', 150, 210, 0),
('L3', 'C76857', 290, 250, 0),
('C731', 'C440198', 60, 250, 270), ('C732', 'C440198', 95, 250, 270),
('C733', 'C1525', 215, 285, 270), # CB
('C734', 'C12891', 350, 250, 270), ('C735', 'C12891', 385, 250, 270),
('R706', 'C25741', 290, 150, 270), # FB 上 100k
('R707', 'C25854', 290, 90, 270), # FB 下 13.7k
# ── 5V -> 3V3(§9.5,只给 Hub)──
('U31', 'C6186', 470, 300, 0),
('C736', 'C440198', 410, 260, 270),
('C737', 'C12891', 540, 260, 270),
]
js_parts = json.dumps([[d, P[l], x, y, r] for d, l, x, y, r in PARTS])
js = """
await eda.dmt_EditorControl.openDocument('%s');
await new Promise(r=>setTimeout(r,1500));
const info = await eda.dmt_Schematic.getCurrentSchematicPageInfo();
if (info.name !== 'P4B-HUB') return {err:'页面不对', name:info.name};
for (const c of await eda.sch_PrimitiveComponent.getAll())
if (c.getState_ComponentType() !== 'sheet')
await eda.sch_PrimitiveComponent.delete(c.getState_PrimitiveId());
const P = %s;
const bad = [];
for (const [des, uuid, x, y, rot] of P) {
const c = await eda.sch_PrimitiveComponent.create(
{libraryUuid:'%s', uuid}, x, y, undefined, rot, false, true, true);
if (!c) { bad.push(des); continue; }
await c.toAsync().setState_Designator(des).done();
}
const n = (await eda.sch_PrimitiveComponent.getAll())
.filter(c=>c.getState_ComponentType()==='part').length;
return {placed: n, failed: bad};
""" % (PAGE, js_parts, LIB)
if __name__ == '__main__':
print(u'准备放 %d 个元件' % len(PARTS))
r = run(js, timeout=600)
print(json.dumps(r, ensure_ascii=False)[:800])