ShiboSoftwareDev/nema8-20mm-usbc-pd-controller

A 20×20 mm four-layer USB‑C PD stepper motor controller PCB using a CH32X035 MCU, TMC2209 driver, protected power inputs, USB data/boot interface, 3.3 V regulation, ESD/TVS protection, current-sense circuitry, and NEMA‑8 motor outputs.

Version
1.0.13
License
unset
Stars
0

four-layer.circuit.tsx

PCBPCB preview for four-layer.circuit.tsx
SchematicSchematic preview for four-layer.circuit.tsx
import { Fragment } from "react"
import { AutoroutingPipelineSolver9_PreloadedTraceGraph } from "@tscircuit/capacity-autorouter"
import { BAT54KFILM } from "./imports/BAT54KFILM"
import { BAT54WS } from "./imports/BAT54WS"
import { BM04B_SRSS_TB_LF__SN_ } from "./imports/BM04B_SRSS_TB_LF__SN_"
import { BSMD1206_110_16V } from "./imports/BSMD1206_110_16V"
import { CH32X035F8U6 } from "./imports/CH32X035F8U6"
import { HT7533_1 } from "./imports/HT7533_1"
import { PMEG6020ELRX } from "./imports/PMEG6020ELRX"
import { PT1206FR_7W0R33L } from "./imports/PT1206FR_7W0R33L"
import { TMC2209_LA_T } from "./imports/TMC2209_LA_T"
import { TL3780AF100QG } from "./imports/TL3780AF100QG"
import { TYPE_C_31_M_12 } from "./imports/TYPE_C_31_M_12"
import { TYPE_C_6P_LTH5_5_108 } from "./imports/TYPE_C_6P_LTH5_5_108"
import { USBLC6_2SC6 } from "./imports/USBLC6_2SC6"

const resistorParts: Record<string, string> = {
  "27": "C25100",
  "1k": "C11702",
  "4.7k": "C25900",
  "5.1k": "C25905",
  "10k": "C25744",
  "12k": "C25752",
  "47k": "C25792",
  "100k": "C25741",
  "270k": "C25770",
}

const capacitorParts: Record<string, { part: string; footprint: string; voltage: string }> = {
  "22nF_50V": { part: "C1532", footprint: "0402", voltage: "50V" },
  "100nF": { part: "C1525", footprint: "0402", voltage: "16V" },
  "100nF_50V": { part: "C14663", footprint: "0603", voltage: "50V" },
  "2.2uF_10V": { part: "C107370", footprint: "0402", voltage: "10V" },
  "2.2uF": { part: "C23630", footprint: "0603", voltage: "16V" },
  "10uF_25V": { part: "C96446", footprint: "0603", voltage: "25V" },
}

const R = ({ name, resistance, connections: _connections, ...props }: any) => (
  <resistor
    name={name}
    resistance={resistance}
    footprint="0402"
    supplierPartNumbers={{ jlcpcb: [resistorParts[resistance]] }}
    {...props}
  />
)

const C = ({ name, value, connections: _connections, ...props }: any) => {
  const item = capacitorParts[value]
  return (
    <capacitor
      name={name}
      capacitance={value.replace(/_\d+V$/, "")}
      footprint={item.footprint}
      maxVoltageRating={item.voltage}
      maxDecouplingTraceLength="50mm"
      supplierPartNumbers={{ jlcpcb: [item.part] }}
      {...props}
    />
  )
}

const nets = [
  "GND",
  "PD_VBUS_RAW",
  "PD_VBUS_FUSED",
  "VM",
  "USB_5V",
  "LOGIC_IN",
  "VIO",
  "PD_CC1",
  "PD_CC2",
  "DATA_CC1",
  "DATA_CC2",
  "USB_DM_CONN",
  "USB_DP_CONN",
  "USB_DM",
  "USB_DP",
  "BOOT_BIAS",
  "VBUS_ADC",
  "DIAG",
  "STEP",
  "DIR",
  "ENN",
  "STDBY",
  "UART_MCU",
  "UART_DRV",
  "V5_DRV",
  "VREF",
  "CP_HI",
  "CP_LO",
  "VCP",
  "SENSE_A",
  "SENSE_B",
  "MOTOR_A_NEG",
  "MOTOR_A_POS",
  "MOTOR_B_POS",
  "MOTOR_B_NEG",
] as const

const sheets = {
  power: "power",
  control: "control",
  driver: "driver",
} as const

const sections = {
  pdInput: "pd_input",
  logicPower: "logic_power",
  usbData: "usb_data",
  controller: "controller",
  driverCore: "driver_core",
} as const

const driverX = 0
const driverY = -0.5
const mcuX = 5.6
const mcuY = 0
const thermalViaOffsets = [
  [-0.7, -0.7], [-0.7, 0.7], [0.7, -0.7], [0.7, 0.7],
] as const

const traceWidthForNet = (name: (typeof nets)[number]) => {
  if (name.startsWith("MOTOR_")) return "0.3mm"
  if (name.startsWith("SENSE_")) return "0.3mm"
  if (name === "PD_VBUS_RAW" || name === "PD_VBUS_FUSED") return "0.5mm"
  if (name === "VM") return "0.4mm"
  if (["USB_5V", "LOGIC_IN", "VIO", "V5_DRV", "VCP"].includes(name)) return "0.25mm"
  return "0.15mm"
}

// Ground is carried by a dedicated inner-1 plane. Every outer-layer ground
// land gets a full-stack 0.30/0.45 mm through-via fanout into that plane.
const usbGroundVias = [
  { from: ".J_USB_PD > .GND1", x: -4.0, y: 0.06254755 },
  { from: ".J_USB_PD > .GND2", x: 2.749931, y: 0.06254755 },
  { from: ".J_USB_DATA > .GND1", x: 1.25, y: 2.174 },
  { from: ".J_USB_DATA > .GND2", x: 1.75, y: 2.174 },
] as const

const connectorShellGrounds = [
  { from: ".J_USB_PD > .EP1", x: 4.9, y: 0.7 },
  { from: ".J_USB_PD > .EP2", x: -4.9, y: 0.7 },
  { from: ".J_USB_DATA > .EH1", x: 5.2, y: 0.75 },
  { from: ".J_USB_DATA > .EH2", x: -5.2, y: 0.75 },
  { from: ".J_USB_DATA > .EH3", x: 5.2, y: -2.05 },
  { from: ".J_USB_DATA > .EH4", x: -5.2, y: -2.05 },
] as const

