indicator.py: peak-detect (Schottky+RC) on STAGE1_OUT (signal-present) and MIX_OUT (clip) -> LM393 (powered from +15V) vs tunable threshold dividers -> open-collector outputs pulled to +3V3 = SIG_LED/CLIP_LED (drive face LEDs + read on GPIO19/20). speaker.py: PAM8302A filterless class-D (pinout verified, Diodes SO-8) fed from MIX_OUT (single-ended, RIN=68k -> ~+5.7dB), SD pulled high, BTL out -> SPK_P/SPK_N. Both ERC 0 errors; netlists 0 errors. Threshold/gain values tunable; DNP per form factor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
51 lines
2.5 KiB
Python
51 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""PM_K-1 monitor speaker amp (SKiDL): PAM8302A class-D -> SPK_P/SPK_N. DNP/optional.
|
|
|
|
Run INSIDE the EDA container:
|
|
cd hardware/eda && ./run.sh python3 ../eda/circuits/speaker.py
|
|
Outputs ERC + hardware/kicad/speaker.net.
|
|
|
|
Filterless 2.5W mono class-D for a built-in monitor (populated only on form factors that
|
|
want one). Fed from MIX_OUT (the mixed click+input, single-ended into IN+; IN- AC-coupled
|
|
to GND). Gain = 20*log(150k/(10k+RIN)); RIN=68k -> ~+5.7dB. SD pulled high = enabled
|
|
(route SPK_SD to a GPIO if software shutdown is wanted). Output is BTL (filterless) to the
|
|
speaker via the analog interconnect.
|
|
|
|
PAM8302A SO-8 pinout (Diodes, verified): 1=SD 2=NC 3=IN+ 4=IN- 5=VO+ 6=VDD 7=GND 8=VO-.
|
|
"""
|
|
import os
|
|
from skidl import *
|
|
set_default_tool(KICAD9)
|
|
P = Pin.types
|
|
R = Part("Device","R", dest=TEMPLATE, footprint="Resistor_SMD:R_0402_1005Metric")
|
|
def C(v, fp="Capacitor_SMD:C_0402_1005Metric"): return Part("Device","C", value=v, footprint=fp)
|
|
|
|
p5, p3v3, gnd = Net("+5V"), Net("+3V3"), Net("GND")
|
|
for n in (p5, p3v3): n.drive = POWER
|
|
gnd.drive = POWER
|
|
mix_out, spk_p, spk_n, spk_sd = Net("MIX_OUT"), Net("SPK_P"), Net("SPK_N"), Net("SPK_SD")
|
|
|
|
PAM = Part(name="PAM8302A", tool=SKIDL, dest=TEMPLATE, ref_prefix="U",
|
|
footprint="Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",
|
|
pins=[Pin(num=1,name="SD",func=P.INPUT),Pin(num=2,name="NC",func=P.NOCONNECT),Pin(num=3,name="IN+",func=P.INPUT),
|
|
Pin(num=4,name="IN-",func=P.INPUT),Pin(num=5,name="VO+",func=P.OUTPUT),Pin(num=6,name="VDD",func=P.PWRIN),
|
|
Pin(num=7,name="GND",func=P.PWRIN),Pin(num=8,name="VO-",func=P.OUTPUT)])
|
|
u = PAM(ref="U12")
|
|
|
|
# supply
|
|
u["VDD"] += p5; u["GND"] += gnd
|
|
cb = C("1uF","Capacitor_SMD:C_0805_2012Metric"); p5 += cb[1]; cb[2] += gnd
|
|
cd = C("100nF"); p5 += cd[1]; cd[2] += gnd
|
|
# enable (SD high); route SPK_SD to a GPIO if desired
|
|
rsd = R(value="100k"); spk_sd += rsd[1]; rsd[2] += p5; u["SD"] += spk_sd
|
|
# single-ended input: MIX_OUT -> coupling cap + RIN -> IN+ ; IN- coupled to gnd (matched)
|
|
cin = C("1uF","Capacitor_SMD:C_0805_2012Metric"); rin = R(value="68k") # ~+5.7dB
|
|
mix_out += cin[1]; cin[2] += rin[1]; rin[2] += u["IN+"]
|
|
cinm = C("1uF","Capacitor_SMD:C_0805_2012Metric"); u["IN-"] += cinm[1]; cinm[2] += gnd
|
|
# filterless BTL output to speaker (via interconnect); add EMI ferrite/cap at layout if needed
|
|
u["VO+"] += spk_p; u["VO-"] += spk_n
|
|
|
|
ERC()
|
|
out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "speaker.net"))
|
|
generate_netlist(file_=out)
|
|
print("Speaker netlist ->", out)
|