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/write-current-checkpoint.mjs
import fs from "node:fs"
import crypto from "node:crypto"
import assert from "node:assert/strict"
const read = path => JSON.parse(fs.readFileSync(path, "utf8"))
const hash = path => crypto.createHash("sha256").update(fs.readFileSync(path)).digest("hex")
const circuitPath = "dist/index/circuit.json"
const circuitSha256 = hash(circuitPath)
const circuit = read(circuitPath)
const continuity = read("reports/connectivity-audit.json")
const stock = read("reports/jlcpcb-stock-audit.json")
const drill = read("reports/drill-clearance-regression.json")
const verification = read("verification.json")
const moduleRegression = read("reports/module-test-regression.json")
const draftCheckpoint = fs.existsSync("reports/checkpoint-publish-confirmation.json")
? read("reports/checkpoint-publish-confirmation.json") : null
const promotion = fs.existsSync("reports/current-sensing-promotion.json")
? read("reports/current-sensing-promotion.json") : null
const fullReview = fs.existsSync("reports/full-board-review.json")
? read("reports/full-board-review.json") : null
if (promotion) assert.equal(promotion.latestVerified, true)
if (draftCheckpoint) {
assert.deepEqual(draftCheckpoint.mismatches, [])
assert.equal(draftCheckpoint.mainReleaseUnchanged, true)
}
for (const report of [continuity, stock, drill, verification])
assert.equal(report.circuitSha256, circuitSha256, "final audit matches actual emitted artifact")
assert.equal(continuity.emittedCopperOnly, true)
assert.equal(continuity.sourceFailures, 0)
assert.equal(continuity.disconnectedTerminalIslands, 0)
assert.equal(drill.regressionCount, 0)
assert.deepEqual(stock.missingCodes, [])
assert.ok(stock.parts.every(part => part.status === "in-stock"))
assert.equal(verification.drcErrors, 0)
assert.equal(verification.fabricationReady, false)
assert.equal(moduleRegression.addedFailures, 0)
const preflight = read("reports/coil-all-copper-preflight.json")
const kelvin = read("reports/coil-session-kelvin.json")
const placement = read("routing/placement-clearance-report.json")
assert.deepEqual(preflight, [])
assert.deepEqual(placement, [])
assert.equal(kelvin.length, 4)
assert.ok(kelvin.every(check => check.connected && check.joinsOnlyAtShuntLand))
const manual = read("reports/manual-routing-import-report.json")
assert.equal(manual.circuit_sha256, hash("routing/placement.json"))
assert.equal(manual.session_sha256, hash("routing/current-sense-staging.ses"))
assert.deepEqual(manual.failures, [])
assert.equal(manual.physical_island_links, 0)
const logs = {
normalBuild: "reports/current-normal-build.log",
nativeCheck: "reports/current-check.log",
allLayerGerberShorts: "reports/current-shorts.log",
schematicStyle: "reports/current-schematic-style.log",
typecheck: "reports/current-typecheck.log",
projectedOriginalNetlist: "reports/current-netlist-regression.log",
firmwareSanitizers: "reports/current-firmware-tests.log",
linuxClientTests: "reports/current-host-tests.log",
armFirmwareBuild: "reports/current-firmware-build.log",
linuxModuleTests: "reports/current-module-tests.log",
}
const status = {
status: promotion ? "DEVELOPMENT_LATEST_NOT_FABRICATION_READY" : "LOCAL_CURRENT_SENSING_INTEGRATED_NOT_FABRICATION_RELEASED",
updatedAt: new Date().toISOString(),
previousStableVersion: "0.4.46",
promotion,
fullReview: fullReview ? { path: "reports/full-board-review.json", sha256: hash("reports/full-board-review.json"),
fabricationReady: false, findings: fullReview.findings.length } : null,
pushPerformed: Boolean(draftCheckpoint),
draftCheckpoint: draftCheckpoint ? { version: draftCheckpoint.version, url: draftCheckpoint.url,
filesVerified: draftCheckpoint.filesChecked, mainVersionPreserved: draftCheckpoint.mainVersion,
note: promotion ? "Now promoted to development latest; not a fabrication release." : "Non-latest draft backup only; not a fabrication release or current-edit tracking." } : null,
fabricationReady: false,
emittedCircuit: { path: circuitPath, sha256: circuitSha256 },
replay: { path: "routing/complete-routes.json", sha256: hash("routing/complete-routes.json") },
acceptedManualSession: { path: "routing/current-sense-staging.ses", sha256: manual.session_sha256 },
routingPlacementReference: { path: "routing/placement.json", sha256: manual.circuit_sha256,
caveat: "Routing geometry reference predates final BOM-only substitutions. All final signoff results use emittedCircuit." },
checks: {
nativeErrors: 0,
nativeWarnings: circuit.filter(e => e.type.endsWith("_warning")).length,
baselineNativeWarnings: 175,
failedSourceConnections: 0,
disconnectedTerminalIslands: 0,
allLayerGerberShorts: "pass",
localEmittedCopperPreflightFindings: preflight.length,
kelvinLandRemoval: kelvin,
padEdgeHoleScrewLandFindings: placement.length,
originalElectricalDesign: "220 parts / 209 nets preserved after contracting only the two declared series shunts; R_ETH_SCLK supplier-code correction explicit",
jlcpcb: { populated: stock.populatedComponentCount, uniqueParts: stock.uniquePartCount,
boardQuantity: stock.boardQuantity, issues: 0, checkedAt: stock.checkedAt, reservation: false },
drillClearance: { baselineDeduplicatedFindings: drill.baselineFindings,
currentDeduplicatedFindings: drill.currentFindings, addedFindings: drill.regressionCount,
waived: false },
firmware: { status: "host sanitizer tests, Linux decoder tests and ARM cross-build pass; no hardware flashing",
binary: { path: "firmware/stm32/build/motion.bin", sha256: hash("firmware/stm32/build/motion.bin") },
telemetry: "read-only 0x21 / --current, signed nominal mA, raw ADC, VDDA, flags and age; no heartbeat refresh" },
storedModuleTests: { status: moduleRegression.status, passed: moduleRegression.currentPassed,
failed: moduleRegression.currentFailed, baselineFailed: moduleRegression.baselineFailed,
addedFailures: moduleRegression.addedFailures },
},
logs: Object.fromEntries(Object.entries(logs).map(([name, path]) => [name, { path, sha256: hash(path) }])),
visualReview: { schematic: "11-coil_current.png inspected", pcb: "both face PNGs inspected",
deployedWebsite: promotion ? "Default release/version and 3D cable visually verified, reports/latest-promoted-website.png" : null,
limitations: "Not a fresh cloud AI style analysis or complete enclosure/mechanical qualification." },
pending: [
"Repair inherited drill-to-foreign-copper clearances before fabrication signoff",
"Correct eight inherited passive value/code mismatches and two Ethernet capacitor package mismatches",
"Coordinate the 25 V motor bulk capacitor with the 35.5 V TVS clamp envelope",
"Resolve the additional SMD-pad gaps, silkscreen and high-speed/analog routing concerns",
"Repair fabrication export gates and regenerate a complete hash-matched 193-part manufacturing handoff only after signoff",
"Review 187 native warnings (175 baseline); zero error records does not mean zero warnings",
"Resolve 26 stored-module/profile test failures also reproduced on untouched published runtime",
"First-article current offset/gain and PWM/noise characterization; telemetry is not RMS or a protection loop",
"Physical rear motor fastening, harness and thermal/power bring-up qualification",
promotion ? "Development latest promoted; still no fabrication release" : "Only a non-latest draft backup has been published; no fabrication release",
],
}
fs.writeFileSync("reports/current-sense-status.json", JSON.stringify(status, null, 2) + "\n")
console.log(JSON.stringify({ status: status.status, sourceFailures: 0, openTerminalIslands: 0,
fabricationReady: false, inheritedDrillFindings: drill.currentFindings }))