gokul/usb3-sd-hub
Engineering draft: four-layer, computer-powered USB 3 hub with one USB-C host socket, two USB-C and two USB-A accessory sockets, and a full-size SD slot. Board and three schematic previews are available. Routing and production checks are incomplete; not fabrication ready.
- Version
- 0.1.5
- License
- MIT
- Stars
- 0
design/downstream-four.ts
import {
wire,
via,
offsetPath,
matchOnHorizontal,
halfCenterGapMm,
type NumericPath,
type Point,
} from "./paired-paths";
const transmitTop: Point[] = [
{ x: 3, y: -3.5 },
{ x: 3, y: -6.8 },
];
const transmitBottom: Point[] = [
{ x: 3, y: -8 },
{ x: 3, y: -10.2 },
{ x: 4, y: -11.2 },
{ x: 29.65, y: -11.2 },
{ x: 31, y: -12.55 },
{ x: 29.55, y: -14 },
{ x: 29.55, y: -14.3 },
];
const receiveTop: Point[] = [
{ x: 4.2, y: -1.6 },
{ x: 4.2, y: -7.8 },
];
const receiveBottom: Point[] = [
{ x: 4.2, y: -9 },
{ x: 4.2, y: -9.1 },
{ x: 5.2, y: -10.1 },
{ x: 31, y: -10.1 },
{ x: 32, y: -11.1 },
{ x: 32, y: -13.2 },
{ x: 30.65, y: -14.55 },
{ x: 30.65, y: -14.85 },
];
function transmitPath(positive: boolean): NumericPath {
const offsetMm = positive ? halfCenterGapMm : -halfCenterGapMm;
const capPad = { x: positive ? 2.5 : 3.5, y: -2.91 };
const firstVia = { x: positive ? 2.65 : 3.35, y: -7.5 };
const landing = { x: positive ? 29.2 : 29.9, y: -14.8 };
const muxPad = { x: positive ? 29.199898 : 29.599948, y: -14.199896 };
const top = offsetPath({ points: transmitTop, offsetMm });
const bottom = offsetPath({ points: transmitBottom, offsetMm });
const first = top[0];
const last = top.at(-1)!;
const bottomLast = bottom.at(-1)!;
return {
connection: positive ? "C_D4_TXP.pin2" : "C_D4_TXN.pin2",
route: [
wire(capPad, "top"),
wire({ x: first.x, y: capPad.y - Math.abs(first.x - capPad.x) }, "top"),
...top.map((point) => wire(point, "top")),
wire({ x: last.x, y: firstVia.y + Math.abs(last.x - firstVia.x) }, "top"),
wire(firstVia, "top"),
via(firstVia, "top"),
wire(firstVia),
...bottom.map((point) => wire(point)),
wire({
x: bottomLast.x,
y: landing.y + Math.abs(bottomLast.x - landing.x),
}),
wire(landing),
via(landing, "bottom"),
wire(landing, "top"),
wire({ x: landing.x, y: -14.45 - Math.abs(muxPad.x - landing.x) }, "top"),
wire({ x: muxPad.x, y: -14.45 }, "top"),
wire(muxPad, "top"),
],
};
}
function receivePath(positive: boolean): NumericPath {
const offsetMm = positive ? halfCenterGapMm : -halfCenterGapMm;
const hubPad = { x: positive ? 4 : 4.4, y: -0.85 };
const firstVia = { x: positive ? 3.85 : 4.55, y: -8.5 };
const landing = { x: positive ? 30.4 : 31.1, y: -15.35 };
const muxPad = {
x: positive ? 30.400048 : 30.8000472,
y: positive ? -14.199896 : -14.2000992,
};
const top = offsetPath({ points: receiveTop, offsetMm });
const bottom = offsetPath({ points: receiveBottom, offsetMm });
const first = top[0];
const last = top.at(-1)!;
const bottomLast = bottom.at(-1)!;
return {
connection: positive ? "U_HUB.D4_RXP" : "U_HUB.D4_RXN",
route: [
wire(hubPad, "top"),
wire({ x: hubPad.x, y: first.y + Math.abs(first.x - hubPad.x) }, "top"),
...top.map((point) => wire(point, "top")),
wire({ x: last.x, y: firstVia.y + Math.abs(last.x - firstVia.x) }, "top"),
wire(firstVia, "top"),
via(firstVia, "top"),
wire(firstVia),
...bottom.map((point) => wire(point)),
wire({
x: bottomLast.x,
y: landing.y + Math.abs(bottomLast.x - landing.x),
}),
wire(landing),
via(landing, "bottom"),
wire(landing, "top"),
wire({ x: landing.x, y: -14.55 - Math.abs(muxPad.x - landing.x) }, "top"),
wire({ x: muxPad.x, y: -14.55 }, "top"),
wire(muxPad, "top"),
],
};
}
export const downstreamFourTransmitPaths = matchOnHorizontal({
paths: [transmitPath(true), transmitPath(false)],
startXsMm: [8, 14, 20],
awayDirection: [-1, 1],
});
export const downstreamFourReceivePaths = matchOnHorizontal({
paths: [receivePath(true), receivePath(false)],
startXsMm: [8, 14, 20],
awayDirection: [-1, 1],
});