pixalynx/cm5-minimal-carrier
A 4-layer Raspberry Pi CM5 carrier board routes USB‑C 5V power through an RT9742 load switch with TVS protection and capacitive filtering, while providing ESD-protected HDMI output, CM5 connectors, test points, and ground/power planes.
- Version
- 0.1.1
- License
- unset
- Stars
- 0
lib/footprints.tsx
import geometry from './footprints.json'
import { Fragment } from 'react'
export function physicalPin(id:string,pin:string):string{
if(id==='usb-c') { if(pin==='S1')return '25'; const common:Record<string,string>={B1:'12',B4:'9',B9:'4',B12:'1'};if(common[pin])return common[pin]; const m=/^([AB])(\d+)$/.exec(pin);if(m)return String(Number(m[2])+(m[1]==='B'?12:0)) }
if(id==='hdmi'&&pin.startsWith('SH'))return String(19+Number(pin.slice(2)))
return pin
}
export function Footprint({id}:{id:string}){
const g=geometry[id as keyof typeof geometry]
// GCT uses common physical lands for A1/B12, A4/B9, A9/B4, A12/B1.
const unique=g.pads.filter((p,i,a)=>a.findIndex(q=>q.x===p.x&&q.y===p.y)===i)
return <footprint insertionDirection={id.startsWith("cm5-")?"from_above":["usb-c","hdmi"].includes(id)?"from_bottom":undefined}>
{unique.map((p,i)=>{const hints=g.pads.filter(q=>p.x===q.x&&p.y===q.y).map(q=>'pin'+physicalPin(id,q.pin));const t=p as typeof p & {dw?:number,dh?:number};return <Fragment key={i}>{p.kind==='smd'?<smtpad portHints={hints} pcbX={p.x} pcbY={p.y} width={p.w} height={p.h} shape="rect"/>:<platedhole portHints={hints} pcbX={p.x} pcbY={p.y} holeWidth={t.dw!} holeHeight={t.dh!} outerWidth={p.w} outerHeight={p.h} shape="pill"/>}</Fragment>})}
{g.holes.map((p,i)=><Fragment key={i}><hole pcbX={p.x} pcbY={p.y} diameter={p.d}/></Fragment>)}
{g.lines.map((l,i)=><Fragment key={i}><silkscreenpath route={l.map(([x,y])=>({x,y:id==='hdmi'?Math.max(y,-9.25):y}))} strokeWidth={0.15}/></Fragment>)}
{(()=>{const special:Record<string,number[]>={'cm5-1':[-1.95,-11.65,1.95,11.65],'cm5-2':[-1.95,-11.65,1.95,11.65],'usb-c':[-4.95,-2.3,4.95,4.5],hdmi:[-8.5,-9.8,8.5,2.3],esd:[-.85,-1.45,.85,1.45]};const [x1,y1,x2,y2]=special[id]??[Math.min(...g.pads.map(p=>p.x-p.w/2))-.25,Math.min(...g.pads.map(p=>p.y-p.h/2))-.25,Math.max(...g.pads.map(p=>p.x+p.w/2))+.25,Math.max(...g.pads.map(p=>p.y+p.h/2))+.25];return <courtyardoutline outline={[{x:x1,y:y1},{x:x2,y:y1},{x:x2,y:y2},{x:x1,y:y2},{x:x1,y:y1}]}/>})()}
</footprint>
}