abse/boostxl-ads7841-q1
The ADS7841ESQDBQRQ1 is a 16-pin touchscreen controller IC with voltage, ground, communication, and mode control pins designed for interfacing with touch sensors.
- Version
- 1.0.6
- License
- unset
- Stars
- 0
scripts/verify-release.mjs
import { existsSync, readFileSync } from "node:fs"
import { dirname, join } from "node:path"
import { fileURLToPath } from "node:url"
const root = join(dirname(fileURLToPath(import.meta.url)), "..")
const sourcePath = join(root, "index.circuit.tsx")
const circuitPath = join(root, "dist/index/circuit.json")
const guidePath = join(root, "reference/ti/BOOSTXL-ADS7841-Q1-user-guide-SNAU229.pdf")
const failures = []
const requireCheck = (condition, message) => {
if (!condition) failures.push(message)
}
requireCheck(existsSync(circuitPath), "dist/index/circuit.json is missing; run bun run build")
requireCheck(existsSync(guidePath), "official TI SNAU229 reference PDF is missing")
if (!existsSync(circuitPath)) {
console.error(failures.join("\n"))
process.exit(1)
}
const source = readFileSync(sourcePath, "utf8")
const circuit = JSON.parse(readFileSync(circuitPath, "utf8"))
const elements = (type) => circuit.filter((element) => element.type === type)
const components = elements("source_component")
const componentByName = new Map(components.map((component) => [component.name, component]))
const pcbBySourceId = new Map(elements("pcb_component").map((component) => [component.source_component_id, component]))
const expectedRefs = [
...Array.from({ length: 30 }, (_, index) => `C${index + 1}`),
...Array.from({ length: 36 }, (_, index) => `R${index + 1}`),
...Array.from({ length: 9 }, (_, index) => `U${index + 1}`),
...Array.from({ length: 13 }, (_, index) => `TP${index + 1}`),
"J1J3", "J2J4", "J5", "J6", "J7", "J8", "J9", "J10", "J11", "J12", "J13", "J14", "J15",
]
for (const ref of expectedRefs) requireCheck(componentByName.has(ref), `missing reference ${ref}`)
const names = components.map((component) => component.name)
requireCheck(new Set(names).size === names.length, "duplicate source-component reference designator")
const board = elements("pcb_board")[0]
requireCheck(board?.num_layers === 4, "board must have four copper layers")
requireCheck(board?.width === 63.5 && board?.height === 44.45, "board must retain the TI 63.5 mm × 44.45 mm outline")
requireCheck(board?.min_via_hole_diameter === 0.3, "minimum via hole must be 0.3 mm")
requireCheck(board?.min_via_pad_diameter === 0.45, "minimum via pad must be 0.45 mm")
requireCheck(elements("pcb_copper_pour").some((pour) => pour.layer === "bottom"), "bottom copper pour is missing")
const holes = elements("pcb_hole")
requireCheck(holes.length === 3, "TI board must have exactly three mechanical mounting holes")
const expectedHoleCenters = [[-26.1, 19.5], [28.9, 19.5], [-26.1, -19.5]]
for (const [x, y] of expectedHoleCenters) {
requireCheck(holes.some((hole) => hole.x === x && hole.y === y && hole.hole_diameter === 3.2), `missing TI mounting hole at (${x}, ${y})`)
}
const expectedSheets = [
"ADS7841 Power Supply",
"ADS7841 LaunchPad and EEPROM",
"ADS7841 SPI Level Translation",
"ADS7841 Analog Input Buffers",
"ADS7841 ADC and Voltage Reference",
]
const sheetNames = elements("schematic_sheet").map((sheet) => sheet.name)
requireCheck(JSON.stringify(sheetNames) === JSON.stringify(expectedSheets), "schematic must retain the five reviewed functional sheets")
const drcErrors = circuit.filter((element) => element.type.endsWith("_error"))
requireCheck(drcErrors.length === 0, `generated circuit contains ${drcErrors.length} DRC/error objects`)
requireCheck(elements("schematic_element_outside_sheet_warning").length === 0, "schematic contains elements outside a drawing sheet")
requireCheck(elements("pcb_trace").length >= 200, "routed board unexpectedly contains fewer than 200 PCB traces")
requireCheck(elements("pcb_via").length > 0, "routed board unexpectedly contains no vias")
requireCheck(!source.includes("<netlabel"), "explicit <netlabel> is forbidden")
requireCheck(!source.includes("<schematicrect"), "overlapping schematic region boxes must not return")
requireCheck(source.includes('minViaHoleDiameter="0.3mm"'), "source via-hole rule is missing")
requireCheck(source.includes('minViaPadDiameter="0.45mm"'), "source via-pad rule is missing")
const dnpRefs = ["C8", "C12", "C18", "C22", "C28", "J6", "J7", "J9", "J11", "J14", "R18", "R27", "R29", "R34"]
for (const ref of dnpRefs) {
const component = componentByName.get(ref)
const pcb = component && pcbBySourceId.get(component.source_component_id)
requireCheck(pcb?.do_not_place === true, `${ref} must remain DNP`)
}
for (const component of components) {
if (/^[CR]/.test(component.name)) {
requireCheck(component.supplier_part_numbers?.jlcpcb?.length > 0, `${component.name} lacks JLCPCB/LCSC sourcing`)
}
if (/^(U|J)/.test(component.name)) {
requireCheck(component.supplier_part_numbers?.jlcpcb?.length > 0, `${component.name} lacks imported JLCPCB/LCSC sourcing`)
}
}
requireCheck(componentByName.get("U1")?.manufacturer_part_number === "REG71055IDDCRQ1", "U1 must use TI BOM REG71055IDDCRQ1")
requireCheck(componentByName.get("U1")?.supplier_part_numbers?.jlcpcb?.includes("C2071120"), "U1 JLCPCB source C2071120 is missing")
requireCheck(componentByName.get("U2")?.manufacturer_part_number === "TPS79901QDRVRQ1", "U2 must use TI BOM TPS79901QDRVRQ1")
requireCheck(componentByName.get("U2")?.supplier_part_numbers?.jlcpcb?.includes("C398922"), "U2 JLCPCB source C398922 is missing")
requireCheck(componentByName.get("U4")?.manufacturer_part_number === "BR24G32FVT-3AGE2", "U4 must use TI BOM BR24G32FVT-3AGE2")
requireCheck(componentByName.get("J10")?.manufacturer_part_number === "TSW-103-07-G-D", "J10 must use TI BOM TSW-103-07-G-D")
requireCheck(componentByName.get("J15")?.manufacturer_part_number === "PEC02DAAN", "J15 must use TI BOM PEC02DAAN")
for (const ref of ["J7", "J11"]) requireCheck(componentByName.get(ref)?.manufacturer_part_number === "5-1814832-1", `${ref} must use TI BOM SMA 5-1814832-1`)
requireCheck(source.includes("connections={{ pin1: N.VDD, pin2: N.LDO_FB, pin3: N.GND, pin4: N.V55, pin5: N.LDO_NR, pin6: N.V55, pin7: N.GND }}"), "U2 adjustable WSON pin mapping changed")
requireCheck(source.includes('connections={{ pin1: N.VDD, pin2: N.VREF, pin3: N.VREF45_RAW }}'), "J13 voltage-reference selector mapping changed")
requireCheck(source.includes('connections={{ pin1: N.VREF45_RAW, pin2: N.VREF45_FILTERED }}'), "R31 reference-filter mapping changed")
requireCheck(source.includes('connections={{ pin1: N.VREF45_FILTERED, pin2: N.GND }}'), "C30 reference-filter mapping changed")
const expectedResistance = { R2: 10, R4: 100000, R11: 31600, R13: 1000, R20: 0, R23: 49.9, R30: 100, R35: 68100, R36: 100000 }
for (const [ref, resistance] of Object.entries(expectedResistance)) {
requireCheck(componentByName.get(ref)?.resistance === resistance, `${ref} resistance does not match TI BOM`)
}
if (failures.length) {
console.error(`Release audit failed (${failures.length}):`)
for (const failure of failures) console.error(`- ${failure}`)
process.exit(1)
}
console.log("Electrical release audit passed with all populated non-passives sourced through JLCPCB/LCSC")