#!/usr/bin/env python3 """ ESP32-S3 Sensor Node — Specctra DSN Generator v2 Uses exact format from known-working DSN file. """ import os PROJ = os.path.expanduser("~/Documents/KiCad/10.0/esp32-s3-sensor-node") TEMPLATE = os.path.expanduser("~/Documents/KiCad/10.0/USB_PD_ESP32S3/freerouting.dsn") def gen(): templ = open(TEMPLATE).read() # Replace key sections # 1. Board outline templ = templ.replace( '(rect 0 0 100000 80000)', '(rect 0 0 65000 40000)' ) # 2. Keepout zones (after GND layer) # Find the end of layer definitions and add keepout keepout_section = ''' (place_rule (F.Cu (clearance 200))) (place_rule (B.Cu (clearance 200))) (rule (clearance 150)) (rule "3V3" (clearance 250)) (rule "VBUS" (clearance 250)) (rule "USB_D_P" (clearance 150)) (rule "USB_D_N" (clearance 150)) (keepout F.Cu (rect 46000 28000 65000 40000)) (keepout B.Cu (rect 46000 28000 65000 40000)) )''' # Find structure closing struct_end = templ.find('\n )\n', templ.find('(structure')) if struct_end > 0: templ = templ[:struct_end] + keepout_section + templ[struct_end:] # 3. Replace nets nets_section = gen_nets() net_start = templ.find('(network\n') net_end = templ.find('\n)', net_start) + 2 if net_start > 0: templ = templ[:net_start] + nets_section + templ[net_end:] # Write dsn = os.path.join(PROJ, "esp32-s3-sensor-node.dsn") open(dsn, 'w').write(templ) print(f"Written: {dsn} ({len(templ)} bytes)") NETS = { "GND": ["J1-SH","J1-A1","J1-B1","U2-1","U1-1","U1-16","U1-40", "C1-2","C2-2","C3-2","C4-2","C5-2","C6-2", "D1-1","R4-2","R7-2","R8-2","J2-4","J3-1"], "3V3": ["U2-2","U1-2","C1-1","C2-1","C3-1","C6-1", "R2-2","R3-2","R5-2","R6-2","J2-1","J3-4"], "VBUS": ["J1-A4","J1-B4","U2-3","C5-1"], "EN": ["U1-3","R2-1","C4-1"], "IO0": ["U1-27","R3-1"], "IO12": ["U1-20","R4-1"], "SDA": ["U1-4","R5-1","J2-2"], "SCL": ["U1-5","R6-1","J2-3"], "USB_D_P": ["J1-A6","J1-B6","U1-14"], "USB_D_N": ["J1-A7","J1-B7","U1-13"], "CC1": ["J1-A5","R7-1"], "CC2": ["J1-B5","R8-1"], "IO2_LED": ["U1-38","R1-1"], "D1_A": ["R1-2","D1-2"], "RXD0": ["U1-36","J3-2"], "TXD0": ["U1-37","J3-3"], } def gen_nets(): lines = ['(network'] for name, pins in NETS.items(): lines.append(f' (net "{name}"') for pin in pins: ref, pn = pin.split('-') lines.append(f' (pin {ref} {pn})') lines.append(f' )') lines.append(')') return '\n'.join(lines) if __name__ == "__main__": gen()