const driverEpGroundPaths = [
  { from: ".U_DRV > .GND2", path: [
    { x: -0.5, y: -1.3 },
    { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .GND1", path: [
    { x: 0, y: 1.3 },
    { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .SPREAD", path: [
    { x: 1.6, y: -2.5 }, { x: 1.6, y: -1.4 }, { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .MS1_AD0", path: [
    { x: 1.4, y: -1.0 }, { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .MS2_AD1", path: [
    { x: 1.4, y: -0.5 }, { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .CLK", path: [
    { x: 1.4, y: 1.0 }, { x: 0, y: 0 },
  ] },
  { from: ".U_DRV > .UNUSED", path: [
    { x: -1.4, y: 0 }, { x: 0, y: 0 },
  ] },
] as const

const groundFanouts = [
  // Coordinates are local to each source component (the pcbPath convention).
  { from: ".C_VM_HF1 > .pin2", x: 1.4, y: 0, fromLayer: "top" },
  { from: ".D_VM_TVS > .anode", x: 2.5, y: 0, fromLayer: "bottom" },
  { from: ".C_VM_BULK1 > .pin2", x: -0.83, y: -0.8, fromLayer: "bottom" },
  { from: ".C_VM_BULK2 > .pin2", x: -0.83, y: -0.8, fromLayer: "bottom" },
  { from: ".R_PD_CC1 > .pin2", x: -1.1, y: 0, fromLayer: "bottom" },
  { from: ".R_PD_CC2 > .pin2", x: -1.1, y: 0, fromLayer: "bottom" },
  { from: ".R_DATA_CC1 > .pin2", x: -0.51, y: 0.65, fromLayer: "bottom" },
  { from: ".R_DATA_CC2 > .pin2", x: -0.51, y: 0.65, fromLayer: "bottom" },
  { from: ".C_LDO_IN > .pin2", x: -1.4, y: 0, fromLayer: "bottom" },
  { from: ".U_3V3 > .GND", x: -1.9, y: -0.95, fromLayer: "bottom" },
  { from: ".C_LDO_OUT > .pin2", x: -1.0, y: 0, fromLayer: "bottom" },
  { from: ".C_MCU_HF > .pin2", x: -0.6, y: 0.7, fromLayer: "bottom" },
  { from: ".C_MCU_BULK > .pin2", x: -0.2, y: 1.0, fromLayer: "bottom" },
  { from: ".R_STDBY_PD > .pin2", x: 1.1, y: 0, fromLayer: "top" },
  { from: ".C_VIO > .pin2", x: 3.3, y: 0, fromLayer: "top" },
  { from: ".R_VREF_BOTTOM > .pin2", x: -0.7, y: 0.8, fromLayer: "bottom" },
  { from: ".R_VBUS_BOTTOM > .pin2", x: 0.8, y: 0, fromLayer: "top" },
  { from: ".R_SENSE_A > .pin2", x: -2.2, y: 0, fromLayer: "bottom" },
  { from: ".R_SENSE_B > .pin2", x: -2.0, y: 1.0, fromLayer: "bottom" },
] as const

// Explicitly enumerate the signal/power routes so the default autorouter does
// not waste channels trying to duplicate the copper-pour ground network.
const routedConnections = [
  [".J_USB_PD > .VBUS1", ".J_USB_PD > .VBUS2"],
  [".J_USB_PD > .VBUS2", ".F1 > .pin1"],
  [".F1 > .pin2", ".D_BLOCK > .anode"],
  [".D_BLOCK > .cathode", ".D_VM_TVS > .cathode"],
  [".D_VM_TVS > .cathode", ".C_VM_BULK1 > .pin1"],
  [".C_VM_BULK1 > .pin1", ".C_VM_BULK2 > .pin1"],
  [".C_VM_BULK2 > .pin1", ".D_LOGIC_PD > .anode"],
  [".D_LOGIC_PD > .anode", ".R_VBUS_TOP > .pin1"],
  [".D_LOGIC_PD > .anode", ".C_VM_HF1 > .pin1"],
  [".C_VM_HF1 > .pin1", ".U_DRV > .VS1"],
  [".U_DRV > .VS1", ".U_DRV > .VS2"],
  [".C_VM_HF1 > .pin1", ".C_VCP > .pin2"],
  [".J_USB_DATA > .VBUS1", ".J_USB_DATA > .VBUS2"],
  [".J_USB_DATA > .VBUS2", ".D_LOGIC_USB > .anode"],
  [".D_LOGIC_PD > .cathode", ".D_LOGIC_USB > .cathode"],
  [".D_LOGIC_USB > .cathode", ".U_3V3 > .VIN"],
  [".U_3V3 > .VIN", ".C_LDO_IN > .pin1"],
  [".U_3V3 > .VOUT", ".C_LDO_OUT > .pin1"],
  [".C_LDO_OUT > .pin1", ".U_MCU > .VDD"],
  [".U_MCU > .VDD", ".C_MCU_HF > .pin1"],
  [".C_MCU_HF > .pin1", ".C_MCU_BULK > .pin1"],
  [".C_MCU_HF > .pin1", ".R_BOOT > .pin1"],
  [".C_MCU_BULK > .pin1", ".R_EN_PU > .pin1"],
  [".R_EN_PU > .pin1", ".U_DRV > .VCC_IO"],
  [".U_DRV > .VCC_IO", ".C_VIO > .pin1"],
  [".U_DRV > .VCC_IO", ".U_USB_ESD > .VBUS"],
  [".J_USB_PD > .CC1", ".U_MCU > .CC1"],
  [".J_USB_PD > .CC2", ".U_MCU > .CC2"],
  [".J_USB_DATA > .CC1", ".R_DATA_CC1 > .pin1"],
  [".J_USB_DATA > .CC2", ".R_DATA_CC2 > .pin1"],
  [".J_USB_DATA > .DN1", ".U_USB_ESD > .DM_IN"],
  [".J_USB_DATA > .DN2", ".U_USB_ESD > .DM_IN"],
  [".J_USB_DATA > .DP1", ".U_USB_ESD > .DP_IN"],
  [".J_USB_DATA > .DP2", ".U_USB_ESD > .DP_IN"],
  [".U_USB_ESD > .DM_OUT", ".U_MCU > .USB_DM"],
  [".U_USB_ESD > .DP_OUT", ".U_MCU > .USB_DP"],
  [".U_MCU > .USB_DP", ".SW_BOOT > .pin102"],
  [".R_BOOT > .pin2", ".SW_BOOT > .pin101"],
  [".R_VBUS_TOP > .pin2", ".R_VBUS_BOTTOM > .pin1"],
  [".R_VBUS_BOTTOM > .pin1", ".U_MCU > .VBUS_ADC"],
  [".U_DRV > .DIAG", ".U_MCU > .DIAG_IN"],
  [".U_DRV > .STEP", ".U_MCU > .STEP_OUT"],
  [".U_DRV > .DIR", ".U_MCU > .DIR_OUT"],
  [".U_DRV > .ENN", ".U_MCU > .ENABLE_OUT"],
  [".U_DRV > .ENN", ".R_EN_PU > .pin2"],
  [".U_DRV > .STDBY", ".U_MCU > .STDBY_OUT"],
  [".U_DRV > .STDBY", ".R_STDBY_PD > .pin1"],
  [".U_MCU > .UART1", ".U_DRV > .PDN_UART"],
  [".U_MCU > .UART1", ".U_DRV > .PDN_UART"], // reserved duplicate; not rendered
  [".U_DRV > .5VOUT", ".C_5V > .pin1"],
  [".C_5V > .pin1", ".R_VREF_TOP > .pin1"],
  [".R_VREF_TOP > .pin2", ".R_VREF_BOTTOM > .pin1"],
  [".R_VREF_BOTTOM > .pin1", ".C_VREF > .pin1"],
  [".C_VREF > .pin1", ".U_DRV > .VREF"],
  [".U_DRV > .CPO", ".C_CP > .pin1"],
  [".U_DRV > .CPI", ".C_CP > .pin2"],
  [".U_DRV > .VCP", ".C_VCP > .pin1"],
  [".U_DRV > .BRA", ".R_SENSE_A > .pin1"],
  [".U_DRV > .BRB", ".R_SENSE_B > .pin1"],
  [".U_DRV > .OA2", ".J_MOTOR > .pin1"],
  [".U_DRV > .OA1", ".J_MOTOR > .pin2"],
  [".U_DRV > .OB1", ".J_MOTOR > .pin3"],
  [".U_DRV > .OB2", ".J_MOTOR > .pin4"],
  [".C_VM_HF1 > .pin2", ".U_DRV > .GND1"],
  [".D_VM_TVS > .anode", ".C_VM_BULK1 > .pin2"],
  [".D_VM_TVS > .anode", ".C_VM_BULK2 > .pin2"],
  [".U_DRV > .SPREAD", ".U_DRV > .EP"],
  [".U_DRV > .MS1_AD0", ".U_DRV > .EP"],
  [".U_DRV > .MS2_AD1", ".U_DRV > .EP"],
  [".U_DRV > .CLK", ".U_DRV > .EP"],
  [".U_DRV > .UNUSED", ".U_DRV > .EP"],
  [".R_DATA_CC1 > .pin2", ".R_DATA_CC2 > .pin2"],
  [".R_DATA_CC2 > .pin2", ".U_MCU > .GND"],
  [".U_USB_ESD > .GND", ".J_USB_DATA > .GND1"],
  [".C_LDO_IN > .pin2", ".U_3V3 > .GND"],
  [".C_LDO_OUT > .pin2", ".C_LDO_IN > .pin2"],
  [".U_3V3 > .GND", ".J_USB_DATA > .EH3"],
  [".C_MCU_HF > .pin2", ".U_MCU > .GND"],
  [".C_MCU_BULK > .pin2", ".U_MCU > .GND"],
  [".R_STDBY_PD > .pin2", ".U_DRV > .EP"],
  [".C_5V > .pin2", ".U_DRV > .EP"],
  [".C_VIO > .pin2", ".U_DRV > .EP"],
  [".R_VREF_BOTTOM > .pin2", ".U_DRV > .EP"],
  [".C_VREF > .pin2", ".U_DRV > .EP"],
  [".R_VBUS_BOTTOM > .pin2", ".U_MCU > .GND"],
  [".C_VM_BULK1 > .pin2", ".J_USB_PD > .GND1"],
  [".C_VM_BULK2 > .pin2", ".J_USB_PD > .GND2"],
  [".R_SENSE_A > .pin2", ".U_DRV > .EP"],
  [".R_SENSE_B > .pin2", ".U_DRV > .EP"],
] as const

const traceWidthForRouteIndex = (index: number) => {
  if (index <= 2) return "0.5mm"
  if (index <= 11) return "0.4mm"
  if (index >= 57 && index <= 62) return "0.3mm"
  if (index === 63) return "0.3mm"
  if (index === 64 || index === 65) return "0.5mm"
  if (index >= 71 && index <= 73) return "0.2mm"
  if (index >= 74 && index <= 76) return "0.25mm"
  if (index >= 77 && index <= 83) return "0.2mm"
  if (index === 84) return "0.2mm"
  if (index === 85 || index === 86) return "0.5mm"
  if (index === 87 || index === 88) return "0.3mm"
  if ((index >= 12 && index <= 25) || index === 49 || index === 50 || index === 56) return "0.25mm"
  if (index === 54 || index === 55) return "0.2mm"
  return "0.15mm"
}

const routeNames = (start: number, end: number) =>
  Array.from({ length: end - start + 1 }, (_, offset) => `ROUTE_${start + offset}`)

// Keep signal and power nets under the default autorouter. This avoids the
// partial-layer via definitions that hand routing can accidentally introduce;
// every layer transition is generated as a normal plated through-via.
const manualRouteIndexes = new Set<number>([51])

const manualPcbPathForRouteIndex = (index: number): any[] | undefined => {
  if (index === 14) return [
    { x: 0.8, y: 1.6 },
    { x: 4.6, y: 1.6 },
    { x: 4.6, y: 0.6 },
    { x: 4.34, y: 0.6 },
  ]
  if (index === 15) return [
    { x: 1.14, y: 0 },
    { x: 0.2, y: 0.5 },
    { x: 0.2, y: 10.5 },
    { x: 1.1, y: 10.5 },
    { x: 1.1, y: 12.6 },
    { x: 0.63, y: 12.6 },
  ]
  if (index === 16) return [
    { x: 1.23, y: 0 },
    { x: 1.6, y: -1.0 },
    { x: 1.6, y: -2.975 },
  ]
  if (index === 24) return [
    { x: 1.8, y: 2.5 },
    { x: 3.2, y: 2.3 },
  ]
  if (index === 26) return [
    { x: -0.55, y: 1.2 },
    { x: -0.55, y: 1.2, via: true, fromLayer: "top", toLayer: "inner2" },
    { x: -0.55, y: 1.2 },
    { x: 5.4, y: 1.2 },
    { x: 4.7, y: 4.2 },
    { x: 4.7, y: 4.2, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: 4.7, y: 4.2 },
    { x: 4.9, y: 4.6 },
  ]
  if (index === 27) return [
    { x: 0.55, y: 1.2 },
    { x: 0.55, y: 1.2, via: true, fromLayer: "top", toLayer: "inner1" },
    { x: 0.55, y: 1.2 },
    { x: 0.55, y: 4.7 },
    { x: 4.0, y: 4.7 },
    { x: 4.0, y: 4.7, via: true, fromLayer: "inner1", toLayer: "bottom" },
    { x: 4.0, y: 4.7 },
    { x: 4.5, y: 5.0 },
  ]
  if (index === 28) return [
    { x: -2.4, y: 3.25 },
    { x: -3.0, y: 3.45 },
    { x: -3.0, y: 3.45, via: true, fromLayer: "top", toLayer: "bottom" },
    { x: -3.0, y: 3.45 },
    { x: -3.5, y: 4.05 },
    { x: -8.71, y: 4.05 },
  ]
  if (index === 29) return [
    { x: 0.75, y: 1.55 },
    { x: 0.75, y: -1.45 },
    { x: 0, y: -1.45 },
    { x: 0, y: -1.45, via: true, fromLayer: "top", toLayer: "bottom" },
    { x: 0, y: -1.45 },
    { x: -1.31, y: -2.55 },
  ]
  if (index === 34) return [
    { x: 1.0, y: -2.4 },
    { x: 1.0, y: -2.4, via: true, fromLayer: "bottom", toLayer: "inner2" },
    { x: 1.0, y: -2.4 },
    { x: 1.0, y: -5.6 },
    { x: -1.2, y: -7.8 },
    { x: -7.3, y: -7.8 },
    { x: -7.3, y: -7.8, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: -7.3, y: -7.8 },
    { x: -7.3, y: -5.0 },
    { x: -7.0, y: -4.5 },
  ]
  if (index === 36) return [
    { x: 0, y: 2.3 },
    { x: 0, y: 2.3, via: true, fromLayer: "bottom", toLayer: "inner1" },
    { x: 0, y: 2.3 },
    { x: -2.7, y: 2.3 },
    { x: -2.7, y: -5.5 },
    { x: -3.2, y: -5.5 },
    { x: -3.2, y: -5.5, via: true, fromLayer: "inner1", toLayer: "top" },
    { x: -3.2, y: -5.5 },
  ]
  if (index === 39) return [
    { x: 0.8, y: 1.0 },
    { x: 0.8, y: 1.0, via: true, fromLayer: "top", toLayer: "inner2" },
    { x: 0.8, y: 1.0 },
    { x: -2.6, y: 6.7 },
    { x: -2.6, y: 6.7, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: -2.6, y: 6.7 },
  ]
  if (index === 41) return [
    { x: 1.0, y: 3.3 },
    { x: 1.0, y: 3.3, via: true, fromLayer: "top", toLayer: "inner2" },
    { x: 1.0, y: 3.3 },
    { x: 1.5, y: 2.3 },
    { x: 1.5, y: -0.5 },
    { x: 3.2, y: -0.7 },
    { x: 3.2, y: -0.7, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: 3.2, y: -0.7 },
    { x: 3.2, y: 0.1 },
  ]
  if (index === 42) return [
    { x: -0.5, y: 2.5 },
    { x: -0.5, y: 3.3 },
    { x: 3.2, y: 3.3 },
    { x: 3.2, y: 3.3, via: true, fromLayer: "top", toLayer: "bottom" },
    { x: 3.2, y: 0.5 },
    { x: 3.8, y: 0.5 },
  ]
  if (index === 43) return [
    { x: -1.0, y: -3.2 },
    { x: -1.0, y: -3.2, via: true, fromLayer: "top", toLayer: "inner2" },
    { x: -1.0, y: -3.2 },
    { x: 3.5, y: -3.2 },
    { x: 3.5, y: 0.7 },
    { x: 3.7, y: 0.7 },
    { x: 3.7, y: 0.7, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: 3.7, y: 0.7 },
  ]
  if (index === 44) return [
    { x: -0.8, y: -3.2 },
    { x: -3.6, y: -3.2 },
  ]
  if (index === 45) return [
    { x: -1.0, y: 3.3 },
    { x: -2.2, y: 3.3 },
    { x: -2.2, y: 3.3, via: true, fromLayer: "top", toLayer: "inner2" },
    { x: -2.2, y: 3.3 },
    { x: -2.2, y: 3.7 },
    { x: 3.1, y: 3.7 },
    { x: 3.1, y: 3.2 },
    { x: 3.1, y: 3.2, via: true, fromLayer: "inner2", toLayer: "bottom" },
    { x: 3.1, y: 3.2 },
    { x: 3.1, y: 2.5 },
    { x: 4.5, y: 2.5 },
    { x: 4.5, y: 2.0 },
  ]
  if (index === 46) return [
    { x: -1.0, y: 3.0 },
    { x: -4.7, y: 2.7 },
  ]
  if (index === 47) return [
    { x: 2.1, y: -0.8 },
    { x: 2.1, y: -1.2 },
    { x: 2.1, y: -1.2, via: true, fromLayer: "bottom", toLayer: "top" },
    { x: 2.1, y: -1.2 },
  ]
  if (index === 49) return [
    { x: 3.0, y: -1.5 },
    { x: 3.5, y: -2.5 },
  ]
  if (index === 50) return [
    { x: 0, y: -0.9 },
    { x: 0, y: -0.9, via: true, fromLayer: "top", toLayer: "inner1" },
    { x: 0, y: -0.9 },
    { x: 0, y: -0.6 },
    { x: -4.1, y: -0.6 },
    { x: -4.1, y: 0.6 },
    { x: -4.1, y: 0.6, via: true, fromLayer: "inner1", toLayer: "bottom" },
    { x: -4.1, y: 0.6 },
    { x: -4.1, y: 1.61 },
  ]
  if (index === 51) return [
    { x: -0.51, y: 0 },
    { x: -0.51, y: -0.8 },
    { x: 2.81, y: -0.8 },
    { x: 2.81, y: 0 },
  ]
  if (index === 52) return [
    { x: 0.51, y: -0.7 },
    { x: 2.81, y: -0.7 },
  ]
  if (index === 53) return [
    { x: 0.2, y: 0 },
    { x: 0.2, y: 1.3 },
    { x: 0.2, y: 1.3, via: true, fromLayer: "bottom", toLayer: "top" },
    { x: 0.2, y: 1.3 },
  ]
  if (index === 54) return [{ x: 0, y: -3.2 }]
  if (index === 55) return [{ x: 0.5, y: -3.2 }]
  if (index === 56) return [
    { x: 1.0, y: -3.1 },
    { x: 1.5, y: -3.3 },
    { x: 2.19, y: -3.3 },
  ]
  if (index === 59) return [
    { x: -2.0, y: 2.0 },
    { x: -8.3, y: 2.0 },
  ]
  if (index === 60) return [
    { x: -3.0, y: 0.5 },
    { x: -3.5, y: 1.0 },
    { x: -8.3, y: 1.0 },
  ]
  if (index === 61) return [
    { x: -3.0, y: -0.5 },
    { x: -3.5, y: 0 },
    { x: -8.3, y: 0 },
  ]
  if (index === 62) return [
    { x: -2.5, y: -1.5 },
    { x: -6.8, y: -1.5 },
    { x: -8.3, y: -1.0 },
  ]
  if (index === 57) return [
    { x: -2.2, y: 1.0 },
    { x: -2.2, y: 1.0, via: true, fromLayer: "top", toLayer: "bottom" },
    { x: -2.2, y: 1.0 },
  ]
  if (index === 58) return [
    { x: -2.2, y: -1.0 },
    { x: -2.2, y: -1.0, via: true, fromLayer: "top", toLayer: "bottom" },
    { x: -2.2, y: -1.0 },
  ]
  return undefined
}

const routePhaseForIndex = (index: number) => {
  return index === 40 ? null : 1
}

const replaceAutoroutedRoute = (trace: any, route: any[]) => {
  const original = trace.route ?? []
  const firstPort = original.find((point: any) => point.start_pcb_port_id)?.start_pcb_port_id
  const lastPort = [...original].reverse().find((point: any) => point.end_pcb_port_id)?.end_pcb_port_id
  return {
    ...trace,
    route: route.map((point, index) => ({
      ...point,
      ...(index === 0 && firstPort ? { start_pcb_port_id: firstPort } : {}),
      ...(index === route.length - 1 && lastPort ? { end_pcb_port_id: lastPort } : {}),
    })),
  }
}

const postprocessDenseUsbRoutes = (traces: any[]) => {
  return traces.map((trace: any) => {
  const traceIdentity = `${trace.connection_name ?? ""} ${trace.pcb_trace_id ?? ""}`
  const route = trace.route ?? []
  const touches = (x: number, y: number) => route.some((point: any) =>
    Math.abs((point.x ?? Infinity) - x) < 0.01 && Math.abs((point.y ?? Infinity) - y) < 0.01)

  if (traceIdentity.includes("ROUTE_28") || touches(-0.69, 8.6)) {
    return replaceAutoroutedRoute(trace, [
      { route_type: "wire", x: 2.4, y: 3.876, width: 0.15, layer: "top" },
      { route_type: "wire", x: 2.4, y: 3.0, width: 0.15, layer: "top" },
      { route_type: "via", x: 2.4, y: 3.0, from_layer: "top", to_layer: "inner2", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 2.4, y: 3.0, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 1.9, y: 4.2, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 1.9, y: 8.0, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: -0.69, y: 8.0, width: 0.15, layer: "inner2" },
      { route_type: "via", x: -0.69, y: 8.0, from_layer: "inner2", to_layer: "bottom", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: -0.69, y: 8.0, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: -0.69, y: 8.6, width: 0.15, layer: "bottom" },
    ])
  }
  if (traceIdentity.includes("ROUTE_29") || touches(1.31, 8.6)) {
    return replaceAutoroutedRoute(trace, [
      { route_type: "wire", x: -0.75, y: 3.876, width: 0.15, layer: "top" },
      { route_type: "wire", x: -0.75, y: 3.1, width: 0.15, layer: "top" },
      { route_type: "via", x: -0.75, y: 3.1, from_layer: "top", to_layer: "inner2", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: -0.75, y: 3.1, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: -0.75, y: 7.4, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 1.31, y: 7.4, width: 0.15, layer: "inner2" },
      { route_type: "via", x: 1.31, y: 7.4, from_layer: "inner2", to_layer: "bottom", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 1.31, y: 7.4, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 1.31, y: 8.6, width: 0.15, layer: "bottom" },
    ])
  }
  if (traceIdentity.includes("ROUTE_34") || traceIdentity.includes("source_trace_34") || touches(2.15, 6.1491)) {
    return replaceAutoroutedRoute(trace, [
      { route_type: "wire", x: 2.15, y: 6.1491, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 3.6, y: 6.0, width: 0.15, layer: "bottom" },
      { route_type: "via", x: 3.6, y: 6.0, from_layer: "bottom", to_layer: "inner2", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 3.6, y: 6.0, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 6.8, y: 6.0, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 9.0, y: 3.8, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 9.0, y: -2.3, width: 0.15, layer: "inner2" },
      { route_type: "via", x: 9.0, y: -2.3, from_layer: "inner2", to_layer: "bottom", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 9.0, y: -2.3, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 6.2, y: -2.3, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 5.7, y: -2.0, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 5.7, y: -1.5, width: 0.15, layer: "bottom" },
    ])
  }
  if (traceIdentity.includes("ROUTE_36") || traceIdentity.includes("source_trace_36") || (touches(5.3, -1.5) && touches(7.6, 6.150492))) {
    return replaceAutoroutedRoute(trace, [
      { route_type: "wire", x: 5.3, y: -1.5, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 5.3, y: -1.9, width: 0.15, layer: "bottom" },
      { route_type: "via", x: 5.3, y: -1.9, from_layer: "bottom", to_layer: "inner1", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 5.3, y: -1.9, width: 0.15, layer: "inner1" },
      { route_type: "wire", x: 8.0, y: -1.9, width: 0.15, layer: "inner1" },
      { route_type: "wire", x: 8.0, y: 5.5, width: 0.15, layer: "inner1" },
      { route_type: "wire", x: 8.5, y: 5.5, width: 0.15, layer: "inner1" },
      { route_type: "via", x: 8.5, y: 5.5, from_layer: "inner1", to_layer: "top", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 8.5, y: 5.5, width: 0.15, layer: "top" },
      { route_type: "wire", x: 7.6, y: 6.150492, width: 0.15, layer: "top" },
    ])
  }
  if (traceIdentity.includes("ROUTE_43") || (touches(-1, -3) && touches(4.1, 0.4))) {
    return replaceAutoroutedRoute(trace, [
      { route_type: "wire", x: -1, y: -3, width: 0.15, layer: "top" },
      { route_type: "wire", x: -1, y: -3.2, width: 0.15, layer: "top" },
      { route_type: "via", x: -1, y: -3.2, from_layer: "top", to_layer: "inner2", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: -1, y: -3.2, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 3.5, y: -3.2, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 3.5, y: 0.7, width: 0.15, layer: "inner2" },
      { route_type: "wire", x: 3.7, y: 0.7, width: 0.15, layer: "inner2" },
      { route_type: "via", x: 3.7, y: 0.7, from_layer: "inner2", to_layer: "bottom", via_diameter: 0.45, via_hole_diameter: 0.3 },
      { route_type: "wire", x: 3.7, y: 0.7, width: 0.15, layer: "bottom" },
      { route_type: "wire", x: 4.1, y: 0.4, width: 0.15, layer: "bottom" },
    ])
  }
    return trace
  })
}

// Keep inner1 dedicated to the ground plane and let low-current signals use
// inner2. Power, sense, and motor buses remain restricted to the outer layers.
// With allowBlindAndBuriedVias=false, core expands every routed transition to
// a plated hole spanning top, inner1, inner2, and bottom.
const outerLayerDefaultAutorouter = async (simpleRouteJson: any) => {
  const guardedInput = {
    ...simpleRouteJson,
    layerCount: 4,
    allowBlindAndBuriedVias: false,
  }
  const solver = new AutoroutingPipelineSolver9_PreloadedTraceGraph(guardedInput, {
    effort: 4,
    cacheProvider: null,
  })
  const listeners: Record<string, Array<(event: any) => void>> = {
    complete: [], error: [], progress: [],
  }

  return {
    on(eventName: string, callback: (event: any) => void) {
      listeners[eventName]?.push(callback)
    },
    start() {
      setTimeout(() => {
        const originalRandom = Math.random
        const configuredSeed = (globalThis as any).process?.env?.TSCI_ROUTER_SEED
        let randomState = Number(configuredSeed ?? "2209") >>> 0
        Math.random = () => {
          randomState = (1664525 * randomState + 1013904223) >>> 0
          return randomState / 0x1_0000_0000
        }
        try {
          solver.solve()
          if (solver.failed) {
            const error = new Error(solver.error ?? "Outer-layer default autorouting failed")
            listeners.error.forEach((callback) => callback({ type: "error", error }))
            return
          }
          const traces = postprocessDenseUsbRoutes(solver.getOutputSimplifiedPcbTraces())
          listeners.complete.forEach((callback) => callback({ type: "complete", traces }))
        } catch (cause) {
          const error = cause instanceof Error ? cause : new Error(String(cause))
          listeners.error.forEach((callback) => callback({ type: "error", error }))
        } finally {
          Math.random = originalRandom
        }
      }, 0)
    },
    stop() {
      // The synchronous local solver has already completed when core calls stop.
    },
    getOutputSimpleRouteJson() {
      const output = solver.getOutputSimpleRouteJson()
      return {
        ...output,
        traces: (output.traces ?? []).map((trace: any) => {
          const pcbTraceId = String(trace.pcb_trace_id ?? "")
          const isBootSupplyTree = pcbTraceId.startsWith("source_trace_14__source_trace_15__source_trace_16")
          const isSenseNeck = pcbTraceId === "source_trace_55_0"
          return {
            ...trace,
            route: (trace.route ?? []).map((point: any) => {
              if (
                isBootSupplyTree &&
                Math.abs((point.x ?? Infinity) - 8.03) < 0.01 &&
                Math.abs((point.y ?? Infinity) - 5.434) < 0.01
              ) {
                return { ...point, y: 5.3 }
              }
              if (point.route_type !== "wire") return point
              if (isSenseNeck) return { ...point, width: Math.max(point.width ?? 0.15, 0.28) }
              return point
            }),
          }
        }),
      }
    },
  }
}

export default function Nema8FourLayerController() {
  return (
    <board
      width="20mm"
      height="20mm"
      layers={4}
      thickness="1.6mm"
      fabricatorPreset="jlcpcb_standard_20260912"
      autorouterEffortLevel="2x"
      minTraceWidth="0.15mm"
      minTraceToPadEdgeClearance="0.1mm"
      minTraceToHoleEdgeClearance="0.2mm"
      minViaEdgeToPadEdgeClearance="0.1mm"
      minViaHoleEdgeToViaHoleEdgeClearance="0.2mm"
      minPlatedHoleDrillEdgeToDrillEdgeClearance="0.3mm"
      minPadEdgeToPadEdgeClearance="0.1mm"
      minBoardEdgeClearance="0.2mm"
      minViaHoleDiameter="0.3mm"
      minViaPadDiameter="0.45mm"
      allowBlindAndBuriedVias={false}
      isViaInPadAllowed
      routeRemaining={false}
      autorouterVersion="latest"
      autorouter={{
        algorithmFn: outerLayerDefaultAutorouter,
        serverCacheEnabled: false,
        allowViaInPad: false,
        traceClearance: "0.1mm",
      }}
      pcbStyle={{ viaHoleDiameter: "0.3mm", viaPadDiameter: "0.45mm" }}
    >
      <schematicsheet name={sheets.power} displayName="1. USB-C PD and power" sheetSize="A4" sheetIndex={1}>
        <schematicsection name={sections.pdInput} displayName="USB-C PD input and motor supply" />
        <schematicsection name={sections.logicPower} displayName="3.3 V logic power" />
        <schematictext schX={-13} schY={8.5} anchor="top_left" fontSize={0.22}
          text="PWR / PD — CH32X035 negotiates the motor voltage on the dedicated USB-C input." />
        <schematictext schX={-13} schY={8} anchor="top_left" fontSize={0.19}
          text="F1 protects the input; D_BLOCK limits reverse current; D_VM_TVS clamps VM transients." />
        <schematictext schX={1} schY={8.5} anchor="top_left" fontSize={0.22}
          text="LOGIC POWER — diode-ORed VM or DATA USB 5 V is regulated to 3.3 V." />
      </schematicsheet>

      <schematicsheet name={sheets.control} displayName="2. USB programming and controller" sheetSize="A4" sheetIndex={2}>
        <schematicsection name={sections.usbData} displayName="USB-C data/programming" />
        <schematicsection name={sections.controller} displayName="CH32X035 controller" />
        <schematictext schX={-13} schY={8.5} anchor="top_left" fontSize={0.22}
          text="DATA / PROG — USB 2.0 programming/data and optional 5 V logic power." />
        <schematictext schX={-13} schY={8} anchor="top_left" fontSize={0.19}
          text="Hold BOOT while connecting DATA / PROG to enter the ROM USB bootloader." />
        <schematictext schX={1} schY={8.5} anchor="top_left" fontSize={0.22}
          text="U_MCU negotiates PD and controls STEP, DIR, ENN, UART, and STDBY." />
      </schematicsheet>

      <schematicsheet name={sheets.driver} displayName="3. TMC2209 motor stage" sheetSize="A4" sheetIndex={3}>
        <schematicsection name={sections.driverCore} displayName="TMC2209 driver and current regulation" />
        <schematictext schX={-13} schY={8.5} anchor="top_left" fontSize={0.22}
          text="U_DRV — top-side TMC2209 with a plated-through thermal-via field." />
        <schematictext schX={-13} schY={8} anchor="top_left" fontSize={0.19}
          text="UART changes run/hold current; the VREF network provides a hardware current ceiling." />
        <schematictext schX={1} schY={8.5} anchor="top_left" fontSize={0.22}
          text="MOTOR — 8HS15-0604S; edge-facing JST order A-, A+, B+, B-." />
      </schematicsheet>

      {nets.map((name) => (
        <Fragment key={name}>
          <net
            name={name}
            nominalTraceWidth={traceWidthForNet(name)}
            isGroundNet={name === "GND"}
            routingPhaseIndex={name === "GND" ? null : undefined}
          />
        </Fragment>
      ))}

      <copperpour name="GND_PLANE" layer="inner1" connectsTo="net.GND"
        padMargin="0.3mm" traceMargin="0.3mm" boardEdgeMargin="0.25mm" useThermalReliefs />

      {routedConnections.map(([from, to], index) => index === 40 || index === 48 || index >= 63 ? null : (
        <Fragment key={`route-${index}`}>
          <trace name={`ROUTE_${index}`} from={from} to={to}
            thickness={traceWidthForRouteIndex(index)}
            pcbPath={manualRouteIndexes.has(index) ? manualPcbPathForRouteIndex(index) : undefined}
            routingPhaseIndex={routePhaseForIndex(index)} />
        </Fragment>
      ))}

      <bus name="PD_INPUT_BUS" connections={routeNames(0, 2)} routingPhaseIndex={1}
        pcbTraceWidth="0.5mm" pcbAllowedLayers={["top", "bottom"]} />
      <bus name="VM_POWER_BUS" connections={routeNames(3, 11)} routingPhaseIndex={1}
        pcbTraceWidth="0.4mm" pcbAllowedLayers={["top", "bottom"]} />
      <bus name="LOGIC_POWER_POLICY" connections={routeNames(12, 25)} routingPhaseIndex={1}
        pcbAllowedLayers={["top", "inner2", "bottom"]} />
      <bus name="PD_CC_SIGNAL_POLICY" connections={routeNames(26, 27)} routingPhaseIndex={1}
        pcbAllowedLayers={["top", "inner2", "bottom"]} />
      <bus name="PD_RD_SIGNAL_POLICY" connections={["PD_CC1_RD", "PD_CC2_RD"]} routingPhaseIndex={1}
        pcbAllowedLayers={["top", "inner2", "bottom"]} />
      <bus name="USB_SIGNAL_POLICY" connections={routeNames(28, 39)} routingPhaseIndex={1}
        pcbAllowedLayers={["top", "inner2", "bottom"]} />
      <bus name="STEP_SIGNAL_POLICY" connections={["ROUTE_41"]} routingPhaseIndex={1}
        pcbAllowedLayers={["top", "inner2", "bottom"]} />
      {routeNames(42, 47).map((routeName, offset) => (
        <Fragment key={`control-signal-policy-${routeName}`}>
          <bus name={`CONTROL_SIGNAL_POLICY_${offset + 1}`} connections={[routeName]}
            routingPhaseIndex={1} pcbAllowedLayers={["top", "inner2", "bottom"]} />
        </Fragment>
      ))}
      {routeNames(49, 56).map((routeName, offset) => (
        <Fragment key={`driver-local-policy-${routeName}`}>
          <bus name={`DRIVER_LOCAL_POLICY_${offset + 1}`} connections={[routeName]}
            routingPhaseIndex={1} pcbAllowedLayers={["top", "inner2", "bottom"]} />
        </Fragment>
      ))}
      <bus name="SENSE_BUS" connections={routeNames(57, 58)} routingPhaseIndex={1}
        pcbTraceWidth="0.3mm" pcbAllowedLayers={["top", "bottom"]} />
      <bus name="MOTOR_BUS" connections={routeNames(59, 62)} routingPhaseIndex={1}
        pcbTraceWidth="0.3mm" pcbAllowedLayers={["top", "bottom"]} preferredLayer="top" />
      <autoroutingphase name="GLOBAL_DEFAULT_ROUTING" phaseIndex={1}
        connections={[
          ...routeNames(0, 39),
          ...routeNames(41, 47),
          ...routeNames(49, 62),
          "PD_CC1_RD",
          "PD_CC2_RD",
        ].filter((routeName) => !manualRouteIndexes.has(Number(routeName.slice(6))))} />

      <TYPE_C_6P_LTH5_5_108
        name="J_USB_PD"
        layer="top"
        pcbX={0}
        pcbY={-6.9}
        pcbRotation={0}
        schSectionName={sections.pdInput}
        schSheetName={sheets.power}
        schX={-11}
        schY={3}
        connections={{ EP1: "net.GND", EP2: "net.GND", GND1: "net.GND", GND2: "net.GND" }}
      />

      <TYPE_C_31_M_12
        name="J_USB_DATA"
        layer="top"
        pcbX={0}
        pcbY={6.05}
        pcbRotation={180}
        schSectionName={sections.usbData}
        schSheetName={sheets.control}
        schX={-11}
        schY={3}
        noConnect={["SBU1", "SBU2"]}
        connections={{ EH1: "net.GND", EH2: "net.GND", EH3: "net.GND", EH4: "net.GND", GND1: "net.GND", GND2: "net.GND" }}
      />

      <BM04B_SRSS_TB_LF__SN_
        name="J_MOTOR"
        layer="top"
        pcbX={-7.6}
        pcbY={0}
        pcbRotation={270}
        schSectionName={sections.driverCore}
        schSheetName={sheets.driver}
        schX={10}
        schY={0}
        noConnect={["pin5"]}
        pcbPinLabels={{ pin1: "A-", pin2: "A+", pin3: "B+", pin4: "B-" }}
      />

      <TMC2209_LA_T
        name="U_DRV"
        layer="top"
        pcbX={driverX}
        pcbY={driverY}
        pcbRotation={0}
        schSectionName={sections.driverCore}
        schSheetName={sheets.driver}
        schX={0}
        schY={1}
        schWidth={3.5}
        schHeight={5}
        noConnect={["INDEX", "DIAG"]}
      />

      {thermalViaOffsets.map(([x, y]) => (
        <Fragment key={`thermal-${x}-${y}`}>
          <via
            name={`U_DRV_THERMAL_${x}_${y}`}
            pcbX={driverX + x}
            pcbY={driverY + y}
            fromLayer="top"
            toLayer="bottom"
            holeDiameter="0.3mm"
            outerDiameter="0.45mm"
            connectsTo="net.GND"
            tented="bottom_tented"
          />
        </Fragment>
      ))}

      <CH32X035F8U6
        name="U_MCU"
        layer="bottom"
        pcbX={mcuX}
        pcbY={mcuY}
        pcbRotation={180}
        schSectionName={sections.controller}
        schSheetName={sheets.control}
        schX={4.5}
        schY={2}
        schWidth={4}
        schHeight={5}
        noConnect={["PA5", "PA6", "PB0", "PB1", "PB3", "PB11", "PB12", "DIO", "DCK"]}
      />
      <R name="R_PD_CC1" resistance="5.1k" layer="bottom" pcbX={-3.5} pcbY={-9.2} pcbRotation={0}
        schSectionName={sections.pdInput} schSheetName={sheets.power} schX={-9} schY={-1}
        connections={{ pin1: "net.PD_CC1", pin2: "net.GND" }} />
      <R name="R_PD_CC2" resistance="5.1k" layer="bottom" pcbX={3.5} pcbY={-9.2} pcbRotation={180}
        schSectionName={sections.pdInput} schSheetName={sheets.power} schX={-6} schY={-1}
        connections={{ pin1: "net.PD_CC2", pin2: "net.GND" }} />
      <trace name="PD_CC1_RD" from=".J_USB_PD > .CC1" to=".R_PD_CC1 > .pin1"
        thickness="0.15mm" routingPhaseIndex={1} />
      <trace name="PD_CC2_RD" from=".J_USB_PD > .CC2" to=".R_PD_CC2 > .pin1"
        thickness="0.15mm" routingPhaseIndex={1} />
      <R name="R_DATA_CC1" resistance="5.1k" layer="bottom" pcbX={-1.2} pcbY={8.6} pcbRotation={0}
        schSectionName={sections.usbData} schSheetName={sheets.control} schX={-10} schY={-2}
        connections={{ pin1: "net.DATA_CC1", pin2: "net.GND" }} />
      <R name="R_DATA_CC2" resistance="5.1k" layer="bottom" pcbX={0.8} pcbY={8.6} pcbRotation={0}
        schSectionName={sections.usbData} schSheetName={sheets.control} schX={-7} schY={-2}
        connections={{ pin1: "net.DATA_CC2", pin2: "net.GND" }} />
      <USBLC6_2SC6 name="U_USB_ESD" layer="bottom" pcbX={1.2} pcbY={5.0} pcbRotation={90}
        schSectionName={sections.usbData} schSheetName={sheets.control} schX={-5} schY={3} />

      <BAT54KFILM name="D_LOGIC_PD" layer="bottom" pcbX={4.8} pcbY={-5.6} pcbRotation={0}
        schSectionName={sections.logicPower} schSheetName={sheets.power} schX={-4} schY={-3} />
      <BAT54WS name="D_LOGIC_USB" layer="bottom" pcbX={-7.5} pcbY={4.5} pcbRotation={90}
        schSectionName={sections.logicPower} schSheetName={sheets.power} schX={0} schY={-3} />
      <HT7533_1 name="U_3V3" layer="bottom" pcbX={7.4} pcbY={7.6} pcbRotation={0}
        schSectionName={sections.logicPower} schSheetName={sheets.power} schX={5} schY={-3}
        schWidth={3} schHeight={3}
        schPinArrangement={{
          leftSide: { pins: [3], direction: "top-to-bottom" },
          rightSide: { pins: [2], direction: "top-to-bottom" },
          bottomSide: { pins: [1], direction: "left-to-right" },
        }}
      />
      <C name="C_LDO_IN" value="2.2uF" layer="bottom" pcbX={9.0} pcbY={3.8} pcbRotation={90}
        schSectionName={sections.logicPower} schSheetName={sheets.power} schX={3} schY={-5.5}
        connections={{ pin1: "net.LOGIC_IN", pin2: "net.GND" }} />
      <C name="C_LDO_OUT" value="2.2uF_10V" layer="bottom" pcbX={3.4} pcbY={7.1} pcbRotation={0}
        schSectionName={sections.logicPower} schSheetName={sheets.power} schX={8} schY={-5.5}
        connections={{ pin1: "net.VIO", pin2: "net.GND" }} />

      <C name="C_MCU_HF" value="100nF" layer="bottom" pcbX={4.0} pcbY={-3.6} pcbRotation={180}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={10} schY={4.5}
        connections={{ pin1: "net.VIO", pin2: "net.GND" }} />
      <C name="C_MCU_BULK" value="2.2uF_10V" layer="bottom" pcbX={6.6} pcbY={-3.2} pcbRotation={180}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={10} schY={2.5}
        connections={{ pin1: "net.VIO", pin2: "net.GND" }} />
      <R name="R_VBUS_TOP" resistance="270k" layer="top" pcbX={8.4} pcbY={-2.0} pcbRotation={0}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={9} schY={-1}
        connections={{ pin1: "net.VM", pin2: "net.VBUS_ADC" }} />
      <R name="R_VBUS_BOTTOM" resistance="47k" layer="top" pcbX={8.4} pcbY={-4.2} pcbRotation={0}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={12} schY={-1}
        connections={{ pin1: "net.VBUS_ADC", pin2: "net.GND" }} />
      <R name="R_BOOT" resistance="4.7k" layer="bottom" pcbX={6.5} pcbY={5.2} pcbRotation={0}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={7} schY={-4}
        connections={{ pin1: "net.VIO", pin2: "net.BOOT_BIAS" }} />
      <TL3780AF100QG name="SW_BOOT" layer="top" pcbX={7.6} pcbY={4.5} pcbRotation={90}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={11} schY={-4} />
      <R name="R_EN_PU" resistance="100k" layer="top" pcbX={-4.2} pcbY={-3.0} pcbRotation={0}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={-1} schY={-4}
        connections={{ pin1: "net.VIO", pin2: "net.ENN" }} />
      <R name="R_STDBY_PD" resistance="100k" layer="top" pcbX={-4.2} pcbY={2.2} pcbRotation={0}
        schSectionName={sections.controller} schSheetName={sheets.control} schX={1.5} schY={-4}
        connections={{ pin1: "net.STDBY", pin2: "net.GND" }} />
      <BSMD1206_110_16V name="F1" layer="top" pcbX={-7.5} pcbY={-8.0} pcbRotation={180}
        schSectionName={sections.pdInput} schSheetName={sheets.power} schX={-6} schY={4} />
      <PMEG6020ELRX name="D_BLOCK" layer="bottom" pcbX={0} pcbY={-8.6} pcbRotation={0}
        schSectionName={sections.pdInput} schSheetName={sheets.power} schX={-2} schY={4} />
      <diode name="D_VM_TVS" layer="bottom" pcbX={-0.7} pcbY={-5.5} pcbRotation={0}
        manufacturerPartNumber="SMAJ16A" supplierPartNumbers={{ jlcpcb: ["C20419815"] }}
        footprint="smdpads2_p3.6mm_pw2mm_ph2.1mm"
        schSectionName={sections.pdInput} schSheetName={sheets.power} schX={1} schY={1} schRotation={90} />
      {[{ x: -8.2, y: -6.8 }, { x: -8.2, y: -3.2 }].map(({ x, y }, index) => (
        <C key={`bulk-${index}`} name={`C_VM_BULK${index + 1}`} value="10uF_25V"
          layer="bottom" pcbX={x} pcbY={y} pcbRotation={90}
          schSectionName={sections.pdInput} schSheetName={sheets.power}
          schX={4 + index * 3} schY={1}
          connections={{ pin1: "net.VM", pin2: "net.GND" }} />
      ))}
      <C name="C_VM_HF1" value="100nF_50V" layer="top" pcbX={-3.8} pcbY={-4.5} pcbRotation={180}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={-10} schY={4}
        connections={{ pin1: "net.VM", pin2: "net.GND" }} />

      <C name="C_CP" value="22nF_50V" layer="top" pcbX={0.25} pcbY={-4.3} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={-6} schY={4}
        connections={{ pin1: "net.CP_HI", pin2: "net.CP_LO" }} />
      <capacitor name="C_VCP" capacitance="100nF" footprint="0402" maxVoltageRating="50V"
        supplierPartNumbers={{ jlcpcb: ["C525226"] }} layer="top" pcbX={2.7} pcbY={-4.3} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={-6} schY={2} />
      <C name="C_5V" value="2.2uF_10V" layer="top" pcbX={5.2} pcbY={-3.4} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={-6} schY={0}
        connections={{ pin1: "net.V5_DRV", pin2: "net.GND" }} />
      <C name="C_VIO" value="100nF" layer="top" pcbX={5.4} pcbY={1.8} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={-6} schY={-2}
        connections={{ pin1: "net.VIO", pin2: "net.GND" }} />
      <PT1206FR_7W0R33L name="R_SENSE_A" layer="bottom" pcbX={-4.5} pcbY={0.5} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={4} schY={-3} />
      <PT1206FR_7W0R33L name="R_SENSE_B" layer="bottom" pcbX={-4.8} pcbY={-1.8} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={7} schY={-3} />
      <R name="R_VREF_TOP" resistance="12k" layer="bottom" pcbX={1.8} pcbY={-2.3} pcbRotation={90}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={4} schY={4}
        connections={{ pin1: "net.V5_DRV", pin2: "net.VREF" }} />
      <R name="R_VREF_BOTTOM" resistance="10k" layer="bottom" pcbX={1.8} pcbY={0} pcbRotation={90}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={7} schY={4}
        connections={{ pin1: "net.VREF", pin2: "net.GND" }} />
      <C name="C_VREF" value="100nF" layer="bottom" pcbX={0.2} pcbY={-2.7} pcbRotation={0}
        schSectionName={sections.driverCore} schSheetName={sheets.driver} schX={10} schY={4}
        connections={{ pin1: "net.VREF", pin2: "net.GND" }} />

      {connectorShellGrounds.map(({ from, x, y }, index) => (
        <Fragment key={`connector-shell-ground-${index}`}>
          <trace name={`CONNECTOR_SHELL_GND_${index + 1}`} from={from} to="net.GND" thickness="0.2mm"
            pcbPath={[{ x, y }, { x, y, via: true, fromLayer: "top", toLayer: "bottom" }]}
            routingPhaseIndex={null} />
        </Fragment>
      ))}

      {groundFanouts.map(({ from, x, y, fromLayer }, index) => (
        <Fragment key={`ground-fanout-${index}`}>
          <trace name={`GROUND_FANOUT_${index + 1}`} from={from} to="net.GND"
            thickness={from.includes("R_DATA_CC") ? "0.15mm" : "0.2mm"}
            pcbPath={[
              { x, y },
              {
                x, y, via: true,
                fromLayer,
                toLayer: fromLayer === "top" ? "bottom" : "top",
              },
            ]}
            routingPhaseIndex={null} />
        </Fragment>
      ))}

      <trace name="USB_ESD_GND_FANOUT" from=".U_USB_ESD > .GND" to="net.GND" thickness="0.2mm"
        pcbPathRelativeTo=".U_USB_ESD > .GND"
        pcbPath={[{ x: 0, y: 0, via: true, fromLayer: "bottom", toLayer: "top" }]}
        routingPhaseIndex={null} />

      <trace name="C_VREF_GND_FANOUT" from=".C_VREF > .pin2" to="net.GND" thickness="0.2mm"
        pcbPath={[
          { x: -0.51, y: -1.2 },
          { x: 0.9, y: -2.8 },
          { x: 0.9, y: -2.8, via: true, fromLayer: "bottom", toLayer: "top" },
        ]}
        routingPhaseIndex={null} />

      <trace name="C_5V_GND_FANOUT" from=".C_5V > .pin2" to="net.GND" thickness="0.2mm"
        pcbPath={[
          { x: 1.1, y: -0.9 },
          { x: 1.1, y: -0.9, via: true, fromLayer: "top", toLayer: "bottom" },
        ]}
        routingPhaseIndex={null} />

      {usbGroundVias.map(({ from, x, y }, index) => (
        <Fragment key={`usb-ground-via-${index}`}>
          <trace name={`USB_GND_VIA_${index + 1}`} from={from} to="net.GND" thickness="0.15mm"
            pcbPath={[
              { x, y },
              { x, y, via: true, fromLayer: "top", toLayer: "bottom" },
            ]}
            routingPhaseIndex={null} />
        </Fragment>
      ))}

      {driverEpGroundPaths.map(({ from, path }, index) => (
        <Fragment key={`driver-ground-via-${index}`}>
          <trace name={`U_DRV_GND_VIA_${index + 1}`} from={from} to="net.GND" thickness="0.15mm"
            pcbPath={[...path]}
            routingPhaseIndex={null} />
        </Fragment>
      ))}

      <trace name="U_DRV_EP_GND" from=".U_DRV > .EP" to="net.GND" thickness="0.15mm"
        pcbPathRelativeTo=".U_DRV > .EP"
        pcbPath={[{ x: 0, y: 0, via: true, fromLayer: "top", toLayer: "bottom" }]}
        routingPhaseIndex={null} />
      <trace name="U_MCU_EP_GND" from=".U_MCU > .GND" to="net.GND" thickness="0.15mm"
        pcbPathRelativeTo=".U_MCU > .GND"
        pcbPath={[{ x: 0, y: 0, via: true, fromLayer: "bottom", toLayer: "top" }]}
        routingPhaseIndex={null} />

      <hole name="MOTOR_M2_UPPER_LEFT" pcbX={-7.7} pcbY={7.7} diameter="2.2mm" />
      <hole name="MOTOR_M2_LOWER_RIGHT" pcbX={7.7} pcbY={-7.7} diameter="2.2mm" />

      <silkscreentext text="PWR" layer="top" pcbX={-5.7} pcbY={-7.0} pcbRotation={90} fontSize="0.7mm" />
      <silkscreentext text="PD IN" layer="top" pcbX={-6.5} pcbY={-7.0} pcbRotation={90} fontSize="0.5mm" />
      <silkscreentext text="DATA" layer="top" pcbX={5.7} pcbY={6.2} pcbRotation={270} fontSize="0.7mm" />
      <silkscreentext text="PROG" layer="top" pcbX={6.5} pcbY={6.2} pcbRotation={270} fontSize="0.5mm" />
      <silkscreentext text="MOTOR" layer="top" pcbX={-8.8} pcbY={4.0} pcbRotation={270} fontSize="0.5mm" />
      <silkscreentext text="A- A+ B+ B-" layer="top" pcbX={-5.8} pcbY={0} pcbRotation={270} fontSize="0.4mm" />
      <silkscreentext text="BOOT" layer="top" pcbX={7.6} pcbY={6.4} fontSize="0.45mm" />
      <silkscreentext text="NEMA8 20x20 4L" layer="bottom" pcbX={0} pcbY={-8.8} pcbRotation={180} fontSize="0.5mm" />
      <silkscreentext text="0.60A MAX" layer="bottom" pcbX={0} pcbY={8.8} fontSize="0.5mm" />
    </board>
  )
}