astra/am3352-sbc
A 4-layer AM3352 single-board computer with 128‑MiB DDR3, PMIC power regulation, USB‑C 5‑V PD input, dual USB host ports, HDMI output with ESD protection, microSD/UART/JTAG interfaces, addressable RGB indicators, and a PWM-driven buzzer.
- Version
- 0.1.19
- License
- unset
- Stars
- 0
design/display.tsx
import { Fragment } from "react";
import { Tfp410 } from "../components/tfp410";
import { TPD12S521DBTR } from "../components/TPD12S521DBTR";
import { HDMI_001_19PCBTP } from "../components/HDMI_001_19PCBTP";
import { BLM18AG601SN1D } from "../components/BLM18AG601SN1D";
import { SignalTrace, Cap, Res, cpuPin, link } from "./nets";
// RGB565 expands into the most significant bits of TFP410's 24-bit input.
// TI SLDS145D: high-swing 3.3 V input requires VREF=DVDD (not a divider).
export function Display() {
const dataPins = [3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 19, 20, 21, 22, 23];
const pairs = [
{ id: "CK", out: "C", p: 10, n: 12 },
{ id: "D0", out: "0", p: 7, n: 9 },
{ id: "D1", out: "1", p: 4, n: 6 },
{ id: "D2", out: "2", p: 1, n: 3 },
];
return (
<>
<Tfp410
noConnect={["MSEN_PO1", "NC"]}
name="U_HDMI"
pcbX={22}
pcbY={-16}
/>
<TPD12S521DBTR
noConnect={["CE_REMOTE_IN", "CE_REMOTE_OUT"]}
internallyConnectedPins={pairs.flatMap(({ id }) => [
[`TMDS_${id}_POS1`, `TMDS_${id}_POS2`],
[`TMDS_${id}_NEG1`, `TMDS_${id}_NEG2`],
])}
name="U_HDMI_ESD"
pcbX={35}
pcbY={-16}
pcbRotation={270}
/>
<HDMI_001_19PCBTP
name="J_HDMI"
pcbX={44}
pcbY={-16}
pcbRotation={90}
noConnect={["pin13", "pin14"]}
/>
{dataPins.map((pin, i) => (
<Fragment key={i}>
<SignalTrace
name={`LCD_DATA${i}_SIGNAL`}
from={cpuPin(`LCD_DATA${i}`)}
to={`U_HDMI.DATA${pin}`}
routingPhaseIndex={4}
/>
{link("U_HDMI", `DATA${pin}`, `LCD_DATA${i}`)}
</Fragment>
))}
{[0, 1, 2, 8, 9, 16, 17, 18].map((p) =>
link("U_HDMI", `DATA${p}`, "GND"),
)}
{[
["LCD_PCLK", "IDCK_P"],
["LCD_HSYNC", "HSYNC"],
["LCD_VSYNC", "VSYNC"],
["LCD_AC_BIAS_EN", "DE"],
].map(([signal, pin]) => (
<SignalTrace
key={signal}
name={signal}
from={cpuPin(signal)}
to={`U_HDMI.${pin}`}
routingPhaseIndex={4}
/>
))}
{[
"DGND_16",
"DGND_48",
"DGND_64",
"PGND",
"TGND_20",
"TGND_26",
"TGND_32",
"THERMAL_PAD",
"IDCK_N",
"RESERVED",
"DKEN",
"ISEL_RST",
"DSEL_SDA",
"A3_DK3",
"CTL2_A2_DK2",
"CTL1_A1_DK1",
].map((p) => link("U_HDMI", p, "GND"))}
{["DVDD_1", "DVDD_12", "DVDD_33", "VREF", "BSEL_SCL", "EDGE_HTPLG"].map(
(p) => link("U_HDMI", p, "V3V3"),
)}
{link("U_HDMI", "PD", "PWRONRSTn")}
{["TVDD_23", "TVDD_29"].map((p) => link("U_HDMI", p, "HDMI_TVDD"))}
{link("U_HDMI", "PVDD", "HDMI_PVDD")}
{link("U_HDMI", "TFADJ", "HDMI_TFADJ")}
<Res
name="R_TFADJ"
a="HDMI_TFADJ"
b="HDMI_TVDD"
value="510"
x={31}
y={-24}
/>
{["TVDD", "PVDD"].map((rail, i) => (
<Fragment key={rail}>
<BLM18AG601SN1D name={`FB_HDMI${i}`} pcbX={25 + i * 4} pcbY={-28} />
{link(`FB_HDMI${i}`, "pin1", "V3V3")}
{link(`FB_HDMI${i}`, "pin2", `HDMI_${rail}`)}
<Cap
name={`C_HDMI_BULK${i}`}
net={`HDMI_${rail}`}
value="1uF"
x={25 + i * 4}
y={-31}
/>
</Fragment>
))}
{[
["V3V3", 19, -24],
["V3V3", 24, -24],
["V3V3", 24, -8],
["HDMI_TVDD", 30, -7],
["HDMI_TVDD", 27, -7],
["HDMI_PVDD", 32, -26],
].map(([net, x, y], i) => (
<Cap
key={i}
name={`C_HDMI${i}`}
net={net as string}
x={x as number}
y={y as number}
/>
))}
{pairs.map(({ id, out, p, n }) => (
<Fragment key={id}>
{[
["P", "POS", p],
["N", "NEG", n],
].map(([pol, word, jpin]) => (
<Fragment key={pol}>
<SignalTrace
name={`TMDS_${id}_${pol}_TX`}
from={`U_HDMI.TX${out}_${pol}`}
to={`U_HDMI_ESD.TMDS_${id}_${word}1`}
routingPhaseIndex={3}
/>
<SignalTrace
name={`TMDS_${id}_${pol}_PORT`}
from={`U_HDMI_ESD.TMDS_${id}_${word}2`}
to={`J_HDMI.pin${jpin}`}
routingPhaseIndex={3}
/>
</Fragment>
))}
{["TX", "PORT"].map((segment) => (
<differentialpair
name={`TMDS_${id}_${segment}`}
positiveConnection={`TMDS_${id}_P_${segment}`}
negativeConnection={`TMDS_${id}_N_${segment}`}
targetDifferentialImpedance="100ohm"
maxLengthSkew={0.127}
pcbTraceGap={0.18}
/>
))}
</Fragment>
))}
{[
"GND1",
"GND2",
...Array.from({ length: 8 }, (_, i) => `TMDS_GND${i + 1}`),
].map((p) => link("U_HDMI_ESD", p, "GND"))}
{[2, 5, 8, 11, 17, 20, 21, 22, 23].map((p) =>
link("J_HDMI", `pin${p}`, "GND"),
)}
{link("U_HDMI_ESD", "5V_SUPPLY", "VIN_5V")}
{link("U_HDMI_ESD", "LV_SUPPLY", "V3V3")}
{link("U_HDMI_ESD", "5V_OUT", "HDMI_5V")}
{link("J_HDMI", "pin18", "HDMI_5V")}
{link("U_HDMI_ESD", "DDC_CLK_IN", "I2C0_SCL")}
{link("U_HDMI_ESD", "DDC_DAT_IN", "I2C0_SDA")}
{link("U_HDMI_ESD", "DDC_CLK_OUT", "HDMI_SCL")}
{link("J_HDMI", "pin15", "HDMI_SCL")}
{link("U_HDMI_ESD", "DDC_DAT_OUT", "HDMI_SDA")}
{link("J_HDMI", "pin16", "HDMI_SDA")}
{link("U_HDMI_ESD", "HOTPLUG_DET_OUT", "HDMI_HPD_5V")}
{link("J_HDMI", "pin19", "HDMI_HPD_5V")}
{link("U_HDMI_ESD", "HOTPLUG_DET_IN", "HDMI_HPD")}
{link("U1", "R13", "HDMI_HPD")}
{link("U_HDMI_ESD", "ESD_BYP", "HDMI_ESD_BYP")}
<Res
name="R_HDMI_SCL"
a="HDMI_SCL"
b="HDMI_5V"
value="1.7k"
x={40}
y={-25}
/>
<Res
name="R_HDMI_SDA"
a="HDMI_SDA"
b="HDMI_5V"
value="1.7k"
x={43}
y={-25}
/>
<Res name="R_HDMI_HPD" a="HDMI_HPD_5V" b="GND" x={43} y={-28} />
<Res
name="R_HDMI_HPD_LV"
a="HDMI_HPD"
b="V3V3"
value="47k"
x={37}
y={-28}
/>
<Cap name="C_HDMI_ESD" net="HDMI_ESD_BYP" x={36} y={-24} />
<Cap name="C_HDMI_5V" net="HDMI_5V" x={40} y={-28} />
<Cap name="C_HDMI_SUPPLY" net="VIN_5V" x={36} y={-8} />
<Cap name="C_HDMI_LV" net="V3V3" x={37.5} y={-6} />
<silkscreentext text="HDMI VIDEO" pcbX={41} pcbY={-4} fontSize={0.9} />
</>
);
}