shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

Compact four-layer NEMA 17 carrier PCB combining an F1C100S Linux SoC, USB-C PD power and buck regulation, W5500 10/100 Ethernet, STM32 safety/motion control, and DRV8825 stepper-driver hardware with protection, sensing, connectors, and dual-sided SMT assembly.

Version
0.4.15
License
unset
Stars
0

pd-power.tsx

import { Fragment } from "react"
import { TYPE_C_31_M_12 } from "./imports/TYPE_C_31_M_12"
import { HUSB238A_BB001_QN16R } from "./imports/HUSB238A_BB001_QN16R"
import { TPS54302DDCR } from "./imports/TPS54302DDCR"
import { FHD4020S_100MT } from "./imports/FHD4020S_100MT"

const wire = (name: string, from: string, to: string, thickness = 0.15) =>
  <trace name={name} from={from} to={to} thickness={thickness} />

const pdSchRotation: Record<string, number> = {
  R_BUCK_BOTTOM: -90,
  C_BUCK_IN_HF: -90,
  C_BUCK_BOOT: -90,
}

const pdSchPosition: Record<string, { x: number; y: number }> = {
  R_BUCK_BOTTOM: { x: -19.12, y: 8.67 },
  R_BUCK_FF: { x: -19.62, y: 7.42 },
}

const r0402 = (name: string, value: string, lcsc: string, x: number, y: number) =>
  <resistor name={name} layer="top" resistance={value} footprint="0402"
    supplierPartNumbers={{jlcpcb:[lcsc]}} pcbX={x} pcbY={y}
    schX={pdSchPosition[name]?.x ?? x} schY={pdSchPosition[name]?.y ?? y}
    schRotation={pdSchRotation[name]} />

const c0402 = (name: string, value: string, lcsc: string, x: number, y: number, voltage = 50,
  maxDecouplingTraceLength?: number, schX = x, schY = y) =>
  <capacitor name={name} layer="top" capacitance={value} footprint="0402" maxVoltageRating={voltage}
    maxDecouplingTraceLength={maxDecouplingTraceLength}
    supplierPartNumbers={{jlcpcb:[lcsc]}} pcbX={x} pcbY={y} schX={schX} schY={schY}
    schRotation={pdSchRotation[name]} />

/**
 * J_USB_PWR is a dedicated USB-PD power input. USB2 is deliberately isolated
 * from this receptacle so a charger cable cannot be mistaken for the Linux
 * programming connection. HUSB238A GPIO mode uses 11 kOhm VSET and 21 kOhm
 * ISET for a 15 V / 3 A fixed-PDO request.
 *
 * J_USB_DATA stays in the original, signal-integrity-checked USB position. The
 * new J_USB_PWR is rendered after the rest of the board by UsbPowerPort below.
 * DATA VBUS is intentionally unconnected: the PD port powers the board while
 * the data port is attached to a host, so the two sources cannot backfeed.
 */
