Devesh36/pocket-audio-player

A portable, rechargeable microSD audio player built around an RP2040, SPI flash, USB‑C charging/power management, LCD/button controls, PCM5102A I²S DAC, and TPA6132A headphone amplifier in a 3D‑printed enclosure.

Version
1.0.12
License
unset
Stars
0

audio-player-board.tsx

import type { TraceProps } from "@tscircuit/props";
import { BM08B_GHS_TBT_LF__SN_ } from "./imports/BM08B_GHS_TBT_LF__SN_/BM08B_GHS_TBT_LF__SN_";
import { JstBattery } from "./imports/JST_PH";
import { USBLC6_2SC6 } from "./imports/USBLC6_2SC6";
import { createBoardRouter } from "./board-router";
import { Fragment } from "react";
import { HSMS_C170_FOOTPRINT } from "./imports/HSMS_C170";
import { PZ254V_11_02P_FOOTPRINT } from "./imports/PZ254V_11_02P";
import { RP2040 } from "./imports/RP2040";
import { W25Q16JVUXIQ } from "./imports/W25Q16JVUXIQ";
import { ABM8_272_T3 } from "./imports/ABM8_272_T3";
import { SKRPACE010 } from "./imports/SKRPACE010";
import { PCM5102APWR } from "./imports/PCM5102APWR";
import { TPA6132A2RTER } from "./imports/TPA6132A2RTER";
import { TPS63031DSKR } from "./imports/TPS63031DSKR";
import { MCP73831T_2ACI_OT } from "./imports/MCP73831T_2ACI_OT";
import { AO3401A } from "./imports/AO3401A";
import { SS14 } from "./imports/SS14";
import { TF_01A } from "./imports/TF_01A";
import { TYPE_C_31_M_12 } from "./imports/TYPE_C_31_M_12";
import { PJ_320A } from "./imports/PJ_320A";

