Initial commit: Arduino Uno Q USB Audio Synth project

- USB gadget (UAC1 + MIDI) with boot persistence
- USB host mode with auto-detection
- Pure Data synth patch with ALSA + UDP netreceive MIDI input
- MIDI rawmidi-to-UDP bridge (midi-bridge.py)
- LED matrix visualization (led-matrix-viz.py via arduino-router RPC)
- MCU sketch for LED matrix control (Arduino_RouterBridge + ArduinoGraphics)
- Conftest/OPA Rego policy validation suite for .pd files
- gen_synth_pd.py: programmatic .pd file generator
- System services: midi-bridge, led-matrix-viz, pd-synth-auto, usb-role-detect
- Justfile with deploy, enable, diagnostic recipes
- Diagnostic script (diag.sh)
This commit is contained in:
2026-06-22 22:46:36 -07:00
commit 8cd796e3dd
38 changed files with 2681 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
#!/bin/bash
# detect-usb-role.sh — Detect whether USB-C should be gadget or host.
# Writes result to /run/usb-role for consumption by pd-synth-auto.service.
#
# Detection methods (tried in order):
# 1. extcon — USB cable detection (most reliable on Qualcomm)
# 2. dwc3 debug — USB controller mode
# 3. UDC state — if a UDC is bound as configured, we're in gadget mode
# 4. lsusb — if USB devices appear (after host controller init), we're host
#
# Exit code: 0 if role detected, 1 if unknown
set -euo pipefail
ROLE_FILE="/run/usb-role"
unset ROLE
die() { echo "[USB-ROLE] $*" >&2; exit 1; }
# --- Method 1: extcon ---
check_extcon() {
for path in /sys/class/extcon/*/state; do
[ -f "$path" ] || continue
local state
state=$(cat "$path" 2>/dev/null || true)
if echo "$state" | grep -q "USB=1"; then
echo "gadget"
return 0
fi
done
return 1
}
# --- Method 2: dwc3 debugfs ---
check_dwc3() {
local mode_file
for mode_file in /sys/kernel/debug/usb/dwc3*/mode; do
[ -f "$mode_file" ] || continue
local mode
mode=$(cat "$mode_file" 2>/dev/null || true)
case "$mode" in
*peripheral*) echo "gadget"; return 0 ;;
*host*) echo "host"; return 0 ;;
esac
done
return 1
}
# --- Method 3: UDC state ---
check_udc() {
for path in /sys/class/udc/*/state; do
[ -f "$path" ] || continue
local state
state=$(cat "$path" 2>/dev/null || true)
case "$state" in
configured) echo "gadget"; return 0 ;;
esac
done
return 1
}
# --- Method 4: USB host devices ---
check_lsusb() {
if command -v lsusb &>/dev/null; then
local count
count=$(lsusb 2>/dev/null | grep -v "Linux Foundation" | wc -l)
# If we see non-root-hub devices, likely we're the host
if [ "$count" -gt 1 ]; then
echo "host"
return 0
fi
fi
return 1
}
# Try methods in order
ROLE=$(check_extcon || check_dwc3 || check_udc || echo "")
# If still unknown, check lsusb after brief delay (host controller needs time)
if [ -z "$ROLE" ]; then
sleep 2
ROLE=$(check_lsusb || echo "")
fi
# Write result
if [ -n "$ROLE" ]; then
echo "$ROLE" > "$ROLE_FILE"
echo "[USB-ROLE] Detected: $ROLE"
exit 0
else
echo "[USB-ROLE] Unknown — defaulting to gadget"
echo "gadget" > "$ROLE_FILE"
exit 0
fi