Files
pi-multifx-pedal/scripts/install_hat.sh
T
shawn 0ae2ca6e8e 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
2026-06-07 23:52:13 -04:00

212 lines
7.7 KiB
Bash
Executable File

#!/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