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],
});