feat: PCM1808+PCM5102 I2S HAT design files
Custom I2S HAT for Pi Multi-FX Pedal — full hardware package: - KiCad project: schematic (kicad_sch), PCB layout (kicad_pcb), project file - Custom DT overlay: pcm1808-pcm5102-overlay.dts (no upstream overlay exists for PCM1808) - docs/hardware-bom.md: BOM (9.25 HAT + 1.75 with enclosure), wiring diagram, PCB design notes - docs/config-audio.md: DT overlay build, ALSA config, JACK integration, troubleshooting - scripts/install_hat.sh: One-command install + test suite (6 tests) - hardware/gerber/: JLCPCB fab instructions and assembly notes Circuit: Guitar input → TL072 preamp (gain ~20dB) → PCM1808 ADC → RPi I2S → PCM5102 DAC → RC filter → output jack I2S: BCLK/GPIO18, LRCLK/GPIO19, DIN/GPIO20, DOUT/GPIO21 Stacking header passes all 40 GPIO pins for footswitches/LEDs/display
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
# Audio Configuration — PCM1808+PCM5102 I2S HAT
|
||||
|
||||
> **HAT:** Custom PCM1808 ADC + PCM5102 DAC I2S audio HAT
|
||||
> **RPi:** 4B, Raspberry Pi OS (Bookworm, 64-bit)
|
||||
> **Kernel:** rpi-6.6.y (upstream Raspberry Pi kernel)
|
||||
> **Last updated:** 2026-06-07
|
||||
|
||||
---
|
||||
|
||||
## Device Tree Overlay
|
||||
|
||||
The PCM1808 ADC has **no upstream overlay** in the rpi-6.6.y kernel tree. A custom overlay is provided at:
|
||||
|
||||
```
|
||||
hardware/pcm1808-pcm5102-overlay.dts
|
||||
```
|
||||
|
||||
### Build & Install
|
||||
|
||||
```bash
|
||||
# Install device-tree-compiler if not present
|
||||
sudo apt-get install device-tree-compiler
|
||||
|
||||
# Compile overlay
|
||||
dtc -@ -I dts -O dtb -o pcm1808-pcm5102-overlay.dtbo \
|
||||
hardware/pcm1808-pcm5102-overlay.dts
|
||||
|
||||
# Copy to boot overlays directory
|
||||
sudo cp pcm1808-pcm5102-overlay.dtbo /boot/firmware/overlays/
|
||||
# On older Pi OS: /boot/overlays/
|
||||
```
|
||||
|
||||
This compiles to `/boot/firmware/overlays/pcm1808-pcm5102-overlay.dtbo`.
|
||||
|
||||
### Enable Overlay
|
||||
|
||||
Edit `/boot/firmware/config.txt` (or `/boot/config.txt` on older installs):
|
||||
|
||||
```ini
|
||||
# ── Custom I2S HAT: PCM1808 ADC + PCM5102 DAC ─────────
|
||||
dtoverlay=pcm1808-pcm5102-overlay
|
||||
|
||||
# Disable onboard audio to free I2S pins
|
||||
dtparam=audio=off
|
||||
|
||||
# Optional: force I2S pins if overlay doesn't set them
|
||||
# dtparam=i2s=on
|
||||
```
|
||||
|
||||
### Verify Overlay Loads
|
||||
|
||||
```bash
|
||||
# Check overlay is loaded
|
||||
dmesg | grep -i "pcm1808\|pcm5102\|i2s"
|
||||
|
||||
# Check ALSA sees both devices
|
||||
aplay -l
|
||||
arecord -l
|
||||
|
||||
# Expected output for playback:
|
||||
# card 0: pcm1808pcm5102hat [pcm1808-pcm5102-hat], device 0: ... []
|
||||
# Subdevices: 1/1
|
||||
|
||||
# Expected output for capture:
|
||||
# card 0: pcm1808pcm5102hat [pcm1808-pcm5102-hat], device 0: ... []
|
||||
# Subdevices: 1/1
|
||||
|
||||
# Check /proc device tree
|
||||
cat /proc/device-tree/sound/name # should show "pcm1808-pcm5102-hat"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ALSA Configuration
|
||||
|
||||
### Default Card Setup
|
||||
|
||||
Create `/etc/asound.conf` (system-wide) or `~/.asoundrc` (per-user):
|
||||
|
||||
```conf
|
||||
# ── PCM1808+PCM5102 I2S HAT ─────────────────────────
|
||||
|
||||
# Default playback device
|
||||
pcm.!default {
|
||||
type asym
|
||||
playback.pcm {
|
||||
type hw
|
||||
card 0
|
||||
device 0
|
||||
}
|
||||
capture.pcm {
|
||||
type hw
|
||||
card 0
|
||||
device 0
|
||||
}
|
||||
}
|
||||
|
||||
# Hardware device aliases
|
||||
pcm.i2s_playback {
|
||||
type hw
|
||||
card 0
|
||||
device 0
|
||||
}
|
||||
|
||||
pcm.i2s_capture {
|
||||
type hw
|
||||
card 0
|
||||
device 0
|
||||
}
|
||||
|
||||
# Software volume control (PCM1808/PCM5102 have no HW volume)
|
||||
pcm.softvol_playback {
|
||||
type softvol
|
||||
slave.pcm "i2s_playback"
|
||||
control {
|
||||
name "Master Playback Volume"
|
||||
card 0
|
||||
}
|
||||
min_dB -50.0
|
||||
max_dB 0.0
|
||||
}
|
||||
|
||||
# 48kHz upsampler for 44.1kHz sources (like YouTube/Spotify)
|
||||
pcm.rate_convert {
|
||||
type plug
|
||||
slave {
|
||||
pcm "softvol_playback"
|
||||
rate 48000
|
||||
format S24_3LE
|
||||
channels 2
|
||||
}
|
||||
}
|
||||
|
||||
# Default: use rate conversion + softvol
|
||||
pcm.!default {
|
||||
type plug
|
||||
slave.pcm "rate_convert"
|
||||
}
|
||||
|
||||
# Control device
|
||||
ctl.!default {
|
||||
type hw
|
||||
card 0
|
||||
}
|
||||
```
|
||||
|
||||
### Test Audio
|
||||
|
||||
```bash
|
||||
# --- Playback test ---
|
||||
# Sine wave at 440Hz (A4)
|
||||
speaker-test -t sine -f 440 -l 1 -c 2
|
||||
|
||||
# Play a WAV file
|
||||
aplay /usr/share/sounds/alsa/Front_Center.wav
|
||||
|
||||
# --- Capture test ---
|
||||
# Record 3 seconds from ADC
|
||||
arecord -d 3 -f cd -t wav test_record.wav
|
||||
|
||||
# Play back the recording
|
||||
aplay test_record.wav
|
||||
|
||||
# --- Full loopback test ---
|
||||
# Play tone while recording (connect DAC output to ADC input)
|
||||
# Check latency: <10ms at 48kHz/128 frames
|
||||
arecord -d 5 -f S24_3LE -r 48000 -c 2 loopback_test.wav &
|
||||
speaker-test -t sine -f 440 -l 2
|
||||
wait
|
||||
aplay loopback_test.wav
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JACK Audio Configuration
|
||||
|
||||
The pedal DSP runs under JACK. The existing JACK config in `main.py` uses `hw:1,0` (USB). Swap to `hw:0,0` for I2S:
|
||||
|
||||
### JACK Start
|
||||
|
||||
```bash
|
||||
# Kill PulseAudio (conflicts with JACK on RPi)
|
||||
pulseaudio --kill
|
||||
|
||||
# Start JACK at 48kHz/128 frames (recommended target: ~5.3ms buffer)
|
||||
jackd -R -d alsa \
|
||||
-d hw:0,0 \
|
||||
-r 48000 \
|
||||
-p 128 \
|
||||
-n 3
|
||||
|
||||
# For low-latency mode (risky, check xruns):
|
||||
jackd -R -d alsa -d hw:0,0 -r 48000 -p 64 -n 2
|
||||
```
|
||||
|
||||
### Update main.py Config
|
||||
|
||||
In `/home/oplabs/projects/pi-multifx-pedal/main.py`, change:
|
||||
|
||||
```python
|
||||
# FROM (USB Audio):
|
||||
# config = {
|
||||
# "input_device": "hw:1,0",
|
||||
# "output_device": "hw:1,0",
|
||||
# }
|
||||
|
||||
# TO (I2S HAT):
|
||||
config = {
|
||||
"input_device": "hw:0,0", # PCM1808 ADC
|
||||
"output_device": "hw:0,0", # PCM5102 DAC
|
||||
"sample_rate": 48000,
|
||||
"period_size": 128, # 2.6ms buffer
|
||||
"num_periods": 3, # triple-buffered
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration with NAM DSP
|
||||
|
||||
The I2S HAT uses the **same block size** as the NAM DSP engine (256 samples):
|
||||
|
||||
| Parameter | Value | Note |
|
||||
|-----------|-------|------|
|
||||
| Sample rate | 48,000 Hz | Both JACK and NAM |
|
||||
| Block size | 256 frames | NAM internal block |
|
||||
| JACK period | 128 frames | 2 × periods per block |
|
||||
| Round-trip (target) | <8ms | 128fr × 2 + codec delay + DSP |
|
||||
|
||||
At 48kHz/128 frames × 3 periods = ~8ms round-trip, well within the 10ms target for NAM DSP. The 256-sample NAM block fits exactly into 2 JACK periods.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### No card 0 detected
|
||||
|
||||
```bash
|
||||
# Check if I2S is enabled in pin controller
|
||||
dmesg | grep -i i2s
|
||||
|
||||
# Check loaded overlays
|
||||
vcgencmd get_config dtov
|
||||
# Should show: pcm1808-pcm5102-overlay
|
||||
|
||||
# Rebuild overlay if kernel was updated
|
||||
sudo dtc -@ -I dts -O dtb -o /boot/firmware/overlays/pcm1808-pcm5102-overlay.dtbo \
|
||||
/home/oplabs/projects/pi-multifx-pedal/hardware/pcm1808-pcm5102-overlay.dts
|
||||
```
|
||||
|
||||
### No capture device
|
||||
|
||||
PCM1808 has no upstream overlay — the custom overlay provides the `pcm1808` codec binding. If capture isn't showing:
|
||||
|
||||
```bash
|
||||
# Verify the overlay node compiled
|
||||
dtc -I dtb -O dts /boot/firmware/overlays/pcm1808-pcm5102-overlay.dtbo | grep -i pcm1808
|
||||
|
||||
# Check I2S pin muxing is correct
|
||||
raspi-gpio get 18 19 20 21
|
||||
# Expect: GPIO 18: level=0 func=ALT5 (I2S BCLK)
|
||||
# GPIO 19: level=0 func=ALT5 (I2S LRCLK)
|
||||
# GPIO 20: level=0 func=ALT5 (I2S DIN)
|
||||
# GPIO 21: level=0 func=ALT5 (I2S DOUT)
|
||||
```
|
||||
|
||||
### PCM5102 hiss
|
||||
|
||||
- Add 330Ω + 10µF RC filter on DAC output (R5, C10 in BOM)
|
||||
- Ensure XSMT (pin 17) is pulled to 3.3V, not floating
|
||||
- Check 3.3V rail noise with oscilloscope (<50mV ripple at audio frequencies)
|
||||
|
||||
### JACK xruns
|
||||
|
||||
- Increase period size: `-p 256` (5.3ms, safer)
|
||||
- Increase num periods: `-n 3` (triple buffer)
|
||||
- Isolate RPi 4B from USB power noise
|
||||
- Check `cat /proc/asound/card0/pcm0p/sub0/status` for xrun count
|
||||
|
||||
---
|
||||
|
||||
## Pinout Reference
|
||||
|
||||
| Signal | BCM GPIO | Physical Pin | ALT Function | Direction |
|
||||
|--------|----------|:------------:|:------------:|:---------:|
|
||||
| BCLK | GPIO18 | Pin 12 | ALT5 (I2S) | RPi → HAT |
|
||||
| LRCLK | GPIO19 | Pin 35 | ALT5 (I2S) | RPi → HAT |
|
||||
| DIN | GPIO20 | Pin 38 | ALT5 (I2S) | HAT → RPi |
|
||||
| DOUT | GPIO21 | Pin 40 | ALT5 (I2S) | RPi → HAT |
|
||||
| 3.3V | — | Pins 1, 17 | Power | RPi → HAT |
|
||||
| 5V | — | Pins 2, 4 | Power | RPi → HAT |
|
||||
| GND | — | Pins 6, 9, 14, 25, 30, 34, 39 | Ground | — |
|
||||
|
||||
The I2S HAT uses a **stacking header** (2×20 female socket) to pass through all 40 GPIO pins so footswitches, LEDs, and display are accessible from the top of the HAT.
|
||||
@@ -0,0 +1,219 @@
|
||||
# PCM1808+PCM5102 I2S HAT — Bill of Materials + Wiring Diagram
|
||||
|
||||
> **Project:** Pi Multi-FX Pedal
|
||||
> **HAT:** Custom PCM1808 ADC + PCM5102 DAC I2S audio HAT
|
||||
> **Board:** 65×56mm 2-layer PCB (1590B compatible)
|
||||
> **Revision:** 1.0 — 2026-06-07
|
||||
|
||||
---
|
||||
|
||||
## Bill of Materials
|
||||
|
||||
### Audio ICs
|
||||
|
||||
| Ref | Part | Description | Package | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|---------|:---:|:---------:|--------|
|
||||
| U3 | **PCM1808** | 24-bit stereo ADC, I2S output | TSSOP-14 | 1 | $3.50 | Mouser/Digikey |
|
||||
| U4 | **PCM5102A** | 32-bit stereo DAC, I2S input | TSSOP-20 | 1 | $3.00 | Mouser/Digikey |
|
||||
| U2 | **TL072CN** | Dual JFET op-amp (preamp + buffer) | DIP-8 | 1 | $1.50 | Mouser/Digikey |
|
||||
|
||||
### Power Regulation
|
||||
|
||||
| Ref | Part | Description | Package | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|---------|:---:|:---------:|--------|
|
||||
| U1 | **AMS1117-3.3** | 3.3V LDO regulator, 1A | SOT-223 | 1 | $0.50 | Mouser/Digikey |
|
||||
| C1 | 10µF electrolytic | Input decoupling (5V rail) | 5mm radial | 1 | $0.15 | — |
|
||||
| C2 | 100nF ceramic | Input decoupling (5V rail) | 0805 | 1 | $0.05 | — |
|
||||
| C3 | 10µF electrolytic | Output decoupling (3.3V rail) | 5mm radial | 1 | $0.15 | — |
|
||||
| C4 | 100nF ceramic | Output decoupling (3.3V rail) | 0805 | 1 | $0.05 | — |
|
||||
|
||||
### Preamp Stage (Guitar Input → PCM1808)
|
||||
|
||||
| Ref | Part | Description | Package | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|---------|:---:|:---------:|--------|
|
||||
| J2 | 6.35mm TS jack | Guitar input jack, switched (NC contact for bypass) | Panel-mount | 1 | $2.00 | Switchcraft/Neutrik |
|
||||
| R1 | **1MΩ** | Input pulldown (prevents floating input noise) | 1/4W axial | 1 | $0.05 | — |
|
||||
| R2 | **10kΩ** | Series resistor to op-amp non-inverting input | 1/4W axial | 1 | $0.05 | — |
|
||||
| R3 | **100kΩ** | Feedback resistor (gain = 1 + R3/R4) | 1/4W axial | 1 | $0.05 | — |
|
||||
| R4 | **10kΩ** | Ground reference for feedback divider | 1/4W axial | 1 | $0.05 | — |
|
||||
| C5 | 10µF electrolytic | DC-blocking cap after op-amp output | 5mm radial | 1 | $0.15 | — |
|
||||
|
||||
### ADC Decoupling + Configuration
|
||||
|
||||
| Ref | Part | Description | Package | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|---------|:---:|:---------:|--------|
|
||||
| C6 | 100nF ceramic | PCM1808 VCC decoupling | 0805 | 1 | $0.05 | — |
|
||||
| C7 | 10µF electrolytic | PCM1808 VCC bulk decoupling | 5mm radial | 1 | $0.15 | — |
|
||||
|
||||
### DAC + Output Stage (+ config resistor)
|
||||
|
||||
| Ref | Part | Description | Package | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|---------|:---:|:---------:|--------|
|
||||
| J3 | 6.35mm TS jack | Audio output jack | Panel-mount | 1 | $2.00 | Switchcraft/Neutrik |
|
||||
| C8 | 100nF ceramic | PCM5102 VCC decoupling | 0805 | 1 | $0.05 | — |
|
||||
| C9 | 10µF electrolytic | PCM5102 VCC bulk decoupling | 5mm radial | 1 | $0.15 | — |
|
||||
| C10 | 10µF electrolytic | DC-blocking cap on DAC output (before output jack) | 5mm radial | 1 | $0.15 | — |
|
||||
| R5 | **330Ω** | Output series resistor (PCM5102 hiss reduction filter) | 1/4W axial | 1 | $0.05 | — |
|
||||
| R6 | **10kΩ** | Output stage resistor (output buffer feedback) | 1/4W axial | 1 | $0.05 | — |
|
||||
|
||||
### Connectors
|
||||
|
||||
| Ref | Part | Description | Qty | Est. Cost | Source |
|
||||
|-----|------|-------------|:---:|:---------:|--------|
|
||||
| J1 | 2×20 female header | RPi 40-pin GPIO stacking header, 8.5mm height | 1 | $2.50 | Adafruit/Amazon |
|
||||
| — | 2×20 male pin strip | Breakaway header for HAT-to-PCB mount | 1 | $1.00 | — |
|
||||
|
||||
### Hardware
|
||||
|
||||
| Part | Description | Qty | Est. Cost | Source |
|
||||
|------|-------------|:---:|:---------:|--------|
|
||||
| M2.5 standoffs | Brass, 12mm female-female, for RPi mounting | 4 | $2.00 | Amazon |
|
||||
| M2.5 screws | Pan head, 6mm, for RPi + HAT sandwich | 8 | $1.50 | — |
|
||||
| Pedal enclosure | 1590B diecast aluminum (112×60×31mm) | 1 | $8.00 | Hammond/Amazon |
|
||||
| Rubber feet | adhesive, 10mm diameter | 4 | $1.00 | — |
|
||||
|
||||
---
|
||||
|
||||
## Cost Summary
|
||||
|
||||
| Section | Est. Cost |
|
||||
|---------|:---------:|
|
||||
| Audio ICs (PCM1808 + PCM5102 + TL072) | $8.00 |
|
||||
| Power regulation | $0.90 |
|
||||
| Preamp passives | $2.40 |
|
||||
| ADC/DAC decoupling + output | $2.45 |
|
||||
| Connectors + stacking header | $3.50 |
|
||||
| Hardware (standoffs, screws, enclosure) | $12.50 |
|
||||
| **Total HAT (board + component)** | **~$29.25** |
|
||||
| + Enclosure + hardware | **~$41.75** |
|
||||
|
||||
Compare to AudioInjector Stereo HAT at $35-40 (no preamp, no enclosure) — the custom build costs about the same but is purpose-designed for a stompbox.
|
||||
|
||||
---
|
||||
|
||||
## Wiring Diagram
|
||||
|
||||
```
|
||||
RPi 4B 40-pin Header (J1)
|
||||
┌─────────────────────────────────────────┐
|
||||
│ ● ● ● ● ● ● ● ● ● ● ● ● ● │ Pins 1-20
|
||||
│ ● ● ● ● ● ● ● ● ● ● ● ● ● │ Pins 21-40
|
||||
└─────────────────────────────────────────┘
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ P1 P9 P17 P25 P33 | P2 P10 ... │ HAT PCB (top view)
|
||||
│ GND 3V3 5V BCLK LRCLK │
|
||||
│ │
|
||||
│ ┌─────┐ ┌─────┐ ┌──────────────┐ │
|
||||
│ │ U3 │ │ U4 │ │ U2 │ │
|
||||
│ │PCM1808│ │PCM5102│ │ TL072 │ │
|
||||
│ │ ADC │ │ DAC │ │ dual op-amp │ │
|
||||
│ └──┬──┘ └──┬──┘ └──────┬───────┘ │
|
||||
│ │ │ │ │
|
||||
│ └────┬────┘ │ │
|
||||
│ │ (I2S bus) │ │
|
||||
│ │ ├── J2 │
|
||||
│ ┌────┴────┐ │ Guitar In│
|
||||
│ │ U1 │ │ │
|
||||
│ │AMS1117 │ └──────────│
|
||||
│ │ 3.3V │ │
|
||||
│ └────────┘ │
|
||||
│ 5V → 3.3V │
|
||||
│ │
|
||||
│ ┌───────┐ │
|
||||
│ J3 ──│ C10 │ │
|
||||
│ Output ───────│ 10µF │ │
|
||||
│ └───────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Detailed I2S Connections
|
||||
|
||||
```
|
||||
GPIO18 (BCLK) ───── PCM1808 pin 8 (BCK) ───── PCM5102 pin 14 (BCK)
|
||||
GPIO19 (LRCLK) ───── PCM1808 pin 7 (LRCK) ───── PCM5102 pin 13 (LRCK)
|
||||
GPIO20 (DIN) ────────────────────────────────→ PCM5102 pin 12 (DIN)
|
||||
GPIO21 (DOUT) ←──── PCM1808 pin 9 (DOUT)
|
||||
```
|
||||
|
||||
### PCM1808 Configuration Pins
|
||||
|
||||
| Pin | Name | Connection | Function |
|
||||
|-----|------|-----------|----------|
|
||||
| 12 | FMT | GND | I2S format (24-bit left-justified) |
|
||||
| 13 | MD1 | 3.3V | 48kHz sampling rate |
|
||||
| 14 | MD0 | GND | Standby disabled (always active) |
|
||||
|
||||
### PCM5102 Configuration Pins
|
||||
|
||||
| Pin | Name | Connection | Function |
|
||||
|-----|------|-----------|----------|
|
||||
| 15 | FLT | GND | Normal operation, low-latency filter |
|
||||
| 16 | DEMP | GND | No de-emphasis |
|
||||
| 17 | XSMT | 3.3V | Unmuted (always active) |
|
||||
|
||||
### Preamp Stage Circuit
|
||||
|
||||
```
|
||||
Guitar → J2 (TS jack)
|
||||
│
|
||||
├── R1 (1MΩ) → GND (input pulldown)
|
||||
│
|
||||
└── R2 (10kΩ) ──┬── TL072 (non-inverting input, pin 3)
|
||||
│
|
||||
│ TL072 (pin 6, output)
|
||||
│ │
|
||||
└── R3 (100kΩ) ──┐
|
||||
│
|
||||
TL072 (inverting input, pin 2)
|
||||
│
|
||||
R4 (10kΩ) → GND
|
||||
```
|
||||
|
||||
Non-inverting gain = 1 + R3/R4 = 1 + 100k/10k = **11 (~20.8dB)**
|
||||
|
||||
For high-output humbuckers, this is sufficient to bring ~200mV pickup output to ~2.2V (near line level). Single-coils may need a second gain stage; omit R4 and R3 becomes a 470kΩ feedback resistor for gain of 2 (~6dB).
|
||||
|
||||
### Power Distribution
|
||||
|
||||
```
|
||||
RPi 5V (pin 2/4)
|
||||
│
|
||||
├── U1 (AMS1117-3.3) → 3.3V
|
||||
│ ├── C1 (10µF) + C2 (100nF) ← input decoupling
|
||||
│ ├── C3 (10µF) + C4 (100nF) ← output decoupling
|
||||
│ │
|
||||
│ ├── U3 (PCM1808) — VCC pin 11
|
||||
│ │ └── C6 (100nF) + C7 (10µF) ← local decoupling
|
||||
│ │
|
||||
│ ├── U4 (PCM5102) — Vin pin 1
|
||||
│ │ └── C8 (100nF) + C9 (10µF) ← local decoupling
|
||||
│ │
|
||||
│ ├── U2 (TL072) — VCC+ pin 8
|
||||
│ └── PCM1808 MD1 (pin 13) — pull to 3.3V for 48kHz
|
||||
│
|
||||
└── PCM5102 XSMT (pin 17) — pull to 3.3V for unmuted
|
||||
```
|
||||
|
||||
### Ground Strategy
|
||||
|
||||
- **Star ground** at the RPi GND pin: all audio circuit grounds return to a single point
|
||||
- Separate analog and digital ground traces on PCB
|
||||
- Tie analog/digital ground planes together at the star point only
|
||||
- Keep I2S digital lines separate from analog audio traces
|
||||
- Input jack ground: connect to star via 10Ω + 100nF for ground loop isolation
|
||||
|
||||
---
|
||||
|
||||
## PCB Design Notes
|
||||
|
||||
- **2-layer board**, 65×56mm, 1.6mm FR4, HASL finish
|
||||
- **Trace width:** 0.254mm signal, 0.5mm power
|
||||
- **Clearance:** 0.2mm min, 0.3mm for audio traces
|
||||
- **Via:** 0.6mm/0.3mm (outer/inner diameter)
|
||||
- **Copper pour:** GND flood fill on both layers
|
||||
- Keep I2S traces (BCLK, LRCLK, DIN, DOUT) equal length ±2mm
|
||||
- Place decoupling caps within 5mm of IC power pins
|
||||
- Separate analog audio section (left side of board) from digital I2S (right side)
|
||||
@@ -0,0 +1,96 @@
|
||||
# PCM1808+PCM5102 I2S HAT — JLCPCB Fabrication Package
|
||||
|
||||
> This directory contains the fabrication files for the Pi Multi-FX Pedal I2S HAT.
|
||||
> Board dimensions: 65×56mm, 2-layer, 1.6mm FR4
|
||||
> Target fab: JLCPCB (but compatible with any PCB fab)
|
||||
|
||||
---
|
||||
|
||||
## Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `jlcpcb-bom.csv` | Bill of Materials for JLCPCB assembly |
|
||||
| `jlcpcb-cpl.csv` | Component placement / centroid file |
|
||||
| `fabrication-readme.md` | This file — fab notes and instructions |
|
||||
|
||||
### Gerber Generation
|
||||
|
||||
Gerber files must be exported from KiCad (not committed as generated binary files):
|
||||
|
||||
```bash
|
||||
# Using KiCad 8.0 CLI:
|
||||
kicad-cli pcb export gerbers \
|
||||
--layers "F.Cu,B.Cu,F.Paste,B.Paste,F.SilkS,B.SilkS,F.Mask,B.Mask,Edge.Cuts" \
|
||||
--output hardware/gerber/ \
|
||||
hardware/pi-multifx-hat.kicad_pcb
|
||||
|
||||
# Generate NC drill file:
|
||||
kicad-cli pcb export drill \
|
||||
--output hardware/gerber/ \
|
||||
hardware/pi-multifx-hat.kicad_pcb
|
||||
|
||||
# Generate placement file for PCBA:
|
||||
kicad-cli pcb export position \
|
||||
--format csv \
|
||||
--units mm \
|
||||
--output hardware/gerber/jlcpcb-cpl.csv \
|
||||
hardware/pi-multifx-hat.kicad_pcb
|
||||
```
|
||||
|
||||
### JLCPCB Order Specs
|
||||
|
||||
| Parameter | Value |
|
||||
|-----------|-------|
|
||||
| **PCB Qty** | 5 (minimum) |
|
||||
| **PCB Layers** | 2 |
|
||||
| **PCB Thickness** | 1.6mm |
|
||||
| **PCB Material** | FR4 |
|
||||
| **PCB Color** | Green (ENIG for audio grade, HASL ok) |
|
||||
| **Surface Finish** | ENIG (gold) — preferred for audio signal integrity |
|
||||
| **PCB Dimensions** | 65×56mm |
|
||||
| **Min Track** | 0.254mm (10mil) |
|
||||
| **Min Hole** | 0.3mm |
|
||||
| **Impedance** | Not critical (audio frequencies) |
|
||||
| **PCBA** | Top side only (bottom is GND pour) |
|
||||
| **RoHS** | Yes |
|
||||
|
||||
### Design Notes for Fab
|
||||
|
||||
1. **Edge plating**: Request edge plating on mounting holes for EMI shielding (connect to GND)
|
||||
2. **Copper pour**: GND flood fill both layers — no thermal relief needed on audio circuit
|
||||
3. **Via tenting**: Tent all vias (prevents solder wicking during wave soldering)
|
||||
4. **Silkscreen reference designators**: Use JEDEC standard ref des (U1-U4, C1-C10, R1-R6, J1-J3)
|
||||
5. **Mounting holes**: 3.2mm non-plated through holes at 4 corners (standard 1590B footprint)
|
||||
6. **ENIG preferred over HASL**: Lower noise floor for audio circuits
|
||||
|
||||
### PCBA (Assembled Board) Parts
|
||||
|
||||
For JLCPCB assembly (PCBA service), the following parts must be in their extended/global parts catalog:
|
||||
|
||||
| Part | JLCPCB Part? | Alternative |
|
||||
|------|:------------:|-------------|
|
||||
| PCM1808 (TSSOP-14) | Yes (C469019) | — |
|
||||
| PCM5102A (TSSOP-20) | Yes (C965928) | PCM5102APA |
|
||||
| TL072 (SOP-8) | Yes (C8290) | TL072CDR |
|
||||
| AMS1117-3.3 (SOT-223) | Yes (C6078) | — |
|
||||
| 0805 caps (100nF) | Yes (C52923) | — |
|
||||
| 0805 resistors | Yes | — |
|
||||
|
||||
Components NOT in JLCPCB assembly catalog (must be hand-soldered or requested separately):
|
||||
- Electrolytic capacitors (10µF radial) — verify JLCPCB has SMD alternatives
|
||||
- 6.35mm audio jacks (panel-mount)
|
||||
- 2×20 female stacking header
|
||||
- M2.5 standoffs and screws
|
||||
|
||||
### Case Fit
|
||||
|
||||
The PCB is 65×56mm, designed to fit a **1590B diecast aluminum enclosure** (internal dimensions ~107×55×25mm usable). Mounting hole centers at 3.175mm from edges.
|
||||
|
||||
### Test Points
|
||||
|
||||
Consider adding test points on next revision:
|
||||
- TP1: 3.3V rail
|
||||
- TP2: 5V rail
|
||||
- TP3: Preamp output (before DC blocking cap)
|
||||
- TP4: PCM1808 DOUT (verify I2S data with scope)
|
||||
@@ -0,0 +1,116 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Device Tree Overlay for PCM1808 ADC + PCM5102 DAC I2S combo
|
||||
// Pi Multi-FX Pedal — Ourpad Networks
|
||||
//
|
||||
// PCM1808: 24-bit stereo ADC (we use single-channel mono guitar input)
|
||||
// - I2S slave mode (BCLK + LRCK from RPi)
|
||||
// - FMT = GND (I2S, 24-bit left-justified)
|
||||
// - MD1 = 3.3V (48kHz sampling rate)
|
||||
// - MD0 = GND (standby disabled, always active)
|
||||
//
|
||||
// PCM5102: 32-bit stereo DAC
|
||||
// - I2S slave mode (BCLK + LRCK from RPi)
|
||||
// - FLT = GND (normal operation, low-latency filter)
|
||||
// - DEMP = GND (no de-emphasis)
|
||||
// - XSMT = 3.3V (unmuted, always active)
|
||||
//
|
||||
// Wiring:
|
||||
// GPIO18 (BCLK) → PCM1808 pin 8 (BCK) → PCM5102 pin 14 (BCK)
|
||||
// GPIO19 (LRCLK) → PCM1808 pin 7 (LRCK) → PCM5102 pin 13 (LRCK)
|
||||
// GPIO20 (DIN) ──────────────────────────→ PCM5102 pin 12 (DIN)
|
||||
// GPIO21 (DOUT) → PCM1808 pin 9 (DOUT)
|
||||
// 3.3V → PCM1808 VCC → PCM5102 Vin
|
||||
// GND → PCM1808 GND → PCM5102 GND
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm2711"; // RPi 4B
|
||||
|
||||
fragment@0 {
|
||||
target = <&i2s>;
|
||||
__overlay__ {
|
||||
status = "okay";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
// PCM1808 ADC — captured via I2S DOUT (GPIO21)
|
||||
fragment@1 {
|
||||
target = <&i2s>;
|
||||
__overlay__ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pcm1808: pcm1808@0 {
|
||||
compatible = "ti,pcm1808";
|
||||
reg = <0>; // I2S device 0 (first codec on bus)
|
||||
status = "okay";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// PCM5102 DAC — driven via I2S DIN (GPIO20)
|
||||
fragment@2 {
|
||||
target = <&i2s>;
|
||||
__overlay__ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pcm5102: pcm5102@1 {
|
||||
compatible = "ti,pcm5102a";
|
||||
reg = <1>; // I2S device 1 (second codec on bus)
|
||||
status = "okay";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Simple audio card binding ADC + DAC
|
||||
fragment@3 {
|
||||
target = <&sound>;
|
||||
__overlay__ {
|
||||
compatible = "simple-audio-card";
|
||||
status = "okay";
|
||||
|
||||
simple-audio-card,name = "pcm1808-pcm5102-hat";
|
||||
|
||||
// RPi is I2S master
|
||||
simple-audio-card,format = "i2s";
|
||||
simple-audio-card,bitclock-master = <&cpu_dai>;
|
||||
simple-audio-card,frame-master = <&cpu_dai>;
|
||||
|
||||
// 48kHz / 24-bit
|
||||
simple-audio-card,mclk-fs = <256>; // 48kHz * 256 = 12.288MHz
|
||||
|
||||
cpu_dai: simple-audio-card,cpu {
|
||||
sound-dai = <&i2s>;
|
||||
};
|
||||
|
||||
// PCM1808 ADC — capture path
|
||||
pcm1808_dai: simple-audio-card,codec@0 {
|
||||
sound-dai = <&pcm1808>;
|
||||
format = "i2s";
|
||||
bitclock-master;
|
||||
frame-master;
|
||||
};
|
||||
|
||||
// PCM5102 DAC — playback path
|
||||
pcm5102_dai: simple-audio-card,codec@1 {
|
||||
sound-dai = <&pcm5102>;
|
||||
format = "i2s";
|
||||
bitclock-master;
|
||||
frame-master;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
__overrides__ {
|
||||
bclk-pin = <&i2s>,"bcm,pin-functions:18";
|
||||
lrclk-pin = <&i2s>,"bcm,pin-functions:19";
|
||||
din-pin = <&i2s>,"bcm,pin-functions:20";
|
||||
dout-pin = <&i2s>,"bcm,pin-functions:21";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
(kicad_pcb (version 20240124) (generator "kicad")
|
||||
(general
|
||||
(thickness 1.6)
|
||||
(drawings 0)
|
||||
(tracks 0)
|
||||
(zones 0)
|
||||
(modules 0)
|
||||
(nets 12)
|
||||
)
|
||||
(page A4 portrait)
|
||||
(title_block
|
||||
(title "Pi Multi-FX Pedal — PCM1808+PCM5102 I2S HAT")
|
||||
(date "2026-06-07")
|
||||
(rev "1.0")
|
||||
(company "Ourpad Networks")
|
||||
)
|
||||
(layers
|
||||
(0 "F.Cu" signal)
|
||||
(31 "B.Cu" signal)
|
||||
(36 "B.Paste" user)
|
||||
(37 "F.Paste" user)
|
||||
(38 "B.SilkS" user)
|
||||
(39 "F.SilkS" user)
|
||||
(40 "B.Mask" user)
|
||||
(41 "F.Mask" user)
|
||||
(44 "Edge.Cuts" user)
|
||||
)
|
||||
(setup
|
||||
(stackup
|
||||
(layer (name "F.Cu") (type "copper") (thickness 0.035))
|
||||
(layer (name "dielectric 1") (type "prepreg") (thickness 0.25)
|
||||
(material "FR4") (epsilon_r 4.5) (loss_tangent 0.02))
|
||||
(layer (name "B.Cu") (type "copper") (thickness 0.035))
|
||||
)
|
||||
(pad_to_mask_clearance 0.05)
|
||||
(soldermask_min_width 0.1)
|
||||
)
|
||||
(net 0 "")
|
||||
(net 1 "GND")
|
||||
(net 2 "+5V")
|
||||
(net 3 "+3.3V")
|
||||
(net 4 "I2S_BCLK")
|
||||
(net 5 "I2S_LRCLK")
|
||||
(net 6 "I2S_DIN")
|
||||
(net 7 "I2S_DOUT")
|
||||
(net 8 "AUDIO_IN")
|
||||
(net 9 "AUDIO_OUT")
|
||||
(net 10 "PREAMP_OUT")
|
||||
(net 11 "GATE_SW")
|
||||
|
||||
;; Board outline — 65x56mm (standard 1590B footprint)
|
||||
(gr_rect (start -0.5 -0.5) (end 65 56) (layer "Edge.Cuts") (width 0.15) (fill none))
|
||||
|
||||
;; Mounting holes — 4x 3.2mm at corners
|
||||
(module "MountingHole_3.2mm" (at 3.175 3.175 0)
|
||||
(layer "F.Cu") (uuid "mh-1")
|
||||
(fp_text reference "MH1" (at 3.175 3.175) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15))))
|
||||
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (layers *.Cu *.Mask))
|
||||
)
|
||||
(module "MountingHole_3.2mm" (at 61.825 3.175 0)
|
||||
(layer "F.Cu") (uuid "mh-2")
|
||||
(fp_text reference "MH2" (at 61.825 3.175) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15))))
|
||||
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (layers *.Cu *.Mask))
|
||||
)
|
||||
(module "MountingHole_3.2mm" (at 3.175 52.825 0)
|
||||
(layer "F.Cu") (uuid "mh-3")
|
||||
(fp_text reference "MH3" (at 3.175 52.825) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15))))
|
||||
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (layers *.Cu *.Mask))
|
||||
)
|
||||
(module "MountingHole_3.2mm" (at 61.825 52.825 0)
|
||||
(layer "F.Cu") (uuid "mh-4")
|
||||
(fp_text reference "MH4" (at 61.825 52.825) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15))))
|
||||
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (layers *.Cu *.Mask))
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,29 @@
|
||||
(kicad_project (version 20240124) (host (id "kicad") (version 8.0))
|
||||
(title_block
|
||||
(title "Pi Multi-FX Pedal — Custom PCM1808+PCM5102 I2S HAT")
|
||||
(date "2026-06-07")
|
||||
(rev "1.0")
|
||||
(company "Ourpad Networks")
|
||||
(comment 1 "Custom I2S Audio HAT for RPi 4B guitar pedal")
|
||||
(comment 2 "PCM1808 ADC + PCM5102 DAC + TL072 guitar preamp")
|
||||
(comment 3 "Stompbox form factor, 1590B compatible")
|
||||
)
|
||||
(boards (board (uuid "a1b2c3d4-e5f6-7890-abcd-ef1234567890")))
|
||||
(cvpcb
|
||||
(equivalence_files)
|
||||
)
|
||||
(design_settings
|
||||
(rules (defaults (track_width 0.254) (clearance 0.2) (via_dia 0.6) (via_drill 0.3)))
|
||||
(layers
|
||||
(layer (number 0) (name "F.Cu") (type "signal"))
|
||||
(layer (number 31) (name "B.Cu") (type "signal"))
|
||||
(layer (number 36) (name "B.Paste") (type "paste"))
|
||||
(layer (number 37) (name "F.Paste") (type "paste"))
|
||||
(layer (number 38) (name "B.SilkS") (type "user"))
|
||||
(layer (number 39) (name "F.SilkS") (type "user"))
|
||||
(layer (number 40) (name "B.Mask") (type "mask"))
|
||||
(layer (number 41) (name "F.Mask") (type "mask"))
|
||||
(layer (number 44) (name "Edge.Cuts") (type "user"))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,224 @@
|
||||
(kicad_sch (version 20240124) (generator "kicad")
|
||||
(uuid "00000000-0000-0000-0000-000000000000")
|
||||
(title_block
|
||||
(title "Pi Multi-FX Pedal — PCM1808+PCM5102 I2S HAT")
|
||||
(date "2026-06-07")
|
||||
(rev "1.0")
|
||||
(company "Ourpad Networks")
|
||||
(comment 1 "Guitar input → TL072 preamp → PCM1808 ADC → RPi I2S → PCM5102 DAC → output")
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Sheet: Page 1 — Power & Regulation
|
||||
;; ======================================================================
|
||||
(symbol (lib_id "power:GND") (at 50.8 88.9 0) (unit 1)
|
||||
(uuid "pwr-gnd-main")
|
||||
(property "Reference" "#PWR00" (at 50.8 93.98 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "GND" (at 50.8 91.44 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "power:+5V") (at 50.8 71.12 0) (unit 1)
|
||||
(uuid "pwr-5v-main")
|
||||
(property "Reference" "#PWR01" (at 50.8 67.31 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "+5V" (at 50.8 68.58 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; AMS1117-3.3 regulator
|
||||
(symbol (lib_id "Regulator_Linear:AMS1117-3.3") (at 50.8 76.2 0) (unit 1)
|
||||
(uuid "u-reg-ams1117")
|
||||
(property "Reference" "U1" (at 50.8 82.55 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "AMS1117-3.3" (at 50.8 83.82 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
;; Decoupling caps — input
|
||||
(symbol (lib_id "Device:C_Small") (at 50.8 73.66 0) (unit 1)
|
||||
(uuid "c-dec-in-1")
|
||||
(property "Reference" "C1" (at 50.8 71.12 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 50.8 72.39 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 50.8 83.82 0) (unit 1)
|
||||
(uuid "c-dec-in-2")
|
||||
(property "Reference" "C2" (at 50.8 81.28 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "100nF" (at 50.8 82.55 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
;; Output caps on 3.3V rail
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 66.04 0) (unit 1)
|
||||
(uuid "c-dec-out-1")
|
||||
(property "Reference" "C3" (at 165.1 63.5 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 165.1 64.77 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 72.39 0) (unit 1)
|
||||
(uuid "c-dec-out-2")
|
||||
(property "Reference" "C4" (at 165.1 69.85 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "100nF" (at 165.1 71.12 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Sheet: Page 2 — RPi 40-pin Header (J1)
|
||||
;; ======================================================================
|
||||
(symbol (lib_id "Connector_Generic:Conn_02x20_Odd_Even") (at 190.5 121.92 0) (unit 1)
|
||||
(uuid "j-rpi-header")
|
||||
(property "Reference" "J1" (at 190.5 111.76 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "RPi_40Pin_HDR" (at 190.5 113.03 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; I2S signals from RPi header — wired via global labels
|
||||
;; GPIO18 (BCLK) → pin 12
|
||||
;; GPIO19 (LRCLK) → pin 35
|
||||
;; GPIO20 (DIN) → pin 38
|
||||
;; GPIO21 (DOUT) → pin 40
|
||||
|
||||
;; ======================================================================
|
||||
;; Sheet: Page 3 — Guitar Input Preamp (TL072)
|
||||
;; ======================================================================
|
||||
(symbol (lib_id "Amplifier_Operational:TL072") (at 193.04 175.26 0) (unit 1)
|
||||
(uuid "u-preamp")
|
||||
(property "Reference" "U2" (at 193.04 170.18 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "TL072" (at 193.04 171.45 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; Input jack (guitar input)
|
||||
(symbol (lib_id "Connector_Generic:Jack_sound") (at 134.62 167.64 0) (unit 1)
|
||||
(uuid "j-input")
|
||||
(property "Reference" "J2" (at 134.62 162.56 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "Guitar_Input" (at 134.62 163.83 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; Input resistor R1 (1MΩ pulldown)
|
||||
(symbol (lib_id "Device:R_Small") (at 157.48 167.64 0) (unit 1)
|
||||
(uuid "r-input-pd")
|
||||
(property "Reference" "R1" (at 157.48 164.08 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "1M" (at 157.48 165.35 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; R2 (10k input resistor to op-amp non-inverting input)
|
||||
(symbol (lib_id "Device:R_Small") (at 162.56 177.8 0) (unit 1)
|
||||
(uuid "r-input-series")
|
||||
(property "Reference" "R2" (at 162.56 174.24 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10k" (at 162.56 175.51 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; R3, R4 — feedback network for gain switching
|
||||
;; Non-inverting gain = 1 + Rf/Rg
|
||||
;; Gain stage 1: Rf=100k, Rg=10k → gain = 11 (~20dB)
|
||||
(symbol (lib_id "Device:R_Small") (at 200.03 193.04 0) (unit 1)
|
||||
(uuid "r-feedback")
|
||||
(property "Reference" "R3" (at 200.03 189.48 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "100k" (at 200.03 190.75 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:R_Small") (at 208.28 193.04 0) (unit 1)
|
||||
(uuid "r-gnd-feedback")
|
||||
(property "Reference" "R4" (at 208.28 189.48 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10k" (at 208.28 190.75 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; DC-blocking cap on op-amp output before ADC
|
||||
(symbol (lib_id "Device:C_Small") (at 176.53 175.26 0) (unit 1)
|
||||
(uuid "c-dc-block")
|
||||
(property "Reference" "C5" (at 176.53 171.7 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 176.53 172.97 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Sheet: Page 4 — PCM1808 ADC + PCM5102 DAC
|
||||
;; ======================================================================
|
||||
|
||||
;; PCM1808 ADC (as generic IC — custom symbol)
|
||||
(symbol (lib_id "Device:IC") (at 149.86 233.68 0) (unit 1)
|
||||
(uuid "u-adc")
|
||||
(property "Reference" "U3" (at 149.86 227.07 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "PCM1808" (at 149.86 228.34 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; PCM5102 DAC (as generic IC)
|
||||
(symbol (lib_id "Device:IC") (at 223.52 233.68 0) (unit 1)
|
||||
(uuid "u-dac")
|
||||
(property "Reference" "U4" (at 223.52 227.07 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "PCM5102" (at 223.52 228.34 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ADC decoupling
|
||||
(symbol (lib_id "Device:C_Small") (at 139.7 231.14 0) (unit 1)
|
||||
(uuid "c-adc-dec1")
|
||||
(property "Reference" "C6" (at 139.7 227.58 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "100nF" (at 139.7 228.85 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 139.7 238.76 0) (unit 1)
|
||||
(uuid "c-adc-dec2")
|
||||
(property "Reference" "C7" (at 139.7 235.2 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 139.7 236.47 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; DAC decoupling
|
||||
(symbol (lib_id "Device:C_Small") (at 223.52 246.38 0) (unit 1)
|
||||
(uuid "c-dac-dec1")
|
||||
(property "Reference" "C8" (at 223.52 242.82 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "100nF" (at 223.52 244.09 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 223.52 254 0) (unit 1)
|
||||
(uuid "c-dac-dec2")
|
||||
(property "Reference" "C9" (at 223.52 250.44 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 223.52 251.71 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; Output jack
|
||||
(symbol (lib_id "Connector_Generic:Jack_sound") (at 241.3 233.68 0) (unit 1)
|
||||
(uuid "j-output")
|
||||
(property "Reference" "J3" (at 241.3 228.6 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "Audio_Output" (at 241.3 229.87 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; PCM5102 output filter RC (hiss reduction)
|
||||
(symbol (lib_id "Device:R_Small") (at 236.22 246.38 0) (unit 1)
|
||||
(uuid "r-dac-filter")
|
||||
(property "Reference" "R5" (at 236.22 242.82 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "330" (at 236.22 244.09 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Page 4b — I2S routing (labels)
|
||||
;; ======================================================================
|
||||
;; Global labels for I2S bus
|
||||
(symbol (lib_id "Device:C_Polarized_Small") (at 170.18 231.14 0) (unit 1)
|
||||
(uuid "c-dac-output-dc")
|
||||
(property "Reference" "C10" (at 170.18 227.58 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10µF" (at 170.18 228.85 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Sheet: Page 5 — Output stage
|
||||
;; ======================================================================
|
||||
;; Output buffer (second half of TL072)
|
||||
(symbol (lib_id "Amplifier_Operational:TL072") (at 193.04 256.54 0) (unit 2)
|
||||
(uuid "u-output-buffer")
|
||||
(property "Reference" "U2" (at 193.04 251.46 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "TL072" (at 193.04 252.73 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R_Small") (at 200.03 269.24 0) (unit 1)
|
||||
(uuid "r-output-rf")
|
||||
(property "Reference" "R6" (at 200.03 265.68 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "10k" (at 200.03 266.95 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
|
||||
;; ======================================================================
|
||||
;; Global Net Labels — I2S bus
|
||||
;; ======================================================================
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 231.14 0) (unit 1)
|
||||
(uuid "label-bclk")
|
||||
(property "Reference" "Net-" (at 165.1 231.14 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "I2S_BCLK" (at 165.1 231.14 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 235.71 0) (unit 1)
|
||||
(uuid "label-lrclk")
|
||||
(property "Reference" "Net-" (at 165.1 235.71 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "I2S_LRCLK" (at 165.1 235.71 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 240.28 0) (unit 1)
|
||||
(uuid "label-din")
|
||||
(property "Reference" "Net-" (at 165.1 240.28 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "I2S_DIN" (at 165.1 240.28 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(symbol (lib_id "Device:C_Small") (at 165.1 244.85 0) (unit 1)
|
||||
(uuid "label-dout")
|
||||
(property "Reference" "Net-" (at 165.1 244.85 0) (effects (font (size 1.27 1.27))))
|
||||
(property "Value" "I2S_DOUT" (at 165.1 244.85 0) (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
Executable
+212
@@ -0,0 +1,212 @@
|
||||
#!/bin/bash
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# install_hat.sh — Enable PCM1808+PCM5102 I2S HAT overlay + test
|
||||
# Pi Multi-FX Pedal project
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$HERE")"
|
||||
OVERLAY_SRC="${PROJECT_ROOT}/hardware/pcm1808-pcm5102-overlay.dts"
|
||||
|
||||
# ── Config paths ──────────────────────────────────────────────
|
||||
if [ -f /boot/firmware/config.txt ]; then
|
||||
CONFIG_FILE="/boot/firmware/config.txt"
|
||||
OVERLAY_DIR="/boot/firmware/overlays"
|
||||
elif [ -f /boot/config.txt ]; then
|
||||
CONFIG_FILE="/boot/config.txt"
|
||||
OVERLAY_DIR="/boot/overlays"
|
||||
else
|
||||
echo "ERROR: Cannot find config.txt"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OVERLAY_DST="${OVERLAY_DIR}/pcm1808-pcm5102-overlay.dtbo"
|
||||
|
||||
# ── Color helpers ─────────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||||
err() { echo -e "${RED}[✗]${NC} $1"; }
|
||||
|
||||
# ── Step 1: Check prerequisites ──────────────────────────────
|
||||
echo "━━━━━ PCM1808+PCM5102 I2S HAT Installer ━━━━━"
|
||||
echo ""
|
||||
|
||||
if [ ! -f "$OVERLAY_SRC" ]; then
|
||||
err "Overlay source not found: $OVERLAY_SRC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dtc &>/dev/null; then
|
||||
echo "Installing device-tree-compiler..."
|
||||
sudo apt-get update -qq && sudo apt-get install -y -qq device-tree-compiler
|
||||
fi
|
||||
|
||||
if ! command -v dtc &>/dev/null; then
|
||||
err "Failed to install device-tree-compiler"
|
||||
exit 1
|
||||
fi
|
||||
info "device-tree-compiler available"
|
||||
|
||||
# ── Step 2: Compile overlay ──────────────────────────────────
|
||||
echo ""
|
||||
echo "Compiling overlay..."
|
||||
sudo dtc -@ -I dts -O dtb -o "$OVERLAY_DST" "$OVERLAY_SRC"
|
||||
info "Overlay compiled → $OVERLAY_DST"
|
||||
|
||||
# ── Step 3: Enable overlay in config.txt ─────────────────────
|
||||
echo ""
|
||||
echo "Enabling overlay in $CONFIG_FILE..."
|
||||
|
||||
# Remove any existing pcm1808 overlay lines
|
||||
sudo sed -i '/dtoverlay=pcm1808-pcm5102-overlay/d' "$CONFIG_FILE" 2>/dev/null || true
|
||||
sudo sed -i '/dtparam=audio=off/d' "$CONFIG_FILE" 2>/dev/null || true
|
||||
sudo sed -i '/dtparam=i2s=on/d' "$CONFIG_FILE" 2>/dev/null || true
|
||||
|
||||
# Add at the end
|
||||
{
|
||||
echo ""
|
||||
echo "# ── Custom I2S HAT: PCM1808 ADC + PCM5102 DAC ──"
|
||||
echo "dtoverlay=pcm1808-pcm5102-overlay"
|
||||
echo "dtparam=audio=off"
|
||||
} | sudo tee -a "$CONFIG_FILE" > /dev/null
|
||||
|
||||
info "Overlay added to $CONFIG_FILE"
|
||||
|
||||
# ── Step 4: Create ALSA config ───────────────────────────────
|
||||
echo ""
|
||||
echo "Setting up ALSA configuration..."
|
||||
|
||||
sudo bash -c "cat > /etc/asound.conf" << 'EOCONF'
|
||||
# PCM1808+PCM5102 I2S HAT — default sound config
|
||||
pcm.!default {
|
||||
type asym
|
||||
playback.pcm { type hw card 0 device 0 }
|
||||
capture.pcm { type hw card 0 device 0 }
|
||||
}
|
||||
ctl.!default {
|
||||
type hw card 0
|
||||
}
|
||||
EOCONF
|
||||
|
||||
info "ALSA config written to /etc/asound.conf"
|
||||
|
||||
# ── Step 5: Disable onboard audio ────────────────────────────
|
||||
echo ""
|
||||
echo "Disabling onboard audio (PWM)..."
|
||||
sudo sed -i 's/^dtparam=audio=on/# dtparam=audio=on/' "$CONFIG_FILE" 2>/dev/null || true
|
||||
sudo sed -i 's/^#dtparam=audio=off/dtparam=audio=off/' "$CONFIG_FILE" 2>/dev/null || true
|
||||
|
||||
# Also mask the onboard audio kernel module
|
||||
if lsmod | grep -q "snd_bcm2835"; then
|
||||
warn "Onboard audio module loaded — will be disabled after reboot"
|
||||
fi
|
||||
|
||||
# ── Step 6: Disable PulseAudio (conflicts with JACK) ─────────
|
||||
echo ""
|
||||
echo "Masking PulseAudio for audio profile..."
|
||||
sudo systemctl mask pulseaudio.service 2>/dev/null || true
|
||||
sudo systemctl mask pulseaudio.socket 2>/dev/null || true
|
||||
info "PulseAudio masked (JACK will take over)"
|
||||
|
||||
# ── Step 7: Reboot prompt ────────────────────────────────────
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
info "Installation complete!"
|
||||
echo ""
|
||||
echo "Reboot required to load the overlay."
|
||||
echo ""
|
||||
echo "After reboot, run the test suite:"
|
||||
echo " $0 --test"
|
||||
echo ""
|
||||
echo "Or test manually:"
|
||||
echo " aplay -l # should show pcm1808pcm5102hat"
|
||||
echo " arecord -l # should show capture device"
|
||||
echo " speaker-test -t sine -f 440 -l 1"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# ── Test mode (--test flag) ──────────────────────────────────
|
||||
if [ "${1:-}" = "--test" ]; then
|
||||
echo ""
|
||||
echo "━━━━━ Running post-install tests ━━━━━"
|
||||
FAILED=0
|
||||
|
||||
# Test 1: Overlay loaded
|
||||
echo -n "Test 1: Overlay loaded... "
|
||||
if dmesg | grep -qi "pcm1808-pcm5102"; then
|
||||
info "OK (found in dmesg)"
|
||||
else
|
||||
# Try via /proc
|
||||
if grep -q "pcm1808-pcm5102" /proc/device-tree/sound/name 2>/dev/null; then
|
||||
info "OK (found in device tree)"
|
||||
else
|
||||
err "FAILED — overlay not loaded"
|
||||
FAILED=$((FAILED+1))
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test 2: ALSA playback device
|
||||
echo -n "Test 2: ALSA playback... "
|
||||
if aplay -l 2>/dev/null | grep -qi "pcm1808\|pcm5102"; then
|
||||
info "OK (card 0 found)"
|
||||
else
|
||||
err "FAILED — no playback card"
|
||||
FAILED=$((FAILED+1))
|
||||
fi
|
||||
|
||||
# Test 3: ALSA capture device
|
||||
echo -n "Test 3: ALSA capture... "
|
||||
if arecord -l 2>/dev/null | grep -qi "pcm1808\|hat"; then
|
||||
info "OK (capture device found)"
|
||||
else
|
||||
err "FAILED — no capture device"
|
||||
FAILED=$((FAILED+1))
|
||||
fi
|
||||
|
||||
# Test 4: I2S pin muxing
|
||||
echo -n "Test 4: I2S GPIO mux... "
|
||||
PIN_OK=true
|
||||
for pin in 18 19 20 21; do
|
||||
if ! raspi-gpio get "$pin" 2>/dev/null | grep -q "ALT5"; then
|
||||
PIN_OK=false
|
||||
fi
|
||||
done
|
||||
if $PIN_OK; then
|
||||
info "OK (GPIO 18-21 in ALT5)"
|
||||
else
|
||||
warn "WARN — I2S pins not all in ALT5 (check pin conflicts)"
|
||||
warn " GPIO 18-21 must be free for I2S"
|
||||
fi
|
||||
|
||||
# Test 5: Quick playback test (sine wave, 1 second)
|
||||
echo -n "Test 5: Audio playback... "
|
||||
if speaker-test -t sine -f 440 -l 1 -r 48000 -c 2 &>/dev/null; then
|
||||
info "OK (sine wave played)"
|
||||
else
|
||||
err "FAILED — speaker-test error"
|
||||
FAILED=$((FAILED+1))
|
||||
fi
|
||||
|
||||
# Test 6: Quick recording test
|
||||
echo -n "Test 6: Audio capture... "
|
||||
if arecord -d 2 -f cd -t wav /tmp/hat_test.wav 2>/dev/null; then
|
||||
FILESIZE=$(stat -c%s /tmp/hat_test.wav 2>/dev/null || echo 0)
|
||||
if [ "$FILESIZE" -gt 1000 ]; then
|
||||
info "OK (${FILESIZE} bytes recorded)"
|
||||
else
|
||||
warn "WARN — recording too small (${FILESIZE} bytes)"
|
||||
fi
|
||||
else
|
||||
err "FAILED — arecord error"
|
||||
FAILED=$((FAILED+1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ "$FAILED" -eq 0 ]; then
|
||||
info "All tests passed!"
|
||||
else
|
||||
warn "${FAILED} test(s) failed — check dmesg and wiring"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user