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:
parent
bcfa5dd7f0
commit
d51c9f1011
5 changed files with 108 additions and 1 deletions
|
|
@ -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 && \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
kicad \
|
||||
kicad-symbols \
|
||||
kicad-footprints \
|
||||
ngspice \
|
||||
python3 python3-pip python3-venv \
|
||||
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
|
||||
CMD ["bash"]
|
||||
|
|
|
|||
56
hardware/eda/sim/stage1_cmrr.cir
Normal file
56
hardware/eda/sim/stage1_cmrr.cir
Normal 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
|
||||
39
hardware/eda/sim/stage1_phantom.cir
Normal file
39
hardware/eda/sim/stage1_phantom.cir
Normal 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
|
||||
0
hardware/kicad/skidl_REPL.erc
Normal file
0
hardware/kicad/skidl_REPL.erc
Normal file
9
hardware/kicad/skidl_REPL.log
Normal file
9
hardware/kicad/skidl_REPL.log
Normal 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.
|
||||
Loading…
Reference in a new issue