- 规则:铜层 2→4,差分 0.28/0.18,间距 0.15,过孔 0.3/0.2(rules_base) - 几何:98×98 板框 + 4×M3,槽阵居中,L1 12V 大铜 + 指头(pcb_base) - 摆位:五插槽留 L1,其余 133 件翻到 L4;背面镜像规则实测;Hub 放走廊 2、 东移 2.5 mm;扇出圈 / 小件间距 1.5(去耦例外)/ 9 A 过孔阵禁区(place_base) - 叠层按用户决定改为 L1 槽面 / L2 整层 +3V3 / L3 整层 GND / L4 器件面 - 布线:D± 七对按构造布通(USB3 掉头、USB1/2 北去掉头、USB4/5 东绕、 J23 桥),+3V3 / GND / +12V 平面网每脚一孔,0.125 网格 + PathFinder 开关(route_base、remote_route.ps1);剩 37 个网待手工补 - 铺铜:4 层重写,入口链自南向北切段 + 断面校核(pour_base); 已下发布线 / 缝合孔 / 铜面轮廓,填铜未成功(待查) - 工具:plot_base / plot_routes / shot_base,board_check 通孔两层都算 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_0168Bu6SEx3cXXCJLkdnE6zB
121 行
7.0 KiB
Python
121 行
7.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
u"""P3 / P3B / P6 三页的**图面文字整页重写**。
|
||
|
||
/c/Python314/python .claude/sch_text.py # 只看现状与计划
|
||
/c/Python314/python .claude/sch_text.py --push # 删光旧文字 -> 写一套新的
|
||
|
||
## 为什么要整页重写
|
||
|
||
2026-09-06 读回来发现这三页的 `sch_PrimitiveText` **层层叠了好几代**:
|
||
P3 有 44 条、P3B 64 条、P6 76 条,其中大量是**同一坐标同一内容的完全重复**
|
||
(历代脚本只 `create` 不 `delete`),还有互相矛盾的旧说明叠在一起。
|
||
渲染出来就是那一坨看不清的黑块 —— 而且 `verify_sch` / `xpage` / DRC
|
||
**四道验证一条都不管文字**,所以它烂了很久也没人发现。
|
||
|
||
⚠️ 判据:`sch_PrimitiveText` 只有图面注释,**标题栏不是它**
|
||
(标题栏字段是图框自己的,`getAll()` 里根本不出现),所以整页删干净是安全的。
|
||
|
||
顺带把 2026-09-06 换脚之后**变成假话**的几条改掉:
|
||
`IO39~IO42 留给 JTAG`、`IO47/IO48 备用`、`U22.Q7 = HUB_RST`、
|
||
`QA~QE = EDL_EN1~5;QF/QG/QH 备用不接`、`风扇座 KF2510-3A`。
|
||
"""
|
||
import json
|
||
import os
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
sys.path.insert(0, HERE)
|
||
from eda import run # noqa: E402
|
||
|
||
PAGE = {'P3': '12f74666e70167e4', 'P3B': 'f42285b3728794d0', 'P6': 'fd00f13e59336392'}
|
||
|
||
TEXT = {
|
||
'P3': [
|
||
(45, 806, u'【A】ESP32-S3-WROOM-1 主控(U20)'),
|
||
(45, 795, u'3V3 由 P1 的 U19 辅助 Buck 供给;EN 端 10k + 100nF 上电复位'),
|
||
(45, 395, u'【B】USB-C 调试口 —— ESP32-S3 原生 USB-Serial-JTAG(IO19/IO20)'),
|
||
(45, 384, u'VBUS 故意不接:板子由 12V 供电,避免 USB 反灌。CC1/CC2 各 5.1k 下拉作 UFP。'),
|
||
(645, 700, u'【C】I2C 上拉 4.7k + 三路开漏上拉'),
|
||
(645, 470, u'【D】NTC 温度采样(10k B3380 + 10k 分压 + 100nF)'),
|
||
# ⚠️ 右下角标题栏的左边界约在 x=476,y<210 那一片的文字末端必须 < 470
|
||
# (宽度按 CJK 12 / ASCII 6 估;`sch_text.py --push` 前会自己核一遍)
|
||
(45, 205, u'引脚按 PCB 几何重排(2026-09-06,§26.18):'),
|
||
(45, 194, u'除 USB(IO19/IO20 硬连线)与两路 NTC(要 ADC1)'),
|
||
(45, 183, u'外,全部信号走 GPIO matrix,落哪个脚都行 ——'),
|
||
(45, 172, u'按「出线方向 = 目的地方向」重排。'),
|
||
(45, 158, u'IO39~IO42 原留给引脚 JTAG,现改作 GPIO:'),
|
||
(45, 147, u'调试走原生 USB-Serial-JTAG(出厂 eFuse 默认),'),
|
||
(45, 136, u'板上没有 JTAG 排针。别烧 DIS_USB_JTAG。'),
|
||
(45, 122, u'有意不接:IO0/IO3/IO45/IO46 是 strapping;'),
|
||
(45, 111, u'IO35~IO37 留 R8 版 PSRAM;TXD0/RXD0 引到测试点;'),
|
||
(45, 100, u'IO4/IO5/IO7 空出来备用(三个都带 ADC1)。'),
|
||
],
|
||
'P3B': [
|
||
# ⚠️ 这三行右边 x=445 起是【B】PCA9555 那一块,末端要留在 430 以内
|
||
(45, 806, u'【A】(已搬走)74HC595 ×3 与 15 颗按键 MOS 2026-09-06 整窝挪到载板'),
|
||
(45, 795, u'(载板 C6-KEYS / C4-SITEn,§26.23)。KEY_SER/SRCLK/RCLK/OE#'),
|
||
(45, 784, u'四根线从 P3 的 ESP32 直接去 P5-BTB 的 J25 北排 3~6 行。'),
|
||
(445, 790, u'【B】PCA9555 输入扩展 —— 地址 0x20(A0/A1/A2 全接地)'),
|
||
(445, 779, u'IO0_7 与 IO1_5~7 备用脚直接接地:上电默认即输入,'),
|
||
(445, 768, u'固件严禁把 Port0[7] / Port1[7:5] 配成输出。'),
|
||
(45, 205, u'【C】DAC63204 ×2 —— 5 路调压'),
|
||
(45, 194, u'U6 = 0x4A(A0→SDA),U7 = 0x4B(A0→SCL)'),
|
||
(45, 180, u'三处 datasheet 强制要求,接错也不报错:'),
|
||
(45, 169, u' 1) FBx 必须接回 OUTx(电压模式的闭环反馈)'),
|
||
(45, 158, u' 2) CAP 接 2.2uF 到 AGND(LDO 旁路 0.5~15uF)'),
|
||
(45, 147, u' 3) VREF 空置时 100nF 到地 + 10k 上拉 VDD'),
|
||
(45, 136, u'内部基准 1.212V,×2 -> 满量程 2.424V(不是 2.5V)'),
|
||
(45, 122, u'通道按几何重排(§26.18):U6 = VDAC2/4/1(去西半板),'),
|
||
(45, 111, u'U7 = VDAC3/5(去东半板)。四通道对等,只改固件通道号。'),
|
||
],
|
||
'P6': [
|
||
(45, 806, u'【A】(已搬走)第三片 74HC595(U33)2026-09-06 随整条链挪到载板 C6-KEYS(§26.23)。'),
|
||
(45, 790, u'EDL_EN1~5 / HUB_RST 从此是载板内部网络,不再过排针。这一页只剩风扇。'),
|
||
(45, 520, u'【B】风扇:低边 N-MOS + PWM,5 个风扇并一路(§22.6)'),
|
||
(45, 500, u'Q6 AO3400A 切风扇回流,D2 SS34 做续流 —— 风扇是感性负载,'),
|
||
(45, 484, u'少了它 MOS 会被反峰打穿。FAN_PWM = IO18(模块脚 11),FAN_TACH = IO16(模块脚 9)。'),
|
||
(45, 468, u'5 个 TACH 并联做线或,停一个频率掉约 1/5(分不出是哪一个)。'),
|
||
(45, 444, u'TACH 必须分压:低边 PWM 关断时风扇地被抬到 12V,'),
|
||
(45, 428, u'TACH 是集电极开路,也跟着到 12V —— 直连 GPIO 会打穿 ESP32。'),
|
||
(45, 412, u'10k 上拉到 12V + 10k/3.3k 分压 -> 最高 2.98V。'),
|
||
(45, 396, u'关断期间读到稳定高电平(测不到转速),导通期间才有脉冲 ——'),
|
||
(45, 380, u'这是低边调速的固有限制,不是接线错。'),
|
||
(45, 190, u'风扇电流 4x0.10 + 1x0.30 = 0.70A @12V;'),
|
||
(45, 176, u'12V 输入预算 7.6 -> 8.3A,10A 适配器仍有余量。'),
|
||
(45, 162, u'风扇座 2510-3A 直针(C2803349):'),
|
||
(45, 148, u'pin1 = +12V,pin2 = 风扇回流(MOS 漏极),pin3 = TACH。'),
|
||
],
|
||
}
|
||
|
||
JS = u"""
|
||
await eda.dmt_EditorControl.openDocument('%s');
|
||
await new Promise(r => setTimeout(r, 1500));
|
||
const old = await eda.sch_PrimitiveText.getAll();
|
||
const ids = old.map(t => t.getState_PrimitiveId());
|
||
%s
|
||
const T = %s;
|
||
%s
|
||
await eda.sch_Document.save();
|
||
await new Promise(r => setTimeout(r, 800));
|
||
return {removed: ids.length, made: %d,
|
||
now: (await eda.sch_PrimitiveText.getAll()).length};
|
||
"""
|
||
DEL = u"if (ids.length) await eda.sch_PrimitiveText.delete(ids);"
|
||
MAKE = u"for (const t of T) await eda.sch_PrimitiveText.create(t[0], t[1], t[2], 0, null, null, 12);"
|
||
|
||
if __name__ == '__main__':
|
||
go = '--push' in sys.argv
|
||
for pg in ('P3', 'P3B', 'P6'):
|
||
rows = [[x, y, s] for x, y, s in TEXT[pg]]
|
||
print(u'%-4s 新文字 %d 条' % (pg, len(rows)))
|
||
if not go:
|
||
continue
|
||
r = run(JS % (PAGE[pg], DEL, json.dumps(rows, ensure_ascii=False), MAKE, len(rows)),
|
||
timeout=600)
|
||
assert r.get('success'), json.dumps(r, ensure_ascii=False)[:400]
|
||
q = r['result']
|
||
print(u' 删 %d / 建 %d / 现在 %d %s'
|
||
% (q['removed'], q['made'], q['now'], u'✅' if q['now'] == len(rows) else u'❌'))
|
||
if not go:
|
||
print(u'(未加 --push,没有改动)')
|