export function PdPower() {
  return <group name="PD_POWER" pcbX={0} pcbY={0} schX={13} schY={-21.5} schSheetName="pd_power">
    <TYPE_C_31_M_12 name="J_USB_DATA" layer="top" pcbX={-6} pcbY={17.25} pcbRotation={180}
      schX={0} schY={24}
      noConnect={["EH1","EH3","EH4","SBU1","SBU2","VBUS1","VBUS2"]} />

    {/* Shell and receptacle grounds. */}
    {wire("USB_GND_14", ".J_USB_DATA > .pin14", "net.BOARD_GND", 0.3)}
    {wire("USB_GND_1", ".J_USB_DATA > .pin1", "net.BOARD_GND", 0.3)}
    <trace name="USB_GND_BRIDGE" from=".J_USB_DATA > .pin1" to=".J_USB_DATA > .pin13" thickness={0.3}
      pcbPath={[".J_USB_DATA > .pin1",{x:5.2,y:-0.4},{x:-5,y:-0.4},{x:-5,y:3},".J_USB_DATA > .pin13"]} />
    {/* Both receptacle VBUS contacts and all switch-source contacts share one
        explicit raw-VBUS tree; this avoids ambiguous chained junctions. */}
    {wire("USB_VBUS_A", ".J_USB_PWR > .pin15", ".J_USB_PWR > .pin16", 0.8)}
    {wire("USB_VBUS_B", ".J_USB_PWR > .pin16", ".Q_VBUS > .pin1", 0.8)}
    {wire("USB_DM_A", ".J_USB_DATA > .pin7", "net.USB_N_PORT")}
    <trace name="USB_DM_JOIN" from=".J_USB_DATA > .pin7" to=".J_USB_DATA > .pin9" thickness={0.15}
      pcbPath={[".J_USB_DATA > .pin7",
        {x:-0.75,y:3}, {x:-0.75,y:3,via:true,fromLayer:"top",toLayer:"inner1"}, {x:-0.75,y:3},
        {x:0.25,y:3}, {x:0.25,y:3,via:true,fromLayer:"inner1",toLayer:"top"}, {x:0.25,y:3},
        ".J_USB_DATA > .pin9"]} />
    {wire("USB_DP_A", ".J_USB_DATA > .pin8", "net.USB_P_PORT")}
    <trace name="USB_DP_JOIN" from=".J_USB_DATA > .pin8" to=".J_USB_DATA > .pin10" thickness={0.15}
      pcbPath={[".J_USB_DATA > .pin8",
        {x:-0.25,y:3.6}, {x:-0.25,y:3.6,via:true,fromLayer:"top",toLayer:"inner2"}, {x:-0.25,y:3.6},
        {x:0.75,y:3.6}, {x:0.75,y:3.6,via:true,fromLayer:"inner2",toLayer:"top"}, {x:0.75,y:3.6},
        ".J_USB_DATA > .pin10"]} />

    <HUSB238A_BB001_QN16R name="U_PD" layer="bottom" pcbX={-5.5} pcbY={24} pcbRotation={90}
      schX={-8} schY={24} schHeight={1.8}
      noConnect={["D_POS","D_NEG","EN_HVDCP_OUT1","ADDR_ORIENT","INT_N","FAULT_OUT2","FLGIN"]} />
    <capacitor name="C_PD_VDD" layer="bottom" capacitance="1uF" footprint="0402" maxVoltageRating={25}
      manufacturerPartNumber="CL05A105KA5NQNC" supplierPartNumbers={{jlcpcb:["C52923"]}}
      pcbX={14.3} pcbY={15.2} pcbRotation={270}
      schX={-12} schY={23} schRotation={-90} maxDecouplingTraceLength={15} />
    <resistor name="R_PD_VSET" layer="bottom" resistance="11k" footprint="0402"
      supplierPartNumbers={{jlcpcb:["C25749"]}} pcbX={13.9} pcbY={17.0} pcbRotation={0}
      schX={-2.5} schY={18.5} schRotation={-90} />
    <resistor name="R_PD_ISET" layer="bottom" resistance="21k" footprint="0402"
      supplierPartNumbers={{jlcpcb:["C25766"]}} pcbX={16.4} pcbY={12.55} pcbRotation={0}
      schX={-1} schY={20.5} schRotation={-90} />
    <resistor name="R_PD_DEBUG" layer="bottom" resistance="910k" footprint="0402"
      supplierPartNumbers={{jlcpcb:["C25800"]}} pcbX={17.93} pcbY={11.5} pcbRotation={90}
      schX={-13} schY={28.5} schRotation={-90} />
    <resistor name="R_PD_GOOD_PU" layer="bottom" resistance="49.9k" footprint="0402"
      supplierPartNumbers={{jlcpcb:["C25794"]}} pcbX={18.2} pcbY={18} pcbRotation={180}
      schX={-5.5} schY={27.5} schRotation={180} />
    {wire("PD_CC1", ".J_USB_PWR > .pin6", ".U_PD > .CC1")}
    {wire("PD_CC2", ".J_USB_PWR > .pin12", ".U_PD > .CC2")}
    {wire("PD_VDD", ".U_PD > .VDD", ".R_V3V3_RIGHT > .pin2")}
    <trace name="PD_VDD_CAP" from=".C_PD_VDD > .pin1" to=".U_PD > .VDD" thickness={0.15}
      pcbPath={[".C_PD_VDD > .pin1", {x:-0.51,y:0.9}, {x:1.6,y:0.9}, ".U_PD > .VDD"]} />
    {wire("PD_VDD_CAP_GND", ".C_PD_VDD > .pin2", "net.BOARD_GND", 0.3)}
    <trace name="PD_VSET_15V" from=".U_PD > .SNK_VSET" to=".R_PD_VSET > .pin1"
      thickness={0.15} pcbStraightLine />
    {wire("PD_VSET_GND", ".R_PD_VSET > .pin2", "net.BOARD_GND")}
    <trace name="PD_ISET_3A" from=".U_PD > .SNK_ISET" to=".R_PD_ISET > .pin1"
      thickness={0.15} pcbStraightLine />
    {wire("PD_ISET_GND", ".R_PD_ISET > .pin2", "net.BOARD_GND")}
    <trace name="PD_DEBUG_BIAS" from=".U_PD > .DBG_N" to=".R_PD_DEBUG > .pin1" thickness={0.15}
      pcbPath={[".U_PD > .DBG_N", {x:2.3,y:-0.25}, {x:3,y:1}, {x:4.5,y:7}, ".R_PD_DEBUG > .pin1"]} />
    {wire("PD_DEBUG_BIAS_GND", ".R_PD_DEBUG > .pin2", "net.BOARD_GND")}
    {wire("PD_ENABLE", ".U_PD > .EN_N", "net.BOARD_GND")}
    {wire("PD_GROUND", ".U_PD > .GND", "net.BOARD_GND", 0.3)}
    <trace name="PD_GOOD_PULLUP" from=".U_PD > .GATE" to=".R_PD_GOOD_PU > .pin1"
      thickness={0.15} maxViaCount={0}
      pcbPath={[".U_PD > .GATE", {x:-2.4,y:-0.25}, {x:-2.4,y:5}, ".R_PD_GOOD_PU > .pin1"]} />
    {/* GATE is open drain. Pull it to the pass-FET source so loss of the PD
        controller turns the high-side switch off instead of leaving VBUS on. */}
    {wire("PD_GOOD_PULLUP_VDD", ".R_PD_GOOD_PU > .pin2", ".U_PD > .VBUS")}

    {/* TI 5 V / 3 A reference topology. The actual Linux load is well below 3 A. */}
    <TPS54302DDCR name="U_BUCK" layer="top" pcbX={-13.022} pcbY={4.8288} pcbRotation={90}
      schX={-21.75} schY={18} />
    <FHD4020S_100MT name="L_BUCK" layer="top" pcbX={-13.9418} pcbY={0.043} pcbRotation={90}
      schX={-16} schY={17} />
    <capacitor name="C_BUCK_IN" layer="top" capacitance="10uF" maxVoltageRating={25} footprint="0805"
      manufacturerPartNumber="CL21A106KAYNNNE" supplierPartNumbers={{jlcpcb:["C15850"]}}
      maxDecouplingTraceLength={15}
      pcbX={-22.5} pcbY={20} schX={-26} schY={19} schRotation={-90} />
    {c0402("C_BUCK_IN_HF", "100nF", "C307331", -9.8, 5.73, 50, 4, -24.25, 19)}
    {c0402("C_BUCK_BOOT", "100nF", "C307331", -17.5, 15.8)}
    {[[-7,20],[-18.1,0]] .map(([x,y], index) =>
      <Fragment key={index}><capacitor name={`C_BUCK_OUT${index+1}`} layer="top" capacitance="22uF"
        maxVoltageRating={25} footprint="0805" manufacturerPartNumber="CL21A226MAQNNNE"
        supplierPartNumbers={{jlcpcb:["C45783"]}} pcbX={x} pcbY={y} schX={-10} schY={18-index*2}
        schRotation={-90} /></Fragment>)}
    {r0402("R_BUCK_TOP", "100k", "C25741", -16.87, 6.17)}
    {r0402("R_BUCK_BOTTOM", "13.3k", "C122547", -19.37, 8.67)}
    {r0402("R_BUCK_FF", "51", "C881405", -19.37, 7.42)}
    <capacitor name="C_BUCK_FF" layer="top" capacitance="75pF" footprint="0402" maxVoltageRating={50}
      manufacturerPartNumber="CC0402JRNPO9BN750" supplierPartNumbers={{jlcpcb:["C107010"]}}
      pcbX={-18.87} pcbY={6.17} schX={-12} schY={14} schRotation={-90} />
    {wire("BUCK_ENABLE", ".U_BUCK > .EN", ".U_BUCK > .VIN")}
    {wire("BUCK_GND", ".U_BUCK > .GND", "net.BOARD_GND", 0.5)}
    {wire("BUCK_IN_CAP", ".Q_VBUS > .pin8", ".U_BUCK > .VIN", 0.5)}
    {wire("BUCK_IN_CAP_GND", ".C_BUCK_IN > .pin2", "net.BOARD_GND", 0.5)}
    {wire("BUCK_IN_HF", ".C_BUCK_IN_HF > .pin1", ".U_BUCK > .VIN", 0.5)}
    {wire("BUCK_IN_HF_GND", ".C_BUCK_IN_HF > .pin2", "net.BOARD_GND")}
    {wire("BUCK_SW", ".U_BUCK > .SW", ".L_BUCK > .pin1", 0.8)}
    {wire("BUCK_OUT", ".L_BUCK > .pin2", ".C_BUCK_OUT1 > .pin1", 0.8)}
    {wire("BUCK_BOOT", ".U_BUCK > .BOOT", ".C_BUCK_BOOT > .pin1")}
    {wire("BUCK_BOOT_RETURN", ".C_BUCK_BOOT > .pin2", ".U_BUCK > .SW")}
    {[1,2].map(index => <Fragment key={index}><group pcbX={0} pcbY={0} schX={0} schY={0}>
      {index === 1
        ? wire("BUCK_OUT1", ".C_BUCK_OUT1 > .pin1", ".C_BUCK_OUT2 > .pin1", 0.5)
        : wire("BUCK_OUT2", ".C_BUCK_OUT2 > .pin1", ".R_BUCK_TOP > .pin1", 0.5)}
      {wire(`BUCK_OUT${index}_GND`, `.C_BUCK_OUT${index} > .pin2`, "net.BOARD_GND", 0.5)}
    </group></Fragment>)}
    {wire("BUCK_FB_TOP", ".R_BUCK_TOP > .pin1", ".R_BUCK_FF > .pin1")}
    <trace name="BUCK_FB" from=".R_BUCK_TOP > .pin2" to=".U_BUCK > .FB" thickness={0.12} pcbStraightLine />
    <trace name="BUCK_FB_BOTTOM" from=".R_BUCK_BOTTOM > .pin1" to=".U_BUCK > .FB" thickness={0.12}
      pcbPath={[".R_BUCK_BOTTOM > .pin1", {x:-1.23,y:0}, {x:-1.23,y:-1.92},
        {x:3.87,y:-1.92}, ".U_BUCK > .FB"]} />
    {wire("BUCK_FB_GND", ".R_BUCK_BOTTOM > .pin2", "net.BOARD_GND")}
    {wire("BUCK_FF_CAP", ".R_BUCK_FF > .pin2", ".C_BUCK_FF > .pin1")}
    <trace name="BUCK_FF_RETURN" from=".C_BUCK_FF > .pin2" to=".U_BUCK > .FB" thickness={0.12}
      pcbPath={[".C_BUCK_FF > .pin2", {x:0.51,y:0.58}, {x:3.37,y:0.58}, ".U_BUCK > .FB"]} />

    <silkscreentext text="DATA / USB2 FEL" pcbX={4} pcbY={22.5} fontSize={0.75} />
  </group>
}

