shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

scripts/finalize-software-current.mjs

import fs from "node:fs"
import crypto from "node:crypto"
import assert from "node:assert/strict"
const read=p=>JSON.parse(fs.readFileSync(p,"utf8"))
const sha=p=>crypto.createHash("sha256").update(fs.readFileSync(p)).digest("hex")
const circuitPath="dist/index/circuit.json",c=read(circuitPath),circuitSha256=sha(circuitPath)
const steps=fs.readFileSync("reports/software-current-validation.log","utf8").trim().split("\n").map(JSON.parse)
const required=["continuity","copper","typecheck","drill","copper-regression","shorts","native","style-cli","warnings","style-current","dfm","solder","kelvin","motor","gerbers","artwork","module-tests","stock","bom","module-regression","firmware-tests","client-tests","board-tests","verify"]
assert.deepEqual(steps.map(e=>e.step).sort(),required.sort())
assert.ok(steps.every(e=>e.exit===0))
assert.deepEqual(c.filter(e=>e.type.endsWith("_error")),[])
const reports=["reports/connectivity-audit.json","reports/coil-all-copper-preflight-meta.json",
  "reports/drill-clearance-regression.json","reports/software-current-copper-regression.json",
  "reports/review-warning-regression.json","reports/review-style/analysis.json",
  "reports/jlcpcb-stock-audit.json","reports/bom-validation.json","reports/additional-dfm-review.json",
  "reports/solder-process-audit.json","reports/stencil-artwork-audit.json","reports/assembly-motor-reference.json","verification.json"]
for(const p of reports)assert.equal(read(p).circuitSha256,circuitSha256,`fresh evidence: ${p}`)
assert.equal(read("reports/connectivity-audit.json").emittedCopperOnly,true)
assert.equal(read("reports/connectivity-audit.json").sourceFailures,0)
assert.equal(read("reports/connectivity-audit.json").disconnectedTerminalIslands,0)
assert.deepEqual(read("reports/software-current-copper-regression.json").unintendedChanges,[])
assert.equal(read("reports/drill-clearance-regression.json").currentFindings,0)
assert.equal(read("reports/review-style/analysis.json").issueCount,0)
assert.deepEqual(read("reports/review-warning-regression.json").regressions,[])
assert.equal(read("reports/review-warning-regression.json").newWidthReportingDiagnostics.length,4)
assert.ok(read("reports/coil-session-kelvin.json").every(e=>e.connected&&e.joinsOnlyAtShuntLand))
assert.equal(read("reports/module-test-regression.json").currentPassed,32)
assert.equal(read("reports/module-test-regression.json").currentFailed,0)
assert.equal(read("reports/solder-process-audit.json").ordinaryPadDrillIntersections.length,0)
assert.deepEqual(read("reports/stencil-artwork-audit.json").failures,[])
assert.equal(read("verification.json").fabricationReady,false)
assert.match(fs.readFileSync("reports/software-current-build.log","utf8"),/Build exiting with code 0/)
assert.match(fs.readFileSync("reports/software-current-board-tests.log","utf8"),/29 pass\s+0 fail/)
assert.match(fs.readFileSync("reports/software-current-client-tests.log","utf8"),/Ran 10 tests/)
assert.match(fs.readFileSync("reports/software-current-arm-build.log","utf8"),/7336\s+12\s+752/)
assert.equal(sha("scripts/route-round7-usb.py"),sha("../../work/nema17-clean-schematic-v054-IAQpFd/scripts/route-round7-usb.py"),"routing helper unchanged")
assert.equal(sha("package.json"),sha("../../work/nema17-clean-schematic-v054-IAQpFd/package.json"),"runtime dependencies/version unchanged; no publication")
const sources=["index.circuit.tsx","board-layout.ts","schematic-plan.ts","motor-stage.tsx","software-current.tsx","software-current-placement.json",
  "imports/MCP4725A0T_E_CH.tsx","routing-boundary.ts","routing-signature.ts","whole-board-router.ts",
  "routing/complete-routes.json","routing/expected-input.json","routing/native-features.json","routing/trace-constraints.json","routing/net-map.json","routing/physical-copper.json",
  "firmware/stm32/main.c","firmware/stm32/motion.c","firmware/stm32/motion.h","firmware/stm32/limit.c","firmware/stm32/limit.h","firmware/stm32/test_limit.c",
  "firmware/stm32/Makefile","firmware/stm32/build/motion.bin","firmware/motor-control.py","firmware/PROTOCOL.md",
  "README.md","hardware-validation.md","motor-harness.md","requirements-routing.txt"]
const logs=["reports/software-current-validation.log","reports/software-current-build.log","reports/software-current-board-tests.log",
  "reports/software-current-module-tests.log","reports/software-current-baseline-module-tests.log","reports/module-test-regression.json",
  "reports/software-current-firmware-tests.log","reports/software-current-client-tests.log","reports/software-current-arm-build.log",
  "reports/software-current-session-preservation.json","reports/coil-session-kelvin.json",
  "reports/software-current-pcb-top.png","reports/software-current-pcb-bottom.png","reports/software-current-schematic/08-motor_stage.png"]
const report={checkedAt:new Date().toISOString(),status:"LOCAL_VALIDATION_PASS_NOT_FABRICATION_APPROVAL",circuitSha256,
  published:false,publishedBaseline:"0.4.55",fabricationReady:false,
  feature:{nominalPeakCurrentRangeMa:[0,396],commonToBothPhases:true,disarmedOnly:true,defaultMa:396,
    eepromWrites:false,bootZeroReadbackAndSettlingInterlock:true,matchedNewPcbAndFirmwareRequired:true},
  validationStages:steps.length,tests:{board:29,storedModules:32,pythonClient:10,sanitizerSuites:3,armBuild:true},
  nativeErrors:0,shorts:0,styleIssues:0,openSourceConnections:0,independentDrillFindings:0,
  warnings:{inherited:151,additionalWholeNetReportingDiagnostics:4,visibleTotal:155,diagnosticsSuppressed:false},
  unchanged:"42.3 mm four-layer outline, mounting/screw envelopes, connector types/locations/faces, motor/cable assembly, all original part values and firmware pin assignments; original wide ground/winding copper protected except declared same-width input-feed rework and approved moved land areas",
  qualificationStillRequired:read("verification.json").fabricationBlockers,
  evidence:Object.fromEntries([...reports,...logs,...sources].map(p=>[p,sha(p)]))}
fs.writeFileSync("reports/software-current-acceptance.json",JSON.stringify(report,null,2)+"\n")
console.log(JSON.stringify({status:report.status,circuitSha256,validationStages:steps.length,published:false,fabricationReady:false}))