diff --git a/03-Architecture-Hardware/kicad b/03-Architecture-Hardware/kicad index 61652cc..d2db77f 160000 --- a/03-Architecture-Hardware/kicad +++ b/03-Architecture-Hardware/kicad @@ -1 +1 @@ -Subproject commit 61652ccc3f92403e89a01f0ba88660caeaed6be3 +Subproject commit d2db77fddb14c07e406171c4d228b5f938f099ce diff --git a/scripts/2026-09-25_v6_T17_f2_input_fuse.py b/scripts/2026-09-25_v6_T17_f2_input_fuse.py new file mode 100644 index 0000000..32521ab --- /dev/null +++ b/scripts/2026-09-25_v6_T17_f2_input_fuse.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +"""v6 T17 — F2 (24 V vehicle input fuse) gets a real, orderable part. + +F2 carried the placeholder "TBD-2A-1812" (value "2A/63V-slow-1812"). The JLC catalogue has +no 1812 fuse that is both 2 A time-lag and rated >= 63 V (1812 PPTCs top out at 33–36 V, +below what the SMBJ33A on /24V_IN lets through during a load dump). +Chosen: Littelfuse 0454002.MR — NANO2 Slo-Blo, 2 A, 125 V, 50 A breaking, 2410 body. +LCSC C179005 (Extended, 1136 in stock on 25-Sep). + +Schematic: Value, Footprint (Fuse:Fuse_Littelfuse-NANO2-451_453 — same NANO2 land as the +454 series; verify against the 0454 datasheet) and LCSC. +Board: LCSC value + Value only. The footprint swap (1812 -> NANO2, 6.1 x 2.7 mm) is a layout +step: in the PCB editor, right-click F2 -> Change Footprint -> Fuse:Fuse_Littelfuse-NANO2-451_453. + + python3 T17.py hbox-watchdog-v6.kicad_sch hbox-watchdog-v6.kicad_pcb [--apply] +""" +import re, sys, shutil + +REF = 'F2' +NEW = {'Value': '2A/125V-SloBlo-NANO2', 'LCSC': 'C179005', + 'Footprint': 'Fuse:Fuse_Littelfuse-NANO2-451_453'} +OLD_LCSC = 'TBD-2A-1812' + +def span(s, i): + d = 0; instr = False; j = i + while True: + c = s[j] + if c == '"' and s[j-1] != '\\': instr = not instr + elif not instr: + if c == '(': d += 1 + elif c == ')': + d -= 1 + if d == 0: return j + 1 + j += 1 + +def edit(s, head, props, ch, tag): + m = re.search(r'\n\t\t\(property "Reference" "%s"\n' % REF, s) + a = s.rfind('\n\t(' + head, 0, m.start()) + 1; e = span(s, a); b = s[a:e] + for k, v in props.items(): + pm = re.search(r'\n\t\t\(property "%s" "([^"]*)"' % k, b) + if not pm: raise SystemExit(f'{tag}: {REF} has no {k} property') + if pm.group(1) == v: continue + if k == 'LCSC' and pm.group(1) not in (OLD_LCSC, ''): raise SystemExit(f'{tag}: unexpected LCSC {pm.group(1)}') + b = b[:pm.start()] + f'\n\t\t(property "{k}" "{v}"' + b[pm.end():] + ch.append(f'{tag} {REF}: {k} "{pm.group(1)}" -> "{v}"') + return s[:a] + b + s[e:] + +def main(): + sch, pcb = sys.argv[1], sys.argv[2]; apply = '--apply' in sys.argv + S0 = open(sch).read(); P0 = open(pcb).read(); ch = [] + S = edit(S0, 'symbol', NEW, ch, 'sch') + P = edit(P0, 'footprint', {'Value': NEW['Value'], 'LCSC': NEW['LCSC']}, ch, 'pcb') + for t in (S, P): + u = re.sub(r'"(?:[^"\\]|\\.)*"', '', t); assert u.count('(') == u.count(')') + print('\n'.join(ch) or 'nothing to do (already applied)') + if ch and apply: + for f, t in ((sch, S), (pcb, P)): + shutil.copy2(f, f + '.T17bak'); open(f, 'w').write(t) + print('APPLIED (backups .T17bak)') + elif ch: + print('DRY RUN — re-run with --apply') + +if __name__ == '__main__': + main()