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:
2026-06-07 23:52:13 -04:00
parent 0e77adb4c3
commit 0ae2ca6e8e
8 changed files with 1269 additions and 0 deletions
+294
View File
@@ -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.
+219
View File
@@ -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)
+96
View File
@@ -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)
+116
View File
@@ -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";
};
};
+79
View File
@@ -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))
)
)
+29
View File
@@ -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"))
)
)
)
+224
View File
@@ -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))))
)
+212
View File
@@ -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