HaiNguyenEE/axon-c

GitHub: HaiNguyenEE/axon-c

AXON-C 是一款 ESP32-S3 双 USB-C 四层阻抗控制开发板,附带从 Altium 源文件自动生成的完整文档、高速信号完整性分析和板级自检固件。

Stars: 0 | Forks: 0

# AXON-C v1.0 一块带有**两个 USB-C 接口**的 ESP32-S3 开发板 —— 一个直接连接到 芯片的原生 USB 外设,另一个位于 FT231XQ USB 转 UART 桥接器之后 —— 集成在 68.6 × 25.4 mm **4 层阻抗控制 PCB** 上,具有 90 Ω 差分 USB 走线。 **顶层** ![AXON-C v1.0 — 顶层铜箔、焊盘与丝印](https://static.pigsec.cn/wp-content/uploads/repos/cas/66/663f5b8cc1657df7db0a75fd5f08ec0ed701ac27e30670f8c338744bfc64d21f.png) **底层** —— 丝印包含 `AXON-C v1.0`, `(C) 2026 HAI NGUYEN`, `github.com/HaiNguyenEE` 和 `eerfLab.com`,以及两个排针的完整引脚图。 ![AXON-C v1.0 — 底层铜箔、焊盘与丝印](https://static.pigsec.cn/wp-content/uploads/repos/cas/14/14c4ef7e4d3922a12893ea5bc59d8fe26cd2694560032a7c66437e908abdc0b2.png) 这些都不是截图。这两张图都是由 [`tools/mkboardview.py`](tools/mkboardview.py) 根据 `ESP32wUSB.PcbDoc` 内部的制造几何图形逐像素绘制出来的 —— 铜箔、覆铜、ENIG 焊盘、钻孔和丝印全部提取自二进制 Altium 数据流, 并像板厂那样根据布线的板框进行裁剪。 `esp32-s3` · `usb-c` · `pcb-design` · `high-speed-pcb` · `differential-pair` · `signal-integrity` · `controlled-impedance` · `altium-designer` · `hardware-design` · `ft231x` · `platformio` · `jlcpcb` · `4-layer-pcb` · `reverse-engineering` 设置两个接口的意义在于你无需再做选择。**ESP** 接口直接通过 GPIO19/20 为你提供 原生 USB(CDC, MSC, HID, TinyUSB)。**UART** 接口为你提供一个 带有硬件 DTR/RTS 自动复位功能的经典 FTDI 控制台,因此 `esptool` 可以 在不触碰任何按钮的情况下将芯片置入下载模式。插入其中任意一个,或同时插入两个, 通过一个 3 针跳线决定由哪个接口为 5 V 电源轨供电。 本代码库中的所有内容 —— 引脚分配表、示意图、固件 —— 均从实际的 PCB 源文件生成,而非手工输入。详见 [本文档是如何生成的](#how-this-documentation-was-produced)。 ## 开发板一览 | | | |---|---| | **MCU** | ESP32-S3-MINI-1-N8 模块内置 ESP32-S3FN8 — 双核 Xtensa LX7 @ 240 MHz | | **Flash** | 8 MB,封装内 | | **PSRAM** | 无 | | **Radio** | 2.4 GHz Wi-Fi b/g/n + Bluetooth LE 5,PCB 天线 | | **USB** | 2 × USB-C 母座 (Molex 2171790001),均为仅供电 (5.1 kΩ CC 下拉) | | **USB-UART** | FTDI FT231XQ,带有 DTR/RTS 自动下载电路 | | **Regulator** | TI TL1963A-33 — 1.5 A LDO,5 V → 3.3 V | | **I/O** | 2 个 24 针 2.54 mm 排针 (Molex KK254) 上的 40 个 GPIO | | **Protection** | 6 × AQ3045-01ETG ESD 抑制器,位于两路 VBUS 和两路 USB 数据对上 | | **Board** | 68.6 × 25.4 mm (2.700 × 1.000 in),4 层,1.56 mm | | **Stackup** | 阻抗控制 — 0.0994 mm 半固化片 / 1.265 mm 芯板,外层 1 oz,内层 ½ oz,完整内部 GND 平面 | | **High speed** | `DIFF90` 类中的 3 个差分对 — 6.03 mil / 8 mil,约 90 Ω 差分阻抗 | ## ⚠ v1.0 存在两个阻碍下单的勘误 **不要直接按照此版本图纸进行制造。** 通过解析 PCB 文件发现 `UART` 路径上 存在两个独立的故障,在 CAD 中均属于双网络修复: | | 故障 | 影响 | |---|---|---| | **[E4](docs/HARDWARE.md#errata-for-v10)** | USB **D+ 和 D− 在 FT231XQ 处接反** — `CON1_USB_P` 连到了引脚 9 (`USBDM`),`CON1_USB_N` 连到了引脚 8 (`USBDP`) | 桥接器无法枚举 — 完全无法识别到串口 | | **[E1](docs/HARDWARE.md#errata-for-v10)** | UART0 的 **TX 接 TX,RX 接 RX** (通过 R20/R21) | 两个输出相互冲突,两个输入悬空 — 无法传输任何字符 | **`ESP` 接口不受影响**,开发板完全可通过原生 USB 正常使用。完整的 追踪记录、返工几何图形以及针对这两个问题的 CAD 修复方案均位于 [docs/HARDWARE.md § Errata](docs/HARDWARE.md#errata-for-v10) 中。 ## 开发板映射图 ![带有丝印的顶视图](https://static.pigsec.cn/wp-content/uploads/repos/cas/57/5708af3c5fa2445b19b695aca86269d7221e99b43972d974199189c5bbf7b280.png) | 丝印 | 器件 | 描述 | |---|---|---| | `U1` | ESP32-S3-MINI-1-N8 | 模块。PCB 天线悬于右侧边缘。 | | `U2` | FT231XQ | 用于 **UART** 接口的 USB 转 UART 桥接器 | | `U3` | TL1963A-33 | 3.3 V LDO | | `UART` | J3 | 连接到 FT231XQ 的 USB-C 接口 | | `ESP` | J4 | 连接到芯片原生 USB (GPIO19/20) 的 USB-C 接口 | | `J1` | 24 针排针 | 顶排 — GPIO0…GPIO18, +3V3, +5V, GND | | `J2` | 24 针排针 | 底排 — GPIO19…GPIO48, UART0, EN, +3V3, GND | | `RESET` | SW2 | 拉低 `CHIP_PU` | | `USER` | SW1 | 拉低 `GPIO0` — 在复位时保持可进入下载模式 | | `POW` | D1, 绿色 | 硬连接至 +3V3。只要电源轨有电就会亮起。**不可由软件控制。** | | `USER` | D2, 红色 | 位于 GPIO2,**低电平有效** | | `REG`/`3V3` | J5 | 2 针跳线:LDO 输出 → 3.3 V 电源轨 | | `USB1`/`+5V`/`USB2` | J6 | 3 针跳线:决定由哪个 USB-C 接口为 5 V 电源轨供电 | ## 上电前必读 必须正确设置两个跳线,否则将毫无反应。 **J5 (`REG` — `3V3`)** 将 LDO 输出连接到开发板的 3.3 V 电源轨。如果拔下跳线帽, ESP32-S3 将完全断电。将其保持断开是有意为之:这使得 J5 成为了 整个 3.3 V 电源轨的电流测量点,这正是你在不断开走线的情况下测量 Deep Sleep 电流的方法。在 J5 两端串联一个万用表,你就可以读取 所有下游的电流消耗。 **J6 (`USB1` — `+5V` — `USB2`)** 用于选择由哪个 USB-C 接口提供 5 V 电源。`USB1` 是 **UART** 接口 (J3),`USB2` 是 **ESP** 接口 (J4)。中间的引脚是开发板的 `+5V` 节点, 负责为 LDO 和排针引脚 J1-22 供电。这里没有 ORing 二极管,也没有电源多路复用器 —— 跳线帽是连接两个 VBUS 电源轨的唯一部件,因此**切忌在插有两个充电器的情况下 同时短接两侧。** 只有 UART 接口的 VBUS 受到监控:一个从 `+5V_VBUS1` 引出的 4.7 kΩ / 10 kΩ 分压器 驱动 FT231XQ 的 VBUS 检测输入。ESP 接口的 VBUS 没有检测分压器。 ## 引脚分配 ![AXON-C 引脚分配](https://static.pigsec.cn/wp-content/uploads/repos/cas/f2/f27e17a5c9f6fb02241d13603f0e086f4fc8937e26e48df0ad4dfb60ad90c686.png) 完整的引脚表格(包含 PCB 文件中出现的每一个网络名称)位于 **[docs/PINOUT.md](docs/PINOUT.md)** 中。以下是你需要注意的事项简述: | 引脚 | 为何它不仅仅是一个 GPIO | |---|---| | GPIO0 | Strapping(启动模式)。通过 27 Ω 串联电阻连接到 `USER` 按钮,并连接到自动下载晶体管。 | | GPIO2 | 驱动红色 `USER` LED。可用作 I/O,但会导致 LED 闪烁。 | | GPIO3, GPIO45, GPIO46 | Strapping 引脚 — JTAG 源、VDD_SPI 电压电平、ROM 启动日志。 | | GPIO19, GPIO20 | 原生 USB D− / D+。引出至 J2-21 / J2-20,但它们是 `ESP` 接口的数据对。 | | GPIO43, GPIO44 | UART0 TX / RX,由 FT231XQ 驱动。只有在拔下 UART 接口时才被释放。 | | GPIO26 | 默认为 `SPICS1`。在此处使用的 **-N8** 模块上可用;在 `-N4R2` 上**不可**用。 | | GPIO33 – GPIO37 | 在 **-N8** 上可用。在 `-N8R8` 及类似器件上保留给 Octal Flash/PSRAM 使用。 | ADC1 为 GPIO1–GPIO10,ADC2 为 GPIO11–GPIO20。ADC2 在 Wi-Fi 激活时会停止工作,因此 如果你需要在启用 Wi-Fi 的同时使用模拟输入,请保持在 J1 的引脚 4 至 13 上。 ## 烧录代码 **原生 USB(`ESP` 接口,J4)。** 将 J6 设置为 `USB2`,插入 `ESP`,S3 的 USB-serial-JTAG 外设将自动枚举。这是更简单的路径,且无需驱动。 **FTDI(`UART` 接口,J3)。** 将 J6 设置为 `USB1`,插入 `UART`。FT231XQ 的 DTR 和 RTS 信号线驱动两个 SS8050 晶体管控制 `CHIP_PU` 和 `GPIO0`,这是标准的 自动复位方案 —— `esptool` 会翻转 modem 控制线,芯片会自行 进入下载模式。无需按键。 **手动操作**(如果你需要的话):按住 `USER`,轻按 `RESET`,松开 `USER`。 ## 固件 [`firmware/`](firmware/) 包含一个专门为该开发板编写的启动和自检应用程序。 它不是一个简单的 blink 测试程序 —— 它是你在一块刚组装好的开发板上运行的程序, 用于测试组装厂是否合格。 开机时,它会打印芯片版本、Flash 大小、MAC 地址和复位原因,然后使 `USER` LED 呈心跳闪烁。通过串行控制台,它为你提供了一个交互式 shell: ``` axon> test run the full self-test axon> info chip / flash / heap / MAC / reset reason axon> led blink 100 drive the USER LED (remembering it is active LOW) axon> btn live state of the USER button axon> scan drive and read back every free header GPIO axon> adc 4 sample an ADC pin axon> i2c 8 9 scan an I2C bus on any two header pins axon> wifi scan for networks — proves the PCB antenna works axon> bootloader reboot into ROM download mode ``` 提供了两个 PlatformIO 环境,每个 USB 接口各一个: ``` cd firmware pio run -e axon-c-usb -t upload -t monitor # ESP port, native USB CDC pio run -e axon-c-uart -t upload -t monitor # UART port, FT231XQ ``` 构建和接线详情请见 [firmware/README.md](firmware/README.md);针对全新开发板的启动 流程 —— 在通电 5 V 之前测量什么、按什么顺序测量 —— 请见 [docs/BRINGUP.md](docs/BRINGUP.md)。 ## 高速设计 三个 USB 2.0 差分对穿过 4 层阻抗控制叠层。完整的 信号完整性记录 —— 规则、测量的几何尺寸、阻抗以及回流路径分析 —— 位于 **[docs/HIGHSPEED.md](docs/HIGHSPEED.md)** 中。以下是核心数据,全部提取自 PCB 文件而非凭空宣称: **叠层。** 0.0994 mm PP-006 半固化片 (Dk 4.1) / 1.265 mm FR-4 芯板 / 1 oz 外层铜箔 / ½ oz 内层,总厚度 1.5642 mm。这正是 JLCPCB 的 **JLC04161H-3313** 阻抗控制 叠层。**L3 是一个完整、未被分割的 GND 平面**;较薄的外介质使得 90 Ω 差分对能够以可制造的 6 mil 宽度进行布线。 **`DIFF90` 类。** `ESP_USB`、`CON1_USB` 和 `CON2_USB` 受到 `DiffPairsRouting` 规则约束:**8 mil 间距**,外层 6.03 mil 线宽,中间层 1 为 5.1 mil, 并且**最大非耦合长度为 500 mil** —— 此外还有一个专属的 6 mil 间距覆盖规则, 与开发板通用的 5 mil 间距相比,为差分对提供了与其他网络更大的空间。走线转角 为 45°,过孔直接连接到平面,而非通过散热焊盘连接。 **实际实现情况**,测量自 `Tracks6`/`Arcs6`/`Vias6`: | 差分对 | 边缘到边缘间距 | 预估 Z_diff | 对内偏差 | |---|---|---|---| | `ESP_USB` | **8.00 mil** — 严格符合规则 | 91.8 Ω | **1.4 ps** | | `CON2_USB` | **8.00 mil** — 严格符合规则 | 90.0 Ω | 9.2 ps\* | | `FTDI_USB` | 13.68 mil — 超出类规则范围 | 97.1 Ω | 1.2 ps | \* 连接器侧的网络包含 USB-C A6↔B6 / A7↔B7 翻转支持短截线,因此原始网络 长度超出了实际的电气路径。无短截线的差分对数据才是真实数值。 **回流路径。** 每一段走线的中点都经过了 19 个覆铜区域的测试, 按 `POURINDEX` 顺序进行,因此结果就是实际存在的铜箔。十条引脚走线中的八条 位于 **100% GND** 上方。`CON2_USB` —— 最长的差分对,56–57 mm —— 却并非如此: 每条走线大约有 40% 穿过 L2 层的 `+3V3` 和 `+3V3_REG` 覆铜区域, 每条走线有三个边界交叉点,距离最近的 GND 缝合过孔为 1.9–3.9 mm。在 12 Mbps 下 这是无害的,[文档中也对此直言不讳](docs/HIGHSPEED.md#5-return-paths-and-reference-plane-integrity) 而没有加以掩饰。在 High Speed 下则不然,不过在重新设计中可以轻松修复。 ## 图库 | | | |---|---| | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/b7/b72cb5af43f429fbf9c3a2fc1066dd25101400a752bf1c5d44203cb5b10bfbac.png) | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/db/dbb294f33a5490964f60571ceb59e871ea8d2994b424ed933d990ecc86aa1c1f.png) | | 顶部,倾斜视角 | 正面,展示两个 USB-C 母座 | | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/12/12ddd89d777ee627640c06b2a7805109a52f69c1f702780ccb4c1105a081ea30.png) | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/33/33cb6bd7ad2e94929b02b4221828495c26de3311c531665652bfb8de07b70815.png) | | **第 3 层 —— 内部接地平面。** 黄色部分是覆盖整块开发板的 GND 覆铜;这是内层,不是底层。底层在[本页顶部](#axon-c-v10)。 | 去除阻焊层 —— 裸铜和 ENIG | | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/d3/d3af3de7b180ebcd132bc06804749bb909bfecb90976bb5e5e0738e367cd446a.png) | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/cc/cc3203fca12f22da25e9ef157c4406fb84695169b1df28c9daa3c0f737bacd77.png) | | 顶部,从 USB-C 端看去 | 所有层,2D 视图 | | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/d4/d448ecfe5b1daa00ca8913d3921ed95c01abdd90cdc70b0e8bdaa452b2857f06.png) | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/5a/5ac819f231ca2170416d52eac3d54b40334b27ee51cbbcffb2fd46b490e61922.png) | | 底层布线 | 顶层锡膏 / 钢网开窗 | | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/f4/f400cf3326ca7153c2281f1aab92c2b43e91fa9e84214cf527945ceb4e196698.png) | ![](https://static.pigsec.cn/wp-content/uploads/repos/cas/57/5708af3c5fa2445b19b695aca86269d7221e99b43972d974199189c5bbf7b280.png) | | 焊盘上带有网络名称的装配图 | 直接从 Altium 导出的顶视图 | ## 仓库布局 ``` axon-c/ ├── docs/ │ ├── PINOUT.md every pin of J1 and J2, net names verbatim from the PCB │ ├── HARDWARE.md power tree, auto-program circuit, USB paths, errata, fitted/DNP │ ├── HIGHSPEED.md differential pairs, stackup, impedance, return-path analysis │ └── BRINGUP.md first-power-up procedure for a freshly assembled board ├── firmware/ │ ├── platformio.ini │ ├── README.md │ └── src/ │ ├── axon_c_board.h pin map, generated from the PCB netlist │ └── main.cpp bring-up self-test and serial shell ├── hardware/ │ ├── netlist.json component → pin → net, extracted from the PcbDoc │ ├── NETLIST.md the same thing, readable │ ├── extract_netlist.py the netlist extractor, so you can re-run it │ ├── highspeed.json stackup, rules, pair geometry, pours, impedance │ └── extract_highspeed.py the high-speed extractor ├── tools/ │ ├── mkboardview.py draws board-top.png and board-bottom.png from the PcbDoc │ └── mkpinout.py draws the pinout diagram from real PCB coordinates └── images/ ``` ## 本文档是如何生成的 本仓库中的引脚表并非肉眼对照原理图抄录的。`ESP32wUSB.PcbDoc` 是一个 OLE2 复合文档,其 `Nets6`、`Components6` 和 `Pads6` 数据流被直接解析, 以恢复哪个网络连接到了哪个器件的哪个焊盘上。 [`hardware/extract_netlist.py`](hardware/extract_netlist.py) 就是那个解析器;运行它 处理 PCB 文件,你就能得到 [`hardware/netlist.json`](hardware/netlist.json) 文件。 在进行任何信任之前,解码通过三种方式进行了验证:这 303 条焊盘记录 精确消耗了 82,330 字节中的 82,330 字节,没有任何剩余;扫描到的最高网络索引为 74(对应声明的 75 个网络);最高的器件索引为 65(对应声明的 66 个器件)。 记录布局中的任何一处偏移错误(off-by-one)都会破坏这三项的一致性。 这比听起来更重要。开发板渲染图中的任何内容都无法告诉你 `USER` LED 的朝向,而且输出文件夹中也没有原理图图像。从 PCB 文件中读取给出了答案:电流从 +3V3 流经 R19 进入 D2 然后流向 GPIO2, 因此**当 GPIO2 拉低时 LED 灯亮。** 用常规方式编写的 blink 程序,即使用 `digitalWrite(LED, HIGH)`,将会产生反向逻辑,且短时间内根本没人会察觉。 `images/pinout.svg` 中的示意图是由 `tools/mkpinout.py` 根据相同的提取数据生成的,包括开发板轮廓 —— 模块、按键、LED、跳线和 USB 母座都是根据 PCB 文件中的真实坐标绘制而成的。 本页顶部的两个开发板视图来自 [`tools/mkboardview.py`](tools/mkboardview.py), 它将解码过程推进了一大步:`Regions6` 用于覆铜(每条记录是一个 属性字符串,后跟一个 `u32` 顶点计数以及每个轮廓相应数量的双精度浮点数对, 首先是外边界,然后是孔),`Vias6` 用于 24 mil / 12 mil 的通孔,以及 偏移量 45 处的焊盘孔径记录。丝印是最微妙的部分 —— `Texts6` 为全部 66 个器件各自存储了一个位号和一个注释,无论它们是否被 打印,而且可见性开关根本不在 `Texts6` 中,而是在 `Components6` 中,即 `NAMEON` 和 `COMMENTON`。绘制所有 223 个字符串会使板子变得无法阅读;遵守这 两个标志位会去掉其中的 120 个,留下来的恰好就是板厂丝印的内容。底视图在 X 轴上进行了镜像,这既是你翻转板子时看它的方式,也是为什么 底层丝印 —— 存储时即作镜像以便透过板子阅读 —— 能够清晰可辨的原因。 相同的方法也用于生成高速分析。 [`hardware/extract_highspeed.py`](hardware/extract_highspeed.py) 深入剖析了 格式 —— `Rules6` 记录包含其他数据流所没有的两字节前缀,`Arcs6` 使用了 与 `Tracks6` 不同的记录类型字节,尺寸以带有单位后缀的字符串形式存储 (如 `'1.378mil'`),且必须通过 `LAYER{n}NEXT` 链遍历层叠结构,因为按顺序读取 `LAYER1..LAYER32` 会返回 28 个未使用的 FR-4 默认值。走线、 圆弧和过孔的几何结构随后给出了真实的布线长度、真实的差分对间距和真实的过孔数量; `Polygons6` 提供了覆铜区域,按 `POURINDEX` 顺序解析它们可以得到每条 走线的实际参考平面。 正是这些将“差分对看起来没问题”转变为了在任何 渲染图中都不可见的两个发现:测得的 8.00 mil 间距精确符合 8 mil 规则,以及 `CON2_USB` 每条走线穿过了三个参考平面边界。这也正是抓出 **E4** 的关键 —— 即 FT231XQ 处接反的 USB 数据对,这种故障在开发板照片上根本看不出来,如果不这么做, 直到付款组装后才会被发现。 ## 许可证 固件和文档采用 MIT 许可证 —— 详见 [LICENSE](LICENSE)。 此处不重新分发 PCB 源文件。本代码库中的渲染图和衍生引脚数据 描述的是该开发板的一个实体制造版本。
标签:Altium Designer, ESP32-S3, PCB设计, USB-C, 嵌入式系统, 硬件开发, 逆向工具, 阻抗控制