MustafaMulla29/rp2040-bldc-motor-controller-new
A USB‑C PD–powered RP2040 BLDC motor controller PCB with 3.3 V logic, MCT8329A sensorless commutation, three MOSFET half-bridges, protected power switching, USB data, controls, and motor connectors.
- Version
- 0.3.82
- License
- unset
- Stars
- 0
scripts/check-assembly-pcb.mjs
/** Audit the actual main build before using it in the mechanical assembly. */
import {spawnSync} from 'node:child_process'
import {readFileSync,writeFileSync,mkdirSync} from 'node:fs'
import {resolve} from 'node:path'
import {createHash} from 'node:crypto'
const project=resolve(import.meta.dirname,'..'),results=resolve(project,'assembly/dist/results')
mkdirSync(results,{recursive:true})
const input=resolve(project,'dist/index/circuit.json'),raw=readFileSync(input),data=JSON.parse(raw)
const sha256=createHash('sha256').update(raw).digest('hex')
if(data.some(x=>x.type.endsWith('_error')))throw Error('Generated circuit contains errors')
const candidates=[process.env.PCB_AUDIT_PYTHON,resolve(project,'.venv-pcb-audit/bin/python'),'python3'].filter(Boolean)
const python=candidates.find(cmd=>spawnSync(cmd,['-c','import shapely; assert int(shapely.__version__.split(".")[0]) >= 2'],{encoding:'utf8'}).status===0)
if(!python)throw Error('Use Python with Shapely 2; set PCB_AUDIT_PYTHON to that interpreter. See scripts/pcb-audit/requirements.txt.')
const checks=[]
for(const [name,cmd,args] of [
['native-drc','bun',['scripts/check-routed.mjs',input,resolve(results,'pcb-drc.json')]],
['jlc-preflight',python,['scripts/pcb-audit/audit-jlcpcb.py',input]],
['physical-widths',python,['scripts/pcb-audit/audit-widths.py',input]],
['kelvin-sensing',python,['scripts/pcb-audit/audit-kelvin.py',input]],
['route-cleanup',python,['scripts/pcb-audit/audit-route-cleanup.py',input]],
['layout-constraints',python,['scripts/pcb-audit/audit-layout.py',input]],
['pad-anchors',python,['scripts/pcb-audit/check-pad-anchors.py',input]],
]){
const start=Date.now(),r=spawnSync(cmd,args,{cwd:project,encoding:'utf8',maxBuffer:20e6,env:{...process.env,PCB_AUDIT_OUTPUT:results}})
writeFileSync(resolve(results,name+'.log'),(r.stdout??'')+(r.stderr??''));checks.push({name,status:r.status,seconds:(Date.now()-start)/1000});console.log(name,r.status===0?'PASS':'FAIL');if(r.status!==0)throw Error(name+' failed; see assembly/dist/results/'+name+'.log')
}
const report=file=>JSON.parse(readFileSync(resolve(results,file)))
const pre=report('jlcpcb-preflight.json'),cu=report('copper-connectivity.json'),widths=report('width-audit.json'),anchors=report('pad-anchor-audit.json'),drc=report('pcb-drc.json')
for(const x of [pre,cu,widths,anchors])if(x.sha256!==sha256)throw Error('Audit artifact hash mismatch')
if(drc.circuitSha256!==sha256||drc.status!=='PASS')throw Error('Native DRC failed')
if(Object.values(pre.findings).some(v=>v.length))throw Error('Manufacturing-clearance findings remain')
if(Object.keys(cu.disconnected).length||cu.floating.length)throw Error('Physical connectivity failures')
if(widths.paths.some(p=>!p.pass)||anchors.failures.length)throw Error('Power path or pad anchor failure')
const board=data.find(x=>x.type==='pcb_board')
writeFileSync(resolve(results,'pcb-validation.json'),JSON.stringify({sha256,checkedAt:new Date().toISOString(),project:'rp2040-bldc-motor-controller-new',checks,nativeDrcErrors:0,physicalDisconnectedNets:0,floatingCopper:0,manufacturingClearanceFindings:0,requiredPathsPassed:widths.paths.length,padAnchorsPassed:anchors.checked,boardSizeMm:[board.width,board.height],copperLayers:board.num_layers,viaDiameterMm:{hole:.3,pad:.45},note:'PCB checks only; adapter mating dimensions and operating current remain unverified.'},null,2)+'\n')
console.log('Validated power-switch PCB:',sha256)