// Portable microSD player. Hardware only: RP2040 firmware supplies SPI storage,
// PIO I2S audio, display/menu, digital volume and button handling.
// All electrical design, footprints and PCB routing are authored in tscircuit.
function SheetTrace({sheet,...props}: TraceProps & {sheet:string}) {
  return <group schSheetName={sheet}><trace {...props}/></group>;
}
const componentSection: Record<string,string> = { U1:"MCU", U_FLASH:"Storage", Y1:"Clock", U_DAC:"DAC", U_AMP:"Headphones", U_REG:"Power", U_CHG:"Power", Q_SHARE:"Power", D_USB:"Power", J_SD:"Storage", J_AUX:"Headphones", U_ESD:"USB", J_USB:"USB", J_BAT:"Power", J_PWR:"Power", J_LCD:"Controls", J_SWD:"MCU" };
const link = (ref: string, pin: string | number, net: string) => (
  <Fragment key={`${ref}.${pin}.${net}`}><SheetTrace from={`.${ref} > .${typeof pin === "number" ? `pin${pin}` : pin}`}
    to={`net.${net}`} schDisplayLabel={net} sheet={componentSection[ref]} /></Fragment>
);
const sections = ["USB", "Power", "MCU", "Clock", "Storage", "DAC", "Headphones", "Controls"];
// name, value, PCB x/y/rotation, section, pin1 net, pin2 net
type Passive = [string, string, number, number, number, string, string, string];
const resistors: Passive[] = [
  ["R_CC1", "5.1k", -17, 34, 90, "USB", "CC1", "GND"],
  ["R_CC2", "5.1k", -10, 34, 90, "USB", "CC2", "GND"],
  ["R_DM", "27", -1.7, 20, -90, "USB", "USB_DM", "USB_DM_MCU"],
  ["R_DP", "27", -3.5, 20, -90, "USB", "USB_DP", "USB_DP_MCU"],
  ["R_PROG", "10k", -26, 30, 0, "Power", "CHG_PROG", "GND"],
  ["R_GATE", "100k", -13, 33, 90, "Power", "VBUS", "GND"],
  ["R_EN", "100k", -18, -11, 0, "Power", "ENABLE", "GND"],
  ["R_CHG", "2.2k", -26, 34, 90, "Power", "VBUS", "CHG_LED_A"],
  ["R_BAT_TOP", "100k", -22, -22, 0, "Power", "VBAT", "BAT_SENSE"],
  ["R_BAT_BOT", "100k", -18, -22, 0, "Power", "BAT_SENSE", "GND"],
  ["R_XOUT", "1k", 0, 1.5, -90, "Clock", "XOUT", "XTAL_OUT"],
  ["R_RUN", "10k", 3, -1, 0, "MCU", "V3V3", "RUN"],
  ["R_BOOT", "1k", -10, 26, 0, "Storage", "QSPI_CS", "BOOT_SW"],
  ["R_FLASH", "10k", -7, 27, 90, "Storage", "V3V3", "QSPI_CS"],
  ["R_SD_CS", "47k", -11, 19, 90, "Storage", "V3V3", "SD_CS"],
  ["R_SD_DO", "47k", -11, 16, 90, "Storage", "V3V3", "SD_MISO"],
  ["R_SD_D1", "47k", -13, 27, 0, "Storage", "V3V3", "SD_D1"],
  ["R_SD_D2", "47k", -13, 30, 0, "Storage", "V3V3", "SD_D2"],
  ["R_SD_CD", "10k", -11, 13, 0, "Storage", "V3V3", "SD_DETECT"],
  ["R_LCD_CS", "100k", 3, 25, 90, "Controls", "V3V3", "LCD_CS"],
  ["R_LCD_RST", "100k", 6, 25, 90, "Controls", "V3V3", "LCD_RST"],
  ["R_DAC_MUTE", "100k", 10, 1, 0, "DAC", "DAC_UNMUTE", "GND"],
  ["R_AMP_EN", "100k", 15, 22, 90, "Headphones", "AMP_ENABLE", "GND"],
  ["R_DAC_L", "470", 11, 14, 90, "DAC", "DAC_L", "LINE_L"],
  ["R_DAC_R", "470", 14, 14, 90, "DAC", "DAC_R", "LINE_R"],
  ["R_ATT_L1", "10k", 10, 19, 90, "Headphones", "LINE_L", "ATT_L"],
  ["R_ATT_L2", "10k", 10, 22, 90, "Headphones", "ATT_L", "GND"],
  ["R_ATT_R1", "10k", 13, 19, 90, "Headphones", "LINE_R", "ATT_R"],
  ["R_ATT_R2", "10k", 13, 22, 90, "Headphones", "ATT_R", "GND"],
];
const caps: Passive[] = [
  ["C_ESD", "100nF", -14.5, 36, 90, "USB", "VBUS", "GND"],
  ["C_CHG_IN", "4.7uF", -23, 36, 0, "Power", "VBUS", "GND"],
  ["C_BAT", "4.7uF", -21, 30, 0, "Power", "VBAT", "GND"],
  ["C_SYS", "10uF", -22, -3, 0, "Power", "VSYS", "GND"],
  ["C_VINA", "100nF", -18, -5, 0, "Power", "VSYS", "GND"],
  ["C_REG1", "10uF", -18, -1, 0, "Power", "V3V3", "GND"],
  ["C_REG2", "10uF", -18, 2, 0, "Power", "V3V3", "GND"],
  ["C_ADC_BAT", "100nF", -14, -22, 0, "Power", "BAT_SENSE", "GND"],
  ["C_IO1", "100nF", -6.5, 16, 90, "MCU", "V3V3", "GND"],
  ["C_IO2", "100nF", 2.5, 12, 0, "MCU", "V3V3", "GND"],
  ["C_IO3", "100nF", 2.5, 8, 0, "MCU", "V3V3", "GND"],
  ["C_IO4", "100nF", 2, 4, 90, "MCU", "V3V3", "GND"],
  ["C_IO5", "100nF", -9.5, 8, 180, "MCU", "V3V3", "GND"],
  ["C_IO6", "100nF", -9.5, 11, 180, "MCU", "V3V3", "GND"],
  ["C_DVDD1", "100nF", -4.5, 15.5, 90, "MCU", "V1V1", "GND"],
  ["C_DVDD2", "100nF", -8.5, 4, 90, "MCU", "V1V1", "GND"],
  ["C_VREG_IN", "1uF", 3.5, 15.5, 90, "MCU", "V3V3", "GND"],
  ["C_VREG_OUT", "1uF", 0.5, 15.5, 90, "MCU", "V1V1", "GND"],
  ["C_USB", "100nF", 5, 19, 90, "MCU", "V3V3", "GND"],
  ["C_ADC", "100nF", 3.5, 10, 0, "MCU", "V3V3", "GND"],
  ["C_FLASH", "100nF", -4, 25, 90, "Storage", "V3V3", "GND"],
  ["C_SD", "10uF", -11, 23, 90, "Storage", "V3V3", "GND"],
  ["C_XIN", "15pF", -9, -2, 180, "Clock", "XIN", "GND"],
  ["C_XOUT", "15pF", -1, -2, 0, "Clock", "XTAL_OUT", "GND"],
  ["C_DAC_CP", "1uF", 5, 4, 0, "DAC", "DAC_CAPP", "DAC_CAPM"],
  ["C_DAC_NEG", "1uF", 17, 10, 0, "DAC", "GND", "DAC_VNEG"],
  ["C_DAC_CPVDD", "2.2uF", 6, 1, 0, "DAC", "V3V3", "GND"],
  ["C_DAC_AVDD", "2.2uF", 6, 14, 90, "DAC", "V3V3", "GND"],
  ["C_DAC_DVDD", "2.2uF", 17, 4, 0, "DAC", "V3V3", "GND"],
  ["C_DAC_LDO", "100nF", 17, 7, 0, "DAC", "DAC_LDO", "GND"],
  ["C_FILTER_L", "2.2nF", 11, 16.5, 0, "DAC", "LINE_L", "GND"],
  ["C_FILTER_R", "2.2nF", 14, 16.5, 0, "DAC", "LINE_R", "GND"],
  ["C_AMP_L", "1uF", 17, 17, 0, "Headphones", "ATT_L", "AMP_L"],
  ["C_AMP_R", "1uF", 17, 14.5, 0, "Headphones", "ATT_R", "AMP_R"],
  ["C_REF_L", "1uF", 19, 12.5, 0, "Headphones", "GND", "AMP_REF_L"],
  ["C_REF_R", "1uF", 23, 12.5, 0, "Headphones", "GND", "AMP_REF_R"],
  ["C_AMP_CP", "1uF", 23, 19, 90, "Headphones", "AMP_CPP", "AMP_CPN"],
  ["C_AMP_NEG", "1uF", 23, 16, 90, "Headphones", "GND", "AMP_NEG"],
  ["C_AMP_HPVDD", "2.2uF", 23, 22, 90, "Headphones", "AMP_HPVDD", "GND"],
  ["C_AMP_VDD", "2.2uF", 19, 25, 0, "Headphones", "V3V3", "GND"],
  ["C_LCD", "100nF", 9, 26, 0, "Controls", "V3V3", "GND"],
  ["C_LCD_BULK", "10uF", 4, 30, 0, "Controls", "V3V3", "GND"],
];
const powerPins: Record<number, string> = {
  1:"V3V3",10:"V3V3",22:"V3V3",33:"V3V3",42:"V3V3",49:"V3V3",
  43:"V3V3",44:"V3V3",48:"V3V3",23:"V1V1",50:"V1V1",45:"V1V1",19:"GND",57:"GND",
};
const mcuPins: Record<number,string> = {
  6:"SD_MISO",7:"SD_CS",8:"SD_CLK",9:"SD_MOSI",
  11:"BTN_PLAY",12:"BTN_PREV",13:"BTN_NEXT",14:"BTN_UP",15:"BTN_DOWN",
  16:"SD_DETECT",17:"DAC_UNMUTE",18:"AMP_ENABLE",20:"XIN",21:"XOUT",
  24:"SWCLK",25:"SWDIO",26:"RUN",27:"I2S_BCK",28:"I2S_LRCK",29:"I2S_DATA",
  30:"LCD_BL",31:"LCD_DC",32:"LCD_RST",37:"LCD_CS",
  38:"LCD_CLK",39:"LCD_DIN",40:"BAT_SENSE",46:"USB_DM_MCU",47:"USB_DP_MCU",51:"QSPI3",52:"QSPI_CLK",
  53:"QSPI0",54:"QSPI2",55:"QSPI1",56:"QSPI_CS",
};
const buttons: [string,string,number,number,string][] = [
  ["SW_PLAY","BTN_PLAY",0,-27,"PLAY"], ["SW_PREV","BTN_PREV",-12,-27,"PREV"],
  ["SW_NEXT","BTN_NEXT",12,-27,"NEXT"], ["SW_UP","BTN_UP",0,-15,"VOL +"],
  ["SW_DOWN","BTN_DOWN",0,-39,"VOL -"], ["SW_BOOT","BOOT_SW",-20,-32,"BOOT"],
  ["SW_RESET","RUN",20,-32,"RESET"],
];
function schematicPassive(name:string,section:string) {
  const list=[...resistors,...caps].filter(p=>p[5]===section);
  const i=list.findIndex(p=>p[0]===name);
  const index=sections.indexOf(section);
  return { schX:(index%4)*25-37+((i%5)-2)*3.5,
    schY:(section === "MCU" ? 18 : 15)-Math.floor(index/4)*30-Math.floor(i/5)*(section === "MCU" ? 3.2 : 4), schSectionName:section, schSheetName:section };
}
export default (props: { mountedTo?: string } = {}) => (
  <board width="60mm" height="90mm" layers={4} thickness="1.6mm" borderRadius="2mm"
    title="Pocket audio player / Rev B" schLayout={{layoutMode:"relative"}}
    autorouter={{local:true, algorithmFn:createBoardRouter, traceClearance:"0.15mm"}}
    {...props}
    minTraceWidth="0.12mm" minTraceToPadEdgeClearance="0.1mm"
    minViaHoleDiameter="0.2mm" minViaPadDiameter="0.35mm" minBoardEdgeClearance="0.5mm">
    <net name="VBUS" nominalTraceWidth="0.3mm" isPowerNet />
    <net name="VBAT" nominalTraceWidth="0.3mm" isPowerNet />
    <net name="VSYS" nominalTraceWidth="0.3mm" isPowerNet />
    <net name="V3V3" nominalTraceWidth="0.25mm" isPowerNet />
    <net name="V1V1" nominalTraceWidth="0.2mm" isPowerNet />
    <net name="SW_L1" nominalTraceWidth="0.25mm" />
    <net name="SW_L2" nominalTraceWidth="0.25mm" />
    <differentialpair name="USB_DATA" positiveConnection="USB_PAIR_DP" negativeConnection="USB_PAIR_DM" maxLengthSkew={0.5} />
    {/* Each circuit block has its own printable A4 schematic page. */}
    <Fragment>
      {sections.map(name=><Fragment key={name}><schematicsheet name={name} displayName={name}><schematicsection name={name} displayName={name}/></schematicsheet></Fragment>)}
      <RP2040 name="U1" pcbX={-3.5} pcbY={9} schX={13} schY={23} schWidth={3.8} schHeight={12}
        schSectionName="MCU" schSheetName="MCU" showPinAliases />
      <W25Q16JVUXIQ name="U_FLASH" pcbX={-7} pcbY={22} pcbRotation={90}
        schX={-37} schY={-7} schSectionName="Storage" schSheetName="Storage" showPinAliases />
      <ABM8_272_T3 name="Y1" loadCapacitance="10pF" pcbX={-5} pcbY={-1} pcbRotation={0}
        schX={38} schY={23} schSectionName="Clock" schSheetName="Clock" />
      <PCM5102APWR name="U_DAC" pcbX={11} pcbY={8} pcbRotation={90}
        schX={-12} schY={-7} schWidth={3} schHeight={7} schSectionName="DAC" schSheetName="DAC" showPinAliases />
      <TPA6132A2RTER name="U_AMP" pcbX={19} pcbY={20}
        schX={13} schY={-7} schWidth={3} schHeight={6} schSectionName="Headphones" schSheetName="Headphones" showPinAliases />
      <TPS63031DSKR name="U_REG" pcbX={-22} pcbY={0}
        schX={-12} schY={23} schSectionName="Power" schSheetName="Power" showPinAliases />
      <MCP73831T_2ACI_OT name="U_CHG" pcbX={-22} pcbY={33}
        schX={-18} schY={23} schSectionName="Power" schSheetName="Power" showPinAliases />
      <AO3401A name="Q_SHARE" pcbX={-17} pcbY={30} schX={-6} schY={23} schSectionName="Power" schSheetName="Power" />
      <SS14 name="D_USB" pcbX={-23} pcbY={27} schX={-3} schY={23} schSectionName="Power" schSheetName="Power" />
      <inductor name="L1" inductance="1.5uH" maxCurrentRating="1.3A" manufacturerPartNumber="LPS3015-152MRC" footprint={
        <footprint>
          {[-1,1].map((side,i)=><Fragment key={side}><smtpad portHints={[`pin${i+1}`]} shape="polygon" points={[[-1.65,-1.27],[-1.395,-1.525],[-0.51,-1.525],[-0.51,-0.85],[-0.89,-0.51],[-0.89,0.51],[-0.51,0.85],[-0.51,1.525],[-1.395,1.525],[-1.65,1.27]].map(([x,y])=>({x:x*side,y}))}/></Fragment>)}
          <courtyardrect width="3.6mm" height="3.6mm" />
        </footprint>
      }
        pcbX={-26.5} pcbY={0} pcbRotation={90} schX={-12} schY={20} schSectionName="Power" schSheetName="Power"
        connections={{pin1:"net.SW_L1",pin2:"net.SW_L2"}} />
      <TF_01A name="J_SD" pcbX={-19.8} pcbY={15} pcbRotation={-90}
        schX={-29} schY={-7} schSectionName="Storage" schSheetName="Storage" showPinAliases />
      <PJ_320A name="J_AUX" pcbX={20} pcbY={36.8} pcbRotation={-90}
        schX={20} schY={-7} schSectionName="Headphones" schSheetName="Headphones" />
      <USBLC6_2SC6 name="U_ESD" pcbX={-7} pcbY={34} pcbRotation={180} schX={-31} schY={23} schSectionName="USB" schSheetName="USB" internallyConnectedPins={[["pin1","pin6"],["pin3","pin4"]]} />
      <TYPE_C_31_M_12 name="J_USB" pcbX={-7} pcbY={40} pcbRotation={180}
        schX={-37} schY={23} schWidth={2} schHeight={5} schSectionName="USB" schSheetName="USB" showPinAliases />
      <JstBattery name="J_BAT" pcbX={-22} pcbY={-17}
        schX={-21} schY={23} schSectionName="Power" schSheetName="Power" />
      {/* Buy the through-hole power header separately from LCSC and hand solder. */}
      <pinheader name="J_PWR" pinCount={2} pitch="2.54mm" footprint={PZ254V_11_02P_FOOTPRINT} manufacturerPartNumber="PZ254V-11-02P" supplierPartNumbers={{lcsc:["C492401"]}} pcbX={-23} pcbY={-10}
        schX={-9} schY={23} schSectionName="Power" schSheetName="Power" pinLabels={["VSYS","ENABLE"]}/>
      <BM08B_GHS_TBT_LF__SN_ name="J_LCD" pcbX={0} pcbY={-7}
        schX={38} schY={-7} schSectionName="Controls" schSheetName="Controls" showPinAliases/>
      <pinheader name="J_SWD" pinCount={4} footprint="pinrow4" pcbX={13} pcbY={-8}
        schX={22} schY={23} schSectionName="MCU" schSheetName="MCU" pinLabels={["V3V3","SWDIO","SWCLK","GND"]}/>
      <led name="D_CHG" color="red" footprint={HSMS_C170_FOOTPRINT} manufacturerPartNumber="HSMS-C170" supplierPartNumbers={{jlcpcb:["C6795835"]}} pinLabels={{pin1:["anode","pos"],pin2:["cathode","neg"]}} pcbX={-26} pcbY={38}
        schX={-21} schY={19} schSectionName="Power" schSheetName="Power" connections={{anode:"net.CHG_LED_A",cathode:"net.CHG_STAT"}}/>
      {buttons.map(([name,net,x,y,label],i)=><SKRPACE010 key={name} name={name} pcbX={x} pcbY={y}
        schX={31+(i%4)*5} schY={-14-Math.floor(i/4)*5} schSectionName="Controls" schSheetName="Controls"
        internallyConnectedPins={[["pin1","pin2"],["pin3","pin4"]]}
        connections={{pin1:`net.${net}`,pin2:`net.${net}`,pin3:"net.GND",pin4:"net.GND"}} />)}
      {resistors.map(([name,resistance,pcbX,pcbY,pcbRotation,section,a,b])=>
        <resistor key={name} name={name} resistance={resistance} footprint="0603" pcbX={pcbX} pcbY={pcbY} pcbRotation={pcbRotation}
          {...schematicPassive(name,section)} connections={{pin1:`net.${a}`,pin2:`net.${b}`}}/>)}
      {caps.map(([name,capacitance,pcbX,pcbY,pcbRotation,section,a,b])=>
        <capacitor key={name} name={name} capacitance={capacitance} maxVoltageRating="16V" footprint="0603"
          pcbX={pcbX} pcbY={pcbY} pcbRotation={pcbRotation} {...schematicPassive(name,section)}
          schOrientation={a === "GND" ? "pos_bottom" : "pos_top"} connections={{pin1:`net.${a}`,pin2:`net.${b}`}}/>)}
      <schematicbox name="U1 USB pins" chipRef=".U1" schSheetName="USB" schSectionName="USB" schX={-43} schY={23} width={3} height={0.8}
        pinLabels={{pin46:"USB_DM",pin47:"USB_DP"}} schPinArrangement={{rightSide:["pin46","pin47"],leftSide:[]}} />
      <schematicbox name="U1 crystal pins" chipRef=".U1" schSheetName="Clock" schSectionName="Clock" schX={31} schY={23} width={3} height={0.8}
        pinLabels={{pin20:"XIN",pin21:"XOUT"}} schPinArrangement={{rightSide:["pin20","pin21"],leftSide:[]}} />
      {Object.entries({...powerPins,...mcuPins}).filter(([pin])=>![20,21,46,47].includes(Number(pin))).map(([pin,net])=>link("U1",Number(pin),net))}
      {["QSPI_CS","QSPI1","QSPI2","GND","QSPI0","QSPI_CLK","QSPI3","V3V3","GND"].map((net,i)=>link("U_FLASH",i+1,net))}
      {[[2,"GND"],[4,"GND"]].map(([pin,net])=>link("Y1",pin as number,net as string))}
      {["V3V3","DAC_CAPP","GND","DAC_CAPM","DAC_VNEG","DAC_L","DAC_R","V3V3","GND","GND","GND","GND","I2S_BCK","I2S_DATA","I2S_LRCK","GND","DAC_UNMUTE","DAC_LDO","GND","V3V3"].map((net,i)=>link("U_DAC",i+1,net))}
      {["AMP_L","AMP_REF_L","AMP_REF_R","AMP_R","HP_R","GND","GND","AMP_NEG","AMP_CPN","GND","AMP_CPP","AMP_HPVDD","AMP_ENABLE","V3V3","GND","HP_L","GND"].map((net,i)=>link("U_AMP",i+1,net))}
      {["V3V3","SW_L2","GND","SW_L1","VSYS","ENABLE","VSYS","VSYS","GND","V3V3","GND"].map((net,i)=>link("U_REG",i+1,net))}
      {["CHG_STAT","GND","VBAT","VBUS","CHG_PROG"].map((net,i)=>link("U_CHG",i+1,net))}
      {["VBUS","VSYS","VBAT"].map((net,i)=>link("Q_SHARE",i+1,net))}
      {link("D_USB",1,"VSYS")}{link("D_USB",2,"VBUS")}
      {["SD_D2","SD_CS","SD_MOSI","V3V3","SD_CLK","GND","SD_MISO","SD_D1","SD_DETECT","GND","GND","GND","GND"].map((net,i)=>link("J_SD",i+1,net))}
      {link("J_AUX",2,"HP_L")}{link("J_AUX",3,"HP_R")}{link("J_AUX",4,"GND")}{link("J_AUX",5,"GND")}
      {["USB_DM","GND","USB_DP","USB_DP","VBUS","USB_DM"].map((net,i)=>link("U_ESD",i+1,net))}
      {["VBUS1","VBUS2"].map(pin=>link("J_USB",pin,"VBUS"))}
      {["GND1","GND2","EH1","EH2","EH3","EH4"].map(pin=>link("J_USB",pin,"GND"))}
      {link("J_USB","CC1","CC1")}{link("J_USB","CC2","CC2")}
      {["DP1","DP2"].map(pin=>link("J_USB",pin,"USB_DP"))}
      {["DN1","DN2"].map(pin=>link("J_USB",pin,"USB_DM"))}
      {[["J_BAT",["GND","VBAT"]],["J_PWR",["VSYS","ENABLE"]],["J_LCD",["LCD_BL","LCD_RST","LCD_DC","LCD_CS","LCD_CLK","LCD_DIN","GND","V3V3","GND","GND"]],["J_SWD",["V3V3","SWDIO","SWCLK","GND"]]].map(([ref,nets])=>(nets as string[]).map((net,i)=>link(ref as string,i+1,net)))}
      <SheetTrace name="DAC_GROUND_DEMP" sheet="DAC" from=".U_DAC > .pin10" to=".U_DAC > .pin9" pcbPath={[]} thickness="0.12mm" />
      <SheetTrace name="DAC_GROUND_FLT" sheet="DAC" from=".U_DAC > .pin11" to=".U_DAC > .pin12" pcbPath={[]} thickness="0.12mm" />
      <SheetTrace name="USB_PAIR_DM" sheet="USB" from=".U1 > .USB_DM" to=".R_DM > .pin2" thickness="0.12mm" pcbPath={[{x:1.4,y:8.425},{x:1.8,y:8.825}]} />
      <SheetTrace name="USB_PAIR_DP" sheet="USB" from=".U1 > .USB_DP" to=".R_DP > .pin2" thickness="0.12mm"
        pcbPath={[{x:0.999998,y:8.425},{x:-0.000002,y:9.425}]} />
      {/* Explicit crystal paths are relative to each starting component, including its rotation. */}
      <SheetTrace name="XTAL_INPUT" sheet="Clock" from=".U1 > .XIN" to=".Y1 > .pin1" thickness="0.12mm"
        pcbPath={[{x:-0.6,y:-4.5},{x:-3.7,y:-7.4},{x:-3.7,y:-10.85}]} />
      <SheetTrace name="XTAL_OUTPUT" sheet="Clock" from=".U1 > .XOUT" to=".R_XOUT > .pin1" thickness="0.12mm"
        pcbPath={[{x:-0.2,y:-4.5},{x:1.975,y:-6.675}]} />
      <SheetTrace name="XTAL_RETURN" sheet="Clock" from=".R_XOUT > .pin2" to=".Y1 > .pin3" thickness="0.12mm" schDisplayLabel="XTAL_OUT"
        pcbPath={[{x:1.65,y:0}]} />
      <SheetTrace name="XTAL_CIN" sheet="Clock" from=".Y1 > .pin1" to=".C_XIN > .pin1" thickness="0.12mm" schDisplayLabel="XIN"
        pcbPath={[{x:-2.2,y:-0.85}]} />
      <SheetTrace name="XTAL_COUT" sheet="Clock" from=".Y1 > .pin3" to=".C_XOUT > .pin1" thickness="0.12mm" schDisplayLabel="XTAL_OUT"
        pcbPath={[{x:2.5,y:0.85},{x:2.5,y:-0.325}]} />
    </Fragment>
    <copperpour name="GND_inner1" layer="inner1" connectsTo="net.GND" clearance="0.2mm" boardEdgeMargin="0.5mm" />
    <copperpour name="GND_inner2" layer="inner2" connectsTo="net.GND" clearance="0.2mm" boardEdgeMargin="0.5mm" />
    {[-26,26].flatMap(x=>[-41,41].map(y=><Fragment key={`${x},${y}`}><hole name={`H_${x}_${y}`} pcbX={x} pcbY={y} diameter="2.7mm"/></Fragment>))}
    <silkscreentext text="POCKET AUDIO / REV B" pcbX={0} pcbY={-20} fontSize="1mm" />
    <silkscreentext text="USB-C" pcbX={-7} pcbY={35.5} fontSize="0.8mm" />
    <silkscreentext text="AUX / HEADPHONES" pcbX={16} pcbY={28} fontSize="0.7mm" />
    <silkscreentext text="LiPo: 1 GND / 2 +" pcbX={-20} pcbY={-14} fontSize="0.7mm" />
    <silkscreentext text="LCD: GH 1.25 / SPI1" pcbX={0} pcbY={-10.5} fontSize="0.65mm" />
    {buttons.map(([name,net,x,y,label])=><Fragment key={name}><silkscreentext text={label} pcbX={x} pcbY={y-3} fontSize="0.8mm"/></Fragment>)}
  </board>
);