/** Dedicated USB-PD input plus the DATA-port Type-C Rd resistors. These are
 * rendered last to preserve the verified component and route identifiers. */
export function UsbPowerPort() {
  return <group name="USB_PORT_SPLIT" pcbX={0} pcbY={0} schX={-22} schY={-24} schSheetName="pd_power">
    <TYPE_C_31_M_12 name="J_USB_PWR" layer="top" pcbX={16.0} pcbY={17.25} pcbRotation={180}
      schX={14} schY={31}
      internallyConnectedPins={[["pin1","pin2","pin3","pin4"]]}
      noConnect={["SBU1","SBU2","DN2","DP1","DN1","DP2"]} />
    <resistor name="R_USB_DATA_CC1" layer="bottom" resistance="5.1k" footprint="0402"
      manufacturerPartNumber="0402WGF5101TCE" supplierPartNumbers={{jlcpcb:["C25905"]}}
      pcbX={-1.5} pcbY={13.5} pcbRotation={180} schX={10} schY={27} schRotation={-90} />
    <resistor name="R_USB_DATA_CC2" layer="bottom" resistance="5.1k" footprint="0402"
      manufacturerPartNumber="0402WGF5101TCE" supplierPartNumbers={{jlcpcb:["C25905"]}}
      pcbX={-11} pcbY={13.5} pcbRotation={180} schX={18} schY={27} schRotation={90} />

    <trace name="USB_DATA_CC1_RD" from=".J_USB_DATA > .CC1" to=".R_USB_DATA_CC1 > .pin1"
      thickness={0.15}
      pcbPath={[".J_USB_DATA > .CC1", {x:-1.25,y:3.1}, {x:-1.94,y:3.6}, ".R_USB_DATA_CC1 > .pin1"]} />
    <trace name="USB_DATA_CC2_RD" from=".J_USB_DATA > .CC2" to=".R_USB_DATA_CC2 > .pin2"
      thickness={0.15}
      pcbPath={[".J_USB_DATA > .CC2", {x:1.75,y:3.1}, {x:1.99,y:3.6}, ".R_USB_DATA_CC2 > .pin2"]} />
    <trace name="USB_DATA_CC1_GND" from=".R_USB_DATA_CC1 > .pin2" to="net.BOARD_GND"
      thickness={0.15} pcbStraightLine />
    <trace name="USB_DATA_CC2_GND" from=".R_USB_DATA_CC2 > .pin1" to="net.BOARD_GND"
      thickness={0.15} pcbStraightLine />
    <trace name="USB_PWR_SIGNAL_GND" from=".J_USB_PWR > .pin13" to=".J_USB_PWR > .pin14"
      thickness={0.3}
      pcbPath={[".J_USB_PWR > .pin13", {x:-3.2,y:6.3}, {x:3.2,y:6.3}, ".J_USB_PWR > .pin14"]} />
    <trace name="USB_PWR_SHELL_GND" from=".J_USB_PWR > .pin1" to=".J_USB_PWR > .pin14"
      thickness={0.3} pcbStraightLine />
    <trace name="USB_PWR_BOARD_GND" from=".J_USB_PWR > .pin14" to=".J_USB_DATA > .pin13"
      thickness={0.3} pcbStraightLine />

    <silkscreentext text="PWR / USB-PD 15V" pcbX={25} pcbY={22.5} fontSize={0.75} />
  </group>
}