PM_K-1 hardware: Stage 1 audio (input receiver) sims + container libs

Audio chain, stage 1 (balanced input receiver + protection) validated in ngspice:
- stage1_cmrr.cir: CMRR vs resistor matching -> 1% = 46dB, 0.1% = 66dB, perfect
  = amp-limited; justifies the laser-trimmed THAT1240 over discrete resistors.
- stage1_phantom.cir: +48V phantom step -> clamped to ~16V blip, steady-state
  ~0.12V; the DC-block cap + clamp + series R make a miswire a non-event.

Container: add kicad-symbols + kicad-footprints (for symbol placement) and skidl.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-30 19:27:25 -05:00
parent bcfa5dd7f0
commit d51c9f1011
5 changed files with 108 additions and 1 deletions

View file

@ -19,10 +19,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
add-apt-repository -y ppa:kicad/kicad-9.0-releases && \ add-apt-repository -y ppa:kicad/kicad-9.0-releases && \
apt-get update && apt-get install -y --no-install-recommends \ apt-get update && apt-get install -y --no-install-recommends \
kicad \ kicad \
kicad-symbols \
kicad-footprints \
ngspice \ ngspice \
python3 python3-pip python3-venv \ python3 python3-pip python3-venv \
git make && \ git make && \
apt-get clean && rm -rf /var/lib/apt/lists/* apt-get clean && rm -rf /var/lib/apt/lists/* && \
pip3 install --no-cache-dir --break-system-packages skidl
WORKDIR /work WORKDIR /work
CMD ["bash"] CMD ["bash"]

View file

@ -0,0 +1,56 @@
* PM_K-1 Stage 1 : balanced line receiver -- why CMRR needs matched resistors
*
* A balanced receiver rejects "common-mode" noise -- hum/interference that appears
* equally on both signal wires -- by SUBTRACTING the two wires. How well it cancels
* (its Common-Mode Rejection Ratio, CMRR) depends entirely on how well its four
* resistors match. This is the circuit-level reason we chose the laser-trimmed
* THAT1240 instead of a discrete op-amp + four 1% resistors.
*
* Three identical unity-gain difference amplifiers, driven common-mode (same 1V on
* both inputs), with 0% / 0.1% / 1% mismatch on one resistor.
* CMRR(dB) = -20*log10(|Vout|) since differential gain = 1 and Vcm = 1V.
*
* Run: ngspice -b ../eda/sim/stage1_cmrr.cir
.title Stage1 line receiver CMRR vs resistor match
Vcm cm 0 AC 1 ; common-mode drive: both inputs tied to cm
* ---- A: perfectly matched ----
EA outa 0 vpa vma 1e6
R1a cm vma 10k
R2a outa vma 10k
R3a cm vpa 10k
R4a vpa 0 10k
* ---- B: 0.1% mismatch on one resistor ----
EB outb 0 vpb vmb 1e6
R1b cm vmb 10k
R2b outb vmb 10k
R3b cm vpb 10k
R4b vpb 0 10.01k
* ---- C: 1% mismatch on one resistor ----
EC outc 0 vpc vmc 1e6
R1c cm vmc 10k
R2c outc vmc 10k
R3c cm vpc 10k
R4c vpc 0 10.1k
.ac dec 10 100 10k
.control
run
meas ac acm_a find vm(outa) at=1000
meas ac acm_b find vm(outb) at=1000
meas ac acm_c find vm(outc) at=1000
let cmrr_a = -20*log10(acm_a)
let cmrr_b = -20*log10(acm_b)
let cmrr_c = -20*log10(acm_c)
echo
echo " CMRR perfect match : $&cmrr_a dB (limited only by the amplifier)"
echo " CMRR 0.1% mismatch : $&cmrr_b dB"
echo " CMRR 1% mismatch : $&cmrr_c dB"
echo " -> hand-matched 1% resistors give poor rejection; the THAT1240's"
echo " laser-trimmed internal resistors are how we get >90 dB for free."
.endc
.end

View file

@ -0,0 +1,39 @@
* PM_K-1 Stage 1 : input protection -- a +48V phantom-power step at the jack
*
* "Phantom power" is +48V DC that mixers put on their MIC inputs. If it ever reaches
* our input (miswire, wrong cable, our OUT plugged into a phantom'd input), a bare
* op-amp input would die. Our protection makes it a non-event:
* - a series DC-BLOCKING film cap passes audio (AC) but blocks the +48V (DC),
* - a series resistor + clamp diodes to the +/-15V rails survive the turn-on EDGE
* (the cap passes the fast step before it charges).
*
* We hit the input with a +48V step at t=1ms and watch the OP-AMP INPUT node.
*
* Run: ngspice -b ../eda/sim/stage1_phantom.cir
.title Stage1 phantom protection
Vin in 0 PWL(0 0 1m 0 1.001m 48 5 48) ; +48V appears at t=1ms, stays
C1 in a 1u ; DC-blocking film cap (audio passes, DC blocked)
Rs a n 1k ; series current limit
Rb n 0 1meg ; bias / input impedance (audio high-pass corner ~0.16 Hz)
.model Dclamp D(Is=1e-14 N=1 Rs=10)
Dp n vp Dclamp ; clamp to +15
Dn vn n Dclamp ; clamp to -15
Vp vp 0 15
Vn vn 0 -15
.tran 2m 5
.control
run
meas tran vn_peak max v(n) from=1m to=5
meas tran vn_final find v(n) at=4.9
echo
echo " op-amp input PEAK during the +48V step : $&vn_peak V (clamped near a +/-15 rail)"
echo " op-amp input STEADY-STATE : $&vn_final V (DC blocked by the cap)"
echo " -> +48V at the jack becomes a clamped blip that decays to ~0. Nothing is harmed;"
echo " a wrong patch only ever sounds wrong. (Audio passes -- the high-pass is ~0.16 Hz.)"
.endc
.end

View file

View file

@ -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/<frozen importlib._bootstrap_external>:995=>/work/hardware/kicad/<frozen importlib._bootstrap>:488]
WARNING: KICAD6_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/<frozen importlib._bootstrap_external>:995=>/work/hardware/kicad/<frozen importlib._bootstrap>:488]
WARNING: KICAD9_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/<frozen importlib._bootstrap_external>:995=>/work/hardware/kicad/<frozen importlib._bootstrap>:488]
WARNING: KICAD_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/<frozen importlib._bootstrap_external>:995=>/work/hardware/kicad/<frozen importlib._bootstrap>:488]
WARNING: KICAD7_SYMBOL_DIR environment variable is missing, so the default KiCad symbol libraries won't be searched. @ [/work/hardware/kicad/<frozen importlib._bootstrap_external>:995=>/work/hardware/kicad/<frozen importlib._bootstrap>: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.