diff --git a/hardware/eda/Containerfile b/hardware/eda/Containerfile index 15d4933..7e8958a 100644 --- a/hardware/eda/Containerfile +++ b/hardware/eda/Containerfile @@ -27,5 +27,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ apt-get clean && rm -rf /var/lib/apt/lists/* && \ pip3 install --no-cache-dir --break-system-packages skidl +# Point SKiDL / KiCad CLI at the installed libraries (reproducible, not ad-hoc). +ENV KICAD9_SYMBOL_DIR=/usr/share/kicad/symbols \ + KICAD9_FOOTPRINT_DIR=/usr/share/kicad/footprints \ + KICAD_SYMBOL_DIR=/usr/share/kicad/symbols + WORKDIR /work CMD ["bash"] diff --git a/hardware/eda/circuits/stage1_input.py b/hardware/eda/circuits/stage1_input.py new file mode 100644 index 0000000..c7bc5a6 --- /dev/null +++ b/hardware/eda/circuits/stage1_input.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +"""PM_K-1 audio chain - Stage 1: balanced LINE input receiver + protection (SKiDL). + +Code-defined schematic. Run INSIDE the EDA container: + cd hardware/eda && ./run.sh python3 ../eda/circuits/stage1_input.py +Outputs ERC results + a KiCad netlist at hardware/kicad/stage1_input.net, +which imports into Pcbnew for layout. + +VERIFY-BEFORE-LAYOUT (datasheet items -- flagged, not guessed): + * exact THAT line-receiver suffix for the gain we want (1240/1243/1246 differ) + * the receiver's SO-8 pin NUMBERS (function->pin map below is placeholder) + * clamp-diode part choice + pin orientation +The TOPOLOGY/connectivity below is correct; only these pin-level details need +confirming against the datasheet. +""" +import os +from skidl import * + +set_default_tool(KICAD9) + +# ---------- passive templates ---------- +R = Part("Device", "R", dest=TEMPLATE, footprint="Resistor_SMD:R_0805_2012Metric") +C = Part("Device", "C", dest=TEMPLATE, footprint="Capacitor_SMD:C_0805_2012Metric") +D = Part("Device", "D", dest=TEMPLATE, footprint="Diode_SMD:D_SOD-323") + +# ---------- power rails (global nets; marked POWER-driven for ERC) ---------- +# No power-flag *symbols* -- they carry no footprint and SKiDL errors on that. +# The rails arrive from the power block; here we just declare + drive them. +p15, n15, gnd = Net("+15V"), Net("-15V"), Net("GND") +for n in (p15, n15, gnd): + n.drive = POWER + +# ---------- balanced line receiver (THAT124x) : PINOUT TODO-VERIFY ---------- +RX = Part(name="THAT124x_RX", tool=SKIDL, dest=TEMPLATE, ref_prefix="U", + footprint="Package_SO:SOIC-8_3.9x4.9mm_P1.27mm", + pins=[ + Pin(num=1, name="IN-", func=Pin.types.INPUT), + Pin(num=2, name="REF", func=Pin.types.INPUT), + Pin(num=3, name="OUT", func=Pin.types.OUTPUT), + Pin(num=4, name="V-", func=Pin.types.PWRIN), + Pin(num=5, name="V+", func=Pin.types.PWRIN), + Pin(num=6, name="SENSE", func=Pin.types.INPUT), + Pin(num=7, name="IN+", func=Pin.types.INPUT), + Pin(num=8, name="NC", func=Pin.types.NOCONNECT), + ]) +rx = RX(ref="U1") + +# ---------- nets ---------- +ain_hot, ain_cold, rxout = Net("AIN_HOT"), Net("AIN_COLD"), Net("RX_OUT") + +def protected_input(src, node_name): + """series DC-block cap (blocks +48V phantom) -> series R -> node; + bias R to gnd; clamp diodes to the +/-15V rails (orientation TODO-VERIFY).""" + cblk = C(value="2.2uF", footprint="Capacitor_SMD:C_1206_3216Metric") # film + rs, rb = R(value="1k"), R(value="1Meg") + dp, dn = D(value="1N4148WS"), D(value="1N4148WS") + node = Net(node_name) + src += cblk[1]; cblk[2] += rs[1]; rs[2] += node + rb[1] += node; rb[2] += gnd + dp[2] += p15; node += dp[1] # clamp high to +15 + dn[1] += n15; dn[2] += node # clamp low to -15 (avoid rebinding globals) + return node + +rx["IN+"] += protected_input(ain_hot, "RXIN_P") +rx["IN-"] += protected_input(ain_cold, "RXIN_N") +rx["REF"] += gnd +rx["SENSE"] += rxout # sense tied to output (local feedback) +rx["OUT"] += rxout +rx["V+"] += p15 +rx["V-"] += n15 + +# supply decoupling at the receiver +for rail in (p15, n15): + c = C(value="100nF") + rail += c[1]; c[2] += gnd + +ERC() +out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "stage1_input.net")) +generate_netlist(file_=out) +print("Stage 1 netlist ->", out) diff --git a/hardware/kicad/.gitignore b/hardware/kicad/.gitignore index aa9de50..2bcc1eb 100644 --- a/hardware/kicad/.gitignore +++ b/hardware/kicad/.gitignore @@ -7,3 +7,4 @@ *.kicad_prl fp-info-cache ~*.lck +*.net diff --git a/hardware/kicad/skidl.erc b/hardware/kicad/skidl.erc new file mode 100644 index 0000000..e69de29 diff --git a/hardware/kicad/skidl.log b/hardware/kicad/skidl.log new file mode 100644 index 0000000..f3ccbc7 --- /dev/null +++ b/hardware/kicad/skidl.log @@ -0,0 +1,9 @@ +WARNING: KICAD8_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD6_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD9_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD7_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. diff --git a/hardware/kicad/stage1_input.erc b/hardware/kicad/stage1_input.erc new file mode 100644 index 0000000..ee1724d --- /dev/null +++ b/hardware/kicad/stage1_input.erc @@ -0,0 +1,5 @@ +ERC WARNING: Only one pin (PASSIVE pin 1/~ of C/C1) attached to net AIN_HOT. +ERC WARNING: Only one pin (PASSIVE pin 1/~ of C/C2) attached to net AIN_COLD. +ERC INFO: 2 warnings found while running ERC. +ERC INFO: 0 errors found while running ERC. + diff --git a/hardware/kicad/stage1_input.log b/hardware/kicad/stage1_input.log new file mode 100644 index 0000000..c6ab3e5 --- /dev/null +++ b/hardware/kicad/stage1_input.log @@ -0,0 +1,37 @@ +WARNING: KICAD8_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD6_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: KICAD7_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/:995=>/work/hardware/kicad/:488] +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: fp-lib-table file was not found. Component footprints are not available. +WARNING: Missing tag on THAT124x_RX instantiated at /work/hardware/eda/circuits/stage1_input.py:46. +WARNING: Random tag NiUcdSBKvZ generated for THAT124x_RX. +WARNING: Missing tag on C instantiated at /work/hardware/eda/circuits/stage1_input.py:54. +WARNING: Random tag UDuxvr_uTL generated for C. +WARNING: Missing tag on R instantiated at /work/hardware/eda/circuits/stage1_input.py:55. +WARNING: Random tag _Np5DvK_aE generated for R. +WARNING: Missing tag on R instantiated at /work/hardware/eda/circuits/stage1_input.py:55. +WARNING: Random tag 7TLEUp_48E generated for R. +WARNING: Missing tag on D instantiated at /work/hardware/eda/circuits/stage1_input.py:56. +WARNING: Random tag e2BBosboqS generated for D. +WARNING: Missing tag on D instantiated at /work/hardware/eda/circuits/stage1_input.py:56. +WARNING: Random tag ngnho2nWKf generated for D. +WARNING: Missing tag on C instantiated at /work/hardware/eda/circuits/stage1_input.py:54. +WARNING: Random tag WXfeI7Gfj2 generated for C. +WARNING: Missing tag on R instantiated at /work/hardware/eda/circuits/stage1_input.py:55. +WARNING: Random tag jKB97sf61u generated for R. +WARNING: Missing tag on R instantiated at /work/hardware/eda/circuits/stage1_input.py:55. +WARNING: Random tag mXEcsSvVUJ generated for R. +WARNING: Missing tag on D instantiated at /work/hardware/eda/circuits/stage1_input.py:56. +WARNING: Random tag aEBPrkC6b9 generated for D. +WARNING: Missing tag on D instantiated at /work/hardware/eda/circuits/stage1_input.py:56. +WARNING: Random tag vSi9f4M7Zg generated for D. +WARNING: Missing tag on C instantiated at /work/hardware/eda/circuits/stage1_input.py:74. +WARNING: Random tag I5Ulz7qVtA generated for C. +WARNING: Missing tag on C instantiated at /work/hardware/eda/circuits/stage1_input.py:74. +WARNING: Random tag clPAosAbcJ generated for C. +WARNING: Missing tag on instantiated at /work/hardware/kicad/:488. +INFO: 31 warnings found while generating netlist. +INFO: 0 errors found while generating netlist. + diff --git a/hardware/kicad/stage1_input_sklib.py b/hardware/kicad/stage1_input_sklib.py new file mode 100644 index 0000000..a9ed94a --- /dev/null +++ b/hardware/kicad/stage1_input_sklib.py @@ -0,0 +1,26 @@ +from collections import defaultdict +from skidl import Pin, Part, Alias, SchLib, SKIDL, TEMPLATE + +from skidl.pin import pin_types + +SKIDL_lib_version = '0.0.1' + +stage1_input = SchLib(tool=SKIDL).add_parts(*[ + Part(**{ 'name':'THAT124x_RX', 'dest':TEMPLATE, 'tool':SKIDL, 'aliases':Alias({'THAT124x_RX'}), 'ref_prefix':'U', 'fplist':None, 'footprint':'Package_SO:SOIC-8_3.9x4.9mm_P1.27mm', 'keywords':None, 'description':'', 'datasheet':None, 'pins':[ + Pin(num='1',name='IN-',func=pin_types.INPUT), + Pin(num='2',name='REF',func=pin_types.INPUT), + Pin(num='3',name='OUT',func=pin_types.OUTPUT), + Pin(num='4',name='V-',func=pin_types.PWRIN), + Pin(num='5',name='V+',func=pin_types.PWRIN), + Pin(num='6',name='SENSE',func=pin_types.INPUT), + Pin(num='7',name='IN+',func=pin_types.INPUT), + Pin(num='8',name='NC',func=pin_types.NOCONNECT)] }), + Part(**{ 'name':'C', 'dest':TEMPLATE, 'tool':SKIDL, 'aliases':Alias({'C'}), 'ref_prefix':'C', 'fplist':[''], 'footprint':'Capacitor_SMD:C_1206_3216Metric', 'keywords':'cap capacitor', 'description':'Unpolarized capacitor', 'datasheet':'~', 'pins':[ + Pin(num='1',name='~',func=pin_types.PASSIVE,unit=1), + Pin(num='2',name='~',func=pin_types.PASSIVE,unit=1)], 'unit_defs':[] }), + Part(**{ 'name':'R', 'dest':TEMPLATE, 'tool':SKIDL, 'aliases':Alias({'R'}), 'ref_prefix':'R', 'fplist':[''], 'footprint':'Resistor_SMD:R_0805_2012Metric', 'keywords':'R res resistor', 'description':'Resistor', 'datasheet':'~', 'pins':[ + Pin(num='1',name='~',func=pin_types.PASSIVE,unit=1), + Pin(num='2',name='~',func=pin_types.PASSIVE,unit=1)], 'unit_defs':[] }), + Part(**{ 'name':'D', 'dest':TEMPLATE, 'tool':SKIDL, 'aliases':Alias({'D'}), 'ref_prefix':'D', 'fplist':[''], 'footprint':'Diode_SMD:D_SOD-323', 'keywords':'diode', 'description':'Diode', 'datasheet':'~', 'pins':[ + Pin(num='1',name='K',func=pin_types.PASSIVE,unit=1), + Pin(num='2',name='A',func=pin_types.PASSIVE,unit=1)], 'unit_defs':[] })]) \ No newline at end of file