# -*- coding: utf-8 -*- u"""P4B-HUB 网表:板载 USB 2.0 七口 Hub(USB2517I)。 硬件配置的 datasheet 依据逐条写在设计文档 **§21**,这里只管坐标和连线。 **为什么满页都是网络端口**:U32 是 65 脚 QFN,33 脚在左、32 脚在右,脚间距只有 10。 把外围器件直接连到脚上必然打结,所以每个用到的脚只引一小段 stub, 末端放**网络端口当页内标号**(P2 的 `VO1` 就是这个用法), 外围器件按功能分成 B1~B6 几块摆在四周,块与块之间靠端口名对上。 netport 约 10 单位高,在 10 的脚间距上排成一列不重叠(skill §8b-2); netflag 有 20 高,密集区放不下 —— 这是右侧一律用端口的原因。 用法: python .claude/build.py p4b_nets .claude/p4b-pins.json 7a469c6f43d6d0c8 [--push] """ import io, json, os, sys HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) sys.path.insert(0, os.path.join(HERE, 'skills', 'easyeda-sch-geometry', 'scripts')) import local_netcheck as N w, port, txt = N.w, N.port, N.txt PIN = json.load(io.open(os.path.join(HERE, 'p4b-pins.json'), encoding='utf-8')) def P(des, pin): x, y, _ = PIN[des][str(pin)] return (x, y) def gnd_dn(x, y): N.FLAGS.append(('Ground', 'GND', x, y, 0)) # 导线从上方来 def gnd_up(x, y): N.FLAGS.append(('Ground', 'GND', x, y, 180)) # 导线从下方来 def p3v3_up(x, y): N.FLAGS.append(('Power', '+3V3_HUB', x, y, 0)) # 导线从下方来 def p3v3_dn(x, y): N.FLAGS.append(('Power', '+3V3_HUB', x, y, 180)) # 导线从上方来 # U32:左 x=320,pin n 的 y = 660−(n−1)*10;右 x=680,pin n 的 y = 655−(65−n)*10 def L(n): return (320, 660 - (n - 1) * 10) def R(n): return (680, 655 - (65 - n) * 10) # ═════════ 左侧:五路下行 D±,以及几个电源 / strap 脚 ═════════ LEFT = [ (1, 'USB1_DM', 'OUT'), (2, 'USB1_DP', 'OUT'), (3, 'USB2_DM', 'OUT'), (4, 'USB2_DP', 'OUT'), (5, '+3V3_HUB', 'BI'), # VDDA33 (6, 'USB3_DM', 'OUT'), (7, 'USB3_DP', 'OUT'), (8, 'USB4_DM', 'OUT'), (9, 'USB4_DP', 'OUT'), (10, '+3V3_HUB', 'BI'), # VDDA33 (11, 'USB5_DM', 'OUT'), (12, 'USB5_DP', 'OUT'), (13, 'GND', 'BI'), # CFG_SEL2:buffer type 'I',纯输入,可直接接地 (19, 'GND', 'BI'), # TEST:'IPD',接地 (24, '+3V3_HUB', 'BI'), # VDD33CR (25, 'VDD18', 'BI'), # → C742 1µF(B2 块) ] for n, net, d in LEFT: px, py = L(n) w(net, (px, py), (170, py)) port(net, 170, py, 180, d) # rot=180 → 标签在引脚左侧 # ═════════ 右侧:上游 / 时钟 / 配置 strap ═════════ RIGHT = [ (65, 'GND', 'BI'), # VSS(含散热焊盘) (64, '+3V3_HUB', 'BI'), # VDD33PLL (63, 'RBIAS', 'BI'), (62, 'VDD18PLL', 'BI'), (61, 'XTAL1', 'BI'), (60, 'XTAL2', 'BI'), (59, 'UP_DP', 'BI'), (58, 'UP_DM', 'BI'), (57, '+3V3_HUB', 'BI'), # VDDA33 (56, 'PRTDIS7', 'BI'), # USBDN7_DP:10k 上拉 = 禁用口 7 (54, 'PRTDIS6', 'BI'), # USBDN6_DP:10k 上拉 = 禁用口 6 (52, '+3V3_HUB', 'BI'), # VDDA33 (46, '+3V3_HUB', 'BI'), # VDD33 (45, 'NONREM0', 'BI'), # SUSP_IND/LOCAL_PWR/NON_REM0 (44, 'VBUS_DET', 'IN'), (43, 'HUB_RST', 'IN'), # 由 74HC595 备用输出驱动(§21.7) (42, 'CFGSEL1', 'BI'), (41, 'CFGSEL0', 'BI'), (40, 'NONREM1', 'BI'), ] for n, net, d in RIGHT: px, py = R(n) w(net, (px, py), (760, py)) port(net, 760, py, 0, d) # ═══════════ B1 晶振:24MHz + 2×12pF(§21.4)═══════════ w('XTAL1', P('Y1', 1), (880, 690)) port('XTAL1', 880, 690, 180, 'BI') w('XTAL1', (920, 690), P('C740', 1)) w('GND', P('C740', 2), (920, 615)); gnd_dn(920, 615) w('XTAL2', P('Y1', 3), (1090, 710)) w('XTAL2', (1090, 710), P('C741', 1)) w('XTAL2', (1060, 710), (1060, 755)); port('XTAL2', 1060, 755, 0, 'BI') w('GND', P('C741', 2), (1090, 615)); gnd_dn(1090, 615) w('GND', P('Y1', 2), (1030, 655)); gnd_dn(1030, 655) w('GND', P('Y1', 4), (970, 755)); gnd_up(970, 755) # ═══════════ B2 RBIAS / VDD18PLL / VDD18 ═══════════ w('RBIAS', (960, 620), P('R708', 1)); port('RBIAS', 960, 620, 180, 'BI') w('VDD18PLL', (1060, 620), P('C743', 1)); port('VDD18PLL', 1060, 620, 180, 'BI') w('VDD18', (1130, 650), P('C742', 1)); port('VDD18', 1130, 650, 180, 'BI') w('GND', P('R708', 2), P('C742', 2)) # y=540 地轨,C743.2 在线上 w('GND', P('C742', 2), (1130, 510)); gnd_dn(1130, 510) # ═══════════ B3 端口 6/7 禁用:10k 上拉到 +3V3_HUB ═══════════ w('PRTDIS7', (900, 490), P('R715', 1)); port('PRTDIS7', 900, 490, 180, 'BI') w('PRTDIS6', (900, 450), P('R714', 1)); port('PRTDIS6', 900, 450, 180, 'BI') w('+3V3_HUB', P('R715', 2), (1060, 490)) w('+3V3_HUB', P('R714', 2), (1060, 450)) w('+3V3_HUB', (1060, 450), (1060, 490)) w('+3V3_HUB', (1060, 490), (1060, 520)); p3v3_up(1060, 520) # ═══════════ B4 四个 strap 下拉 + RESET 上拉 ═══════════ for des, net, x, stub, rot in (('R711', 'CFGSEL0', 920, 430, 180), ('R712', 'CFGSEL1', 970, 415, 0), ('R719', 'NONREM1', 1020, 430, 0), ('R720', 'NONREM0', 1070, 415, 0)): w(net, P(des, 1), (x, stub)); port(net, x, stub, rot, 'BI') w('GND', P('R711', 2), P('R720', 2)) # y=360 地轨,R712/R719 的下脚在线上 w('GND', (995, 360), (995, 330)); gnd_dn(995, 330) w('HUB_RST', P('R716', 1), (1130, 340)); port('HUB_RST', 1130, 340, 180, 'BI') w('+3V3_HUB', P('R716', 2), (1130, 250)); p3v3_dn(1130, 250) # ═══════════ B5 VBUS_DET 分压 100k/100k(5V → 2.5V)═══════════ w('VBUS_UP', P('R709', 1), (60, 450)); port('VBUS_UP', 60, 450, 0, 'IN') w('VBUS_DET', P('R709', 2), P('R710', 1)) w('VBUS_DET', (60, 360), (110, 360)); port('VBUS_DET', 110, 360, 0, 'OUT') w('GND', P('R710', 2), (60, 270)); gnd_dn(60, 270) # ═══════════ B6 上游 USB-C(J23,UFP)═══════════ # 正反两组脚靠**端口重名**并联,不拉长线互连 —— 免掉 Type-C 固有的一堆交叉 for pin, net, px in (('A1B12', 'GND', 280), ('B1A12', 'GND', 280), ('A4B9', 'VBUS_UP', 300), ('B4A9', 'VBUS_UP', 300), ('A6', 'UP_DP', 320), ('B6', 'UP_DP', 320), ('A7', 'UP_DM', 340), ('B7', 'UP_DM', 340)): x, y = P('J23', pin) w(net, (x, y), (px, y)) port(net, px, y, 0, 'BI') # CC1/CC2 各 5.1k 下拉 → 对外表现为 UFP(§15.1 边界 1) w('CC1', P('J23', 'A5'), P('R717', 1)) w('GND', P('R717', 2), (360, 85)); port('GND', 360, 85, 0, 'BI') w('CC2', P('J23', 'B5'), P('R718', 1)) w('GND', P('R718', 2), (360, 145)); port('GND', 360, 145, 0, 'BI') # 外壳固定脚接地 for sh in ('1', '2', '3', '4'): x, y = P('J23', sh) w('GND', (x, y), (120, y)) w('GND', (120, 135), (120, 165)) w('GND', (120, 135), (120, 105)); gnd_dn(120, 105) # ═══════════ 3V3 去耦 bank(PCB 上必须贴到各电源脚,§10)═══════════ BANK = ['C744', 'C745', 'C746', 'C747', 'C748', 'C749', 'C750', 'C751'] w('+3V3_HUB', P(BANK[0], 1), P(BANK[-1], 1)) # y=740 w('GND', P(BANK[0], 2), P(BANK[-1], 2)) # y=700 w('+3V3_HUB', (180, 740), (180, 775)); p3v3_up(180, 775) w('GND', (180, 700), (180, 670)); gnd_dn(180, 670) NC = { # 逐条理由见 §21.6:LED_A*/LED_B* 兼各种 strap,悬空取默认 '0'; # PRTPWR* 不接(通断权在 ESP32 手里);OCS*_N 内部上拉,悬空 = 无过流。 'U32': ['14', '15', '16', '17', '18', '20', '21', '22', '23', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '47', '48', '49', '50', '51', '53', '55'], 'J23': ['B8', 'A8'], # SBU1/SBU2 不用 } # 注释块挪到 U32 右下的空白带:原来放在左下角 (45, 95~185), # 六行长文字横穿 J23 的符号(几何验证不管文字,只有截图看得出来)。 txt(u'【P4B-HUB】板载 USB 2.0 七口 Hub —— 对外只有一根 USB 线(§15.1 / §21)', 45, 800, 15) txt(u'U32 USB2517I CFG_SEL[2:0]=000 → 内部默认配置 + strap 使能;寄存器 06h 默认 9Bh、bit7=1 = 自供电', 460, 300, 11) txt(u'(声明成总线供电,主机会按每口 100mA 做预算,而手机描述符要 500mA → 拒绝配置,枚举不上)', 460, 282, 11) txt(u'口 1~5 → CH1~CH5;口 6/7 由 R714/R715 各 10k 上拉禁用(拆掉电阻即可放出来)', 460, 264, 11) txt(u'RBIAS 必须 12.0k±1%;晶振 24MHz±350ppm;VDD18/VDD18PLL 各 ≥1µF 且 ESR<0.1Ω', 460, 246, 11) txt(u'VBUS_DET 接真·上游 VBUS(可插拔 Hub 必须如此),100k/100k 分压进 3.3V 逻辑', 460, 228, 11) txt(u'PRTPWR/OCS 全不接:端口通断由 ESP32 经 TPS22918 控制(§15.2 对策 2)', 460, 210, 11)