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

108 行
5.3 KiB
Python

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# -*- coding: utf-8 -*-
"""P3-CONTROL 网表(ESP32-S3 + USB-C 调试口 + I2C/开漏上拉 + NTC)。
用法:cd .claude && python -c "import p3_nets" —— 见 build_p3.py"""
import json, sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
'skills', 'easyeda-sch-geometry', 'scripts'))
os.environ.setdefault('PINS_JSON', '')
import local_netcheck as N # 需要当前目录有 pins.json
w, gnd, pwr, port, txt = N.w, N.gnd, N.pwr, N.port, N.txt
P = N.pin
# ── 【A】ESP32-S3 供电 / EN / GND ────────────────────────────────
w('+3V3', (205,615), (120,615)) # U20.3V3 横向母线
w('+3V3', (160,615), (160,700)) # 竖直母线
pwr('+3V3', 160, 700)
w('+3V3', (135,690), (160,690)) # C601 22uF
w('+3V3', (140,635), (160,635)) # C602 100nF
w('+3V3', (120,615), (120,590)) # -> R601.1(EN 上拉)
w('GND', (105,690), (80,690))
w('GND', (100,635), (80,635))
w('GND', (80,450), (80,690)) # GND 母线
gnd(80, 450)
w('EN', (205,605), (190,605), (190,530), (120,530), (120,550)) # U20.EN -> R601.2
w('EN', (120,530), (120,510)) # -> C603.1
w('GND', (120,470), (120,450), (80,450))
w('GND', (295,440), (320,440))
w('GND', (295,430), (320,430))
w('GND', (295,400), (320,400))
w('GND', (320,440), (320,380))
gnd(320, 380)
# ── 【A】ESP32 GPIO 引出(3 级错开 340/420/500)────────────────
GPIO = [
(790, 'NTC1'), (780, 'NTC2'),
(760, 'EFUSE_EN1'), (750, 'EFUSE_EN2'), (740, 'EFUSE_EN3'),
(730, 'EFUSE_EN4'), (720, 'EFUSE_EN5'),
(710, 'VBUS_EN1'), (700, 'VBUS_EN2'), (690, 'VBUS_EN3'),
(680, 'VBUS_EN4'), (670, 'VBUS_EN5'),
(660, 'SDA'), (650, 'SCL'),
(640, 'KEY_SER'), (630, 'KEY_SRCLK'), (620, 'KEY_RCLK'),
(610, 'USB_DM'), (600, 'USB_DP'), (590, 'KEY_OE#'),
(550, 'IOEXP_INT#'),
]
LVL = {0: 340, 1: 420, 2: 500}
for y, net in GPIO:
x = LVL[((790 - y) // 10) % 3]
w(net, (295, y), (x, y))
port(net, x, y, 0)
# ── 【B】USB-C 调试口 ───────────────────────────────────────────
w('GND', (65,345), (65,225)) # 外壳 4 脚
w('GND', (45,225), (135,225)) # 底部地轨
w('GND', (45,225), (45,375))
w('GND', (45,375), (160,375))
w('GND', (160,375), (160,345), (135,345)) # 上侧 GND 脚绕回
w('GND', (135,235), (135,225)) # 下侧 GND 脚
gnd(45, 225)
w('USB_DP', (135,285), (330,285)) # DP1
w('USB_DP', (135,305), (310,305), (310,285)) # DP2 汇合(与 DM 交叉 1 处)
w('USB_DP', (310,305), (310,320)) # 端口向上引,避开 DM 横线
port('USB_DP', 310, 320, 0)
w('USB_DM', (135,295), (390,295)) # DN1
w('USB_DM', (135,275), (370,275), (370,295)) # DN2 汇合
port('USB_DM', 390, 295, 0)
w('CC1', (135,265), (180,265))
w('CC2', (135,325), (180,325))
w('GND', (220,265), (450,265)) # R602 -> 地轨
w('GND', (220,325), (450,325)) # R603 -> 地轨
w('GND', (450,240), (450,325))
gnd(450, 240)
# ── 【C】I2C 上拉 + 开漏上拉 ────────────────────────────────────
for x, net in ((650,'SDA'), (730,'SCL'), (810,'BUCK_PG'),
(890,'INA_ALERT'), (980,'IOEXP_INT#')):
w('+3V3', (x,620), (x,650)); pwr('+3V3', x, 650)
w(net, (x,580), (x,550)); port(net, x, 550, 0)
# ── 【D】NTC 温度采样 ×2 ───────────────────────────────────────
for xr, xc, xp, net in ((660, 720, 790, 'NTC1'), (880, 940, 1010, 'NTC2')):
w('+3V3', (xr,400), (xr,430)); pwr('+3V3', xr, 430)
w(net, (xr,360), (xr,320)) # R618/R619 -> RT601/RT602
w('GND', (xr,280), (xr,250)); gnd(xr, 250)
w(net, (xr,340), (xc,340), (xc,330)) # -> 滤波电容
w('GND', (xc,290), (xc,260)); gnd(xc, 260)
w(net, (xc,340), (xp,340)); port(net, xp, 340, 0)
# ── 文字 ────────────────────────────────────────────────────────
txt('【A】ESP32-S3 主控', 45, 806)
txt('【B】USB-C 调试口', 45, 390)
txt('【C】I2C 上拉 4.7k + 三路开漏上拉', 645, 700)
txt('【D】NTC 温度采样(10k B3380 + 10k 分压 + 100nF)', 645, 470)
txt('3V3 来自 P1 的 U19,不依赖任何一路输出。', 45, 195)
txt('EN: 10k 上拉 + 100nF 到地,上电复位。', 45, 185)
txt('调试口走 ESP32-S3 原生 USB-Serial-JTAG。', 45, 175)
txt('VBUS 故意不接:板子由 12V 供电,杜绝反灌。', 45, 165)
txt('CC1/CC2 各 5.1k 下拉,对外表现为 UFP。', 45, 155)
txt('不接的脚:IO0/IO3、IO45/IO46 是 strapping;', 45, 145)
txt('IO35~IO37 留 PSRAM;IO39~IO42 留 JTAG;', 45, 135)
txt('IO47/IO48 备用;RXD0/TXD0 引到 PCB 测试点。', 45, 125)
NC = {
'U20': ['27','15','28','29','30','32','33','34','35','26','16','24','25','36','37'],
'J22': ['A4B9','B4A9','A8','B8'],
}