\chapter{Hardware Overview} \label{ch:hardware} This chapter describes the board in detail: the design choices behind it, each integrated circuit and how it is controlled, the bus architecture, and the inter-chip connections. The complete hardware design --- schematics, PCB, Gerbers, and bill of materials --- is published in the repository under the CERN-OHL-S v2 licence. \section{Design philosophy} \label{sec:hw-philosophy} Every major choice on the board serves audio quality and reproducibility. \begin{drkey}[The four-chip split] Rather than a single all-in-one radio IC, DigiRadio separates concerns: a dedicated tuner for reception, a dedicated DSP for audio conditioning, a dedicated Bluetooth module for the wireless codec, and a general-purpose host to coordinate them. Each stage can be understood, measured, and improved on its own. \end{drkey} The consequences of that split run through the rest of the board: a control host that speaks several buses, a clean power tree that keeps the tuner's analogue supplies away from digital noise, and careful RF layout so the two 2.4\,GHz radios do not interfere. \section{System block diagram} \label{sec:hw-block} Four devices are coordinated by the ESP32-S3. The tuner produces the audio stream, the DSP conditions and mixes it, and the Bluetooth module transmits it; the host manages all three and provides the network interface. \begin{table}[htbp] \centering \begin{tabular}{@{}llll@{}} \drhead Device & Role & Control bus & Firmware \\ \midrule Si4684 & DAB+/FM tuner & SPI & host-loaded image \\ ADAU1701 & Audio DSP (EQ + mixer) & I\textsuperscript{2}C & host-loaded RAM \\ ESP32-S3-WROOM-1 & Host, Wi-Fi/BLE & --- & application FW \\ FSC-BT1035 & Bluetooth 5.2 (aptX Ad.) & UART (AT) & vendor FW + config \\ \bottomrule \end{tabular} \caption{Principal integrated circuits, their control bus, and how each receives its firmware or configuration.} \label{tab:hw-ics} \end{table} \section{The tuner: Si4684} \label{sec:hw-si4684} The Si4684 is a single-chip DAB+/FM receiver front-end. It delivers the decoded audio stream to the DSP and reports signal-quality metrics to the host. \subsection{Control interface} The device is controlled through a command/response protocol over its host bus. The host issues a command, then polls a clear-to-send (CTS) status bit before reading the response; the driver validates that status byte before trusting any returned payload. \begin{drkey}[SPI for the tuner] The tuner needs a large firmware image loaded at every power-up (Section~\ref{sec:hw-si4684-fw}). SPI offers substantially higher throughput than I\textsuperscript{2}C, so on DigiRadio the tuner uses \textbf{SPI}, keeping boot time short, while the low-rate DSP control uses a separate I\textsuperscript{2}C bus. \end{drkey} \subsection{Firmware image upload} \label{sec:hw-si4684-fw} The Si4684 holds no application firmware of its own at reset. At power-up the host loads a bootloader/patch and then the firmware image for the desired mode (FM or DAB). These images are large, so the driver streams them to the chip in bounded chunks read from the ESP32's flash, rather than buffering a whole image in RAM. \begin{drref}[Datasheet] The exact power-up, patch, image-load, and boot command sequence follows the Si468x programming guide (AN649). No command byte is issued without a documented source, and each step in the driver cites its section. \end{drref} \section{The audio DSP: ADAU1701} \label{sec:hw-adau} The ADAU1701 is a SigmaDSP audio processor. In DigiRadio it performs equalisation and mixes the tuner audio with the ESP32 audio source before the signal reaches the Bluetooth stage. \subsection{Control and program loading} The DSP is controlled over I\textsuperscript{2}C. Its signal-processing program is designed in SigmaStudio and exported as a sequence of register writes (control settings, program RAM, and parameter RAM). The full SigmaStudio schematic, signal chain, and runtime parameter map are documented in Chapter~\ref{ch:sigmastudio}. Driver boot, safeload API, \texttt{AudioService}, and HTTP integration are in Chapter~\ref{ch:adau1701}. \begin{drkey}[RAM boot, no EEPROM] The board deliberately omits the ADAU1701 self-boot EEPROM. Instead, the ESP32 writes the exported program into the DSP's RAM at \emph{every} boot. This keeps the audio processing under host control and field-updatable --- a new EQ or mixer configuration is a firmware update, not a chip re-programming. \end{drkey} \subsection{Click-free parameter updates} Runtime changes --- adjusting an EQ band, changing a mix level --- are applied through the ADAU1701 safeload mechanism, which updates parameter cells atomically between audio samples. Writing parameter cells directly while audio plays would produce audible clicks and is not done. \section{The Bluetooth module: FSC-BT1035} \label{sec:hw-bt1035} The FSC-BT1035 (Qualcomm QCC3056) is a Bluetooth~5.2 audio transmitter with aptX, aptX~HD, and aptX~Adaptive support --- the high-resolution codecs that make the wireless output hi-fi rather than merely convenient. \subsection{Control interface} The module is controlled with AT commands over UART, with hardware flow control (RTS/CTS). The host sends commands and parses the module's responses explicitly, treating timeouts as errors. Some settings are held in the module's own non-volatile memory. \begin{drcaution}[I\textsuperscript{2}S slave mode] The PCB routes ADAU1701 \texttt{SDATA\_OUT0} to the module over I\textsuperscript{2}S (BCLK, LRCLK, PCM data). Firmware must initialise \texttt{AT+AUXCFG=3} and \texttt{AT+I2SCFG=67}, not Line-In (\texttt{AT+AUXCFG=1}). See Chapter~\ref{ch:bt1035}, Section~\ref{sec:bt1035-i2s}. \end{drcaution} \section{The host: ESP32-S3} \label{sec:hw-esp32} The ESP32-S3-WROOM-1 coordinates the whole system. It loads the tuner and DSP firmware at boot, controls all three companion chips over their respective buses, serves the configuration web interface, and provides Wi-Fi connectivity. Its dual-core processor and generous RAM comfortably handle the firmware images and the network stack alongside the control tasks. \section{Bus architecture} \label{sec:hw-buses} The host speaks several interfaces, each chosen for its traffic: \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Bus & Devices & Purpose \\ \midrule SPI & Si4684 & fast firmware-image upload, tuner control \\ I\textsuperscript{2}C & ADAU1701, 24AA025E48 EEPROM & DSP control, device identity \\ UART & FSC-BT1035 & AT command / response (with RTS/CTS) \\ I\textsuperscript{2}S & Si4684, ESP32, ADAU1701, BT1035 & audio (ADAU is master) \\ \bottomrule \end{tabular} \caption{Interface assignment and rationale.} \label{tab:hw-buses} \end{table} \section{Power} \label{sec:hw-power} The board is powered from USB-C. An AP63203 buck converter generates the main rail from the USB input, feeding the digital and analogue sections. The tuner's sensitive supplies are derived and filtered separately to keep RF performance clean. \section{RF and antennas} \label{sec:hw-rf} Two 2.4\,GHz radios are present --- the ESP32-S3 and the Bluetooth module. Their antennas are placed on opposite diagonal corners of the board to maximise separation and minimise mutual desense. Each module keeps its antenna keep-out clear of copper on all layers. The PCB is a six-layer stack-up with controlled impedance on the USB and RF sections. \section{Inter-chip connections (GPIO map)} \label{sec:hw-gpio} This section is the authoritative wiring reference between the ESP32-S3 and the companion chips. The firmware pin definitions (\texttt{board\_pins.hpp}) must match these tables exactly. \subsection{System and control lines} \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Signal & ESP32-S3 GPIO & Notes \\ \midrule USB D$-$ & GPIO19 & native USB \\ USB D$+$ & GPIO20 & native USB \\ Reset / boot button & GPIO0 & strapping pin \\ \bottomrule \end{tabular} \caption{System and control lines.} \label{tab:hw-sys} \end{table} \subsection{Si4684 tuner (SPI)} \begin{table}[htbp] \centering \begin{tabular}{@{}llll@{}} \drhead Signal & Si4684 pin & ESP32-S3 GPIO & Notes \\ \midrule SCLK & pin 30 & GPIO13 & \\ MOSI & pin 31 & GPIO12 & \\ MISO & pin 32 & GPIO9 & \\ SSB (CS) & pin 29 & GPIO8 & chip select, active-low \\ RSTB\# & pin 4 & GPIO38 & active-low, ext.\ pull-down \\ INTB\# & pin 3 & GPIO39 & active-low, ext.\ pull-up \\ \bottomrule \end{tabular} \caption{Si4684 control and SPI lines.} \label{tab:hw-si4684} \end{table} \subsection{ADAU1701 DSP (I\textsuperscript{2}C)} \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Signal & ADAU1701 pin & ESP32-S3 GPIO \\ \midrule SDA & --- & GPIO4 \\ SCL & --- & GPIO5 \\ RESET\# & pin 5 & GPIO47 (active-low, ext.\ pull-up) \\ \bottomrule \end{tabular} \caption{ADAU1701 control (I\textsuperscript{2}C) and reset. The 7-bit I\textsuperscript{2}C address is 0x34 (ADDR0 and ADDR1 tied to GND).} \label{tab:hw-adau} \end{table} \subsection{Device-identity EEPROM (24AA025E48)} A 24AA025E48 EEPROM shares the DSP's I\textsuperscript{2}C bus. Besides a small general-purpose memory, it carries a factory-programmed, globally unique EUI-48 identifier, which the firmware can read to give each unit a stable identity --- for example a unique Bluetooth name or a device serial number. Its 7-bit address is 0x52 (A0 to GND, A1 to 3V3). \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Device & 7-bit address & Set by \\ \midrule ADAU1701 & 0x34 & ADDR0, ADDR1 = GND \\ 24AA025E48 EEPROM & 0x52 & A0 = GND, A1 = 3V3 (no A2 pin) \\ \bottomrule \end{tabular} \caption{I\textsuperscript{2}C address map (shared bus).} \label{tab:hw-i2c-addr} \end{table} \subsection{FSC-BT1035 Bluetooth} \begin{table}[htbp] \centering \begin{tabular}{@{}llll@{}} \drhead Signal & BT1035 pin & ESP32-S3 GPIO & Direction \\ \midrule SYS\_CTL & pin 34 & GPIO15 & ESP32 $\rightarrow$ BT \\ BT\_CTS & pin 15 & GPIO21 & flow control \\ BT\_RTS & pin 16 & GPIO14 & flow control \\ BT\_RX & pin 14 & GPIO40 & ESP32 TX $\rightarrow$ BT RX \\ BT\_TX & pin 13 & GPIO41 & BT TX $\rightarrow$ ESP32 RX \\ RESET & pin 8 & GPIO17 & ESP32 $\rightarrow$ BT \\ \bottomrule \end{tabular} \caption{FSC-BT1035 UART, control, and reset lines.} \label{tab:hw-bt1035} \end{table} \subsection{Audio bus (I\textsuperscript{2}S)} The audio path is a chip-to-chip I\textsuperscript{2}S bus with the ADAU1701 acting as master. Table~\ref{tab:hw-i2s} lists the chip-to-chip routing; Table~\ref{tab:hw-i2s-esp} lists the ESP32's own I\textsuperscript{2}S source lines that feed the mixer. \begin{table}[htbp] \centering \small \begin{tabular}{@{}lll@{}} \drhead Signal & Path & ADAU1701 / BT1035 pins \\ \midrule SDATA\_IN0 & Si4684 $\rightarrow$ ADAU & MP0 (pin 11) \\ SDATA\_IN1 & ESP32 $\rightarrow$ ADAU & MP1 (pin 10) \\ SDATA\_OUT0 & ADAU $\rightarrow$ BT1035 & MP6 (pin 15) $\rightarrow$ pin 5 \\ LRCLK & ADAU $\rightarrow$ BT1035 & MP4 (pin 8) + MP10 (pin 16) $\rightarrow$ pin 7 \\ BCLK & ADAU $\rightarrow$ BT1035 & MP5 (pin 9) + MP11 (pin 19) $\rightarrow$ pin 4 \\ \bottomrule \end{tabular} \caption{I\textsuperscript{2}S audio routing (chip-to-chip). The MP4/MP10 and MP5/MP11 pairs are electrically connected on the board.} \label{tab:hw-i2s} \end{table} \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Signal & ESP32-S3 GPIO & Direction \\ \midrule BCLK & GPIO6 & in from ADAU (master) \\ LRCLK & GPIO7 & in from ADAU (master) \\ SDATA\_IN1 & GPIO16 & out $\rightarrow$ ADAU MP1 \\ \bottomrule \end{tabular} \caption{ESP32 I\textsuperscript{2}S source lines feeding the mixer. The ESP32 is an I\textsuperscript{2}S slave (clocks in), transmitting audio data. SDATA\_IN1 lands on ADAU MP1 (pin 10); GPIO16 is the ESP32 module's physical pin 9.} \label{tab:hw-i2s-esp} \end{table} \subsection{Completeness} \label{sec:hw-gpio-open} \begin{drnote}[Map complete] The GPIO and I\textsuperscript{2}C maps are complete and match \texttt{board\_pins.hpp}. No values remain open. \end{drnote} This section is the authoritative wiring reference for firmware bring-up: the pin definitions in the source code must match it exactly. \section{Design validation and critical checks} \label{sec:hw-validation} This section records the design-review checks performed against the component datasheets before fabrication, chip by chip. Items marked \emph{critical} can cause permanent damage or a non-functional board if violated, and were verified explicitly. \subsection{Si4684 tuner} \label{sec:hw-val-si4684} \begin{drcaution}[Critical --- RSTB and power sequencing] The Si4684 datasheet requires that RSTB be held low during any power-supply transition and remain asserted for 10\,\textmu s after all supplies are stable; failing to do so \emph{may permanently damage the device}. On DigiRadio, RSTB (GPIO38) has an external pull-down, so the chip powers up held in reset until the ESP32 releases it. \textbf{Verified.} The firmware must not drive RSTB high before the Si4684 supplies are stable. \end{drcaution} \begin{drnote}[Firmware bring-up] RSTB is driven only in \texttt{Si4684Driver::boot()} (Chapter~\ref{ch:si4684}): GPIO38 is configured as output with \texttt{GPIO\_PULLDOWN\_ENABLE} so the net cannot glitch high while the pin mode changes, then held low for 5\,ms and released. The internal pull-down is \emph{not} redundant with the external resistor: the external pull-down holds RSTB during board power-on before \texttt{app\_main}; the internal one closes the brief window between \texttt{gpio\_config} and \texttt{gpio\_set\_level(0)} where an output register default could otherwise violate the datasheet sequencing rule. No other code touches GPIO38. Release occurs only after all Si4684 supplies (VA, VIO, VCORE, VMEM) are stable, satisfying the +10\,\textmu s requirement in practice. \end{drnote} \begin{table}[htbp] \centering \small \begin{tabular}{@{}lll@{}} \drhead Check & Requirement (datasheet) & Status \\ \midrule RSTB low at power-up & held low until supplies stable +10\,\textmu s & verified (pull-down) \\ RSTB release (firmware) & not before supplies stable; boot pulse only & verified (driver) \\ RSTB glitch guard (firmware) & \texttt{GPIO\_PULLDOWN\_ENABLE} in \texttt{gpio\_config} & verified (driver) \\ Core supplies at 1.8\,V & VA = VCORE = VMEM = 1.8\,V & verified \\ VIO level & 1.62--3.6\,V (3.3\,V to talk to ESP32) & verified \\ Bypass caps & 2.2\,nF + 1\,\textmu F per VIO/VMEM/VCORE rail & verified \\ SPI mode & Mode 0 or 3, up to 10\,MHz, SMODE = GND & verified \\ SSB framing (firmware) & SSB held low for the whole transaction & driver rule \\ INTB & interrupt line, external pull-up (GPIO39) & verified \\ \bottomrule \end{tabular} \caption{Si4684 design checks. References: \texttt{Hardware/DATASHEET/SI4684-A10.pdf} (power sequencing, SPI, supply levels) and \texttt{Hardware/DATASHEET/AN851.pdf} (bypass and layout).} \label{tab:hw-val-si4684} \end{table} \begin{drref}[Datasheet] Power sequencing and SPI framing: \texttt{Hardware/DATASHEET/SI4684-A10.pdf}. The user must not pulse SSB high between bytes; SSB frames the whole command/reply. Bypass-capacitor values and placement: \texttt{Hardware/DATASHEET/AN851.pdf}, \emph{Si468x Schematic and Layout Guide}. Boot and command protocol: AN649. Local copies: \texttt{Hardware/DATASHEET/} (see \texttt{README.md}). \end{drref} The core, memory, and analogue rails run at 1.8\,V; only VIO is at 3.3\,V to interface the ESP32. The 2.2\,nF and 1\,\textmu F bypass pairs are placed close to VIO (pin~34), VMEM (pin~35), and VCORE (pin~37) as AN851 requires. The VHF antenna input follows the AN851 layout guidance (short, narrow microstrip; ground-fill relief; ferrite beads near the connector). \subsection{ADAU1701 DSP} \label{sec:hw-val-adau} \begin{drkey}[Master-clock loopback is mandatory, not optional] For an ADAU1701 operating as I\textsuperscript{2}S master while receiving data on its serial inputs, the datasheet requires OUTPUT\_LRCLK (MP10) and OUTPUT\_BCLK (MP11) to be set to master mode and \emph{connected externally} to INPUT\_LRCLK (MP4) and INPUT\_BCLK (MP5). DigiRadio wires exactly this loopback (MP10$\rightarrow$MP4, MP11$\rightarrow$MP5). Without it the DSP locks up when input data arrives. \end{drkey} \begin{table}[htbp] \centering \small \begin{tabular}{@{}lll@{}} \drhead Check & Requirement (datasheet) & Status \\ \midrule Clock loopback & MP10$\rightarrow$MP4, MP11$\rightarrow$MP5 wired & verified \\ Output master & serial output port in Master Mode & verified \\ MCLK ratio & exactly 256\,$\times$\,f\textsubscript{S} & verified \\ MCLK value & 12.288\,MHz oscillator (256\,$\times$\,48\,kHz) & verified \\ I\textsuperscript{2}C pull-ups & 2\,k\(\Omega\) on SDA/SCL (R16/R1) & verified \\ I\textsuperscript{2}C address & 0x34 (ADDR0 = ADDR1 = GND) & verified \\ Self-boot & disabled (host RAM load) & verified \\ \bottomrule \end{tabular} \caption{ADAU1701 design checks. Reference: ADAU1701 data sheet (Rev.~C), serial-port master/slave section and I\textsuperscript{2}C port.} \label{tab:hw-val-adau} \end{table} \begin{drref}[Datasheet] Master-clock loopback and serial-port modes: \texttt{Hardware/DATASHEET/adau1701.pdf}, Rev.~C, Table~63 and the serial-port section. The master clock must be exactly 256\,$\times$\,f\textsubscript{S}. I\textsuperscript{2}C lines require pull-up resistors on SDA and SCL. DigiRadio uses \textbf{2\,k\(\Omega\)} (schematic R1/R16; ADAU1701 datasheet recommends 2.2\,k\(\Omega\) --- acceptable at 3.3\,V). \end{drref} \begin{drnote}[I\textsuperscript{2}C pull-ups confirmed] Schematic \texttt{DigitalRadio.pdf} and BOM list R1 (SCL) and R16 (SDA) as 2\,k\(\Omega\) to 3V3 on the shared ADAU1701/EEPROM bus. \end{drnote} \subsection{FSC-BT1035 (QCC3056)} \label{sec:hw-val-bt1035} \begin{table}[htbp] \centering \small \begin{tabular}{@{}lll@{}} \drhead Check & Requirement & Status \\ \midrule UART with flow control & TX/RX + RTS/CTS wired & verified \\ I\textsuperscript{2}S init (firmware) & \texttt{AT+AUXCFG=3}, \texttt{AT+I2SCFG=67} & driver rule \\ I\textsuperscript{2}S input & receives clocks from ADAU master (slave) & verified \\ Reset line & RESET (GPIO17) driven by ESP32 & verified \\ \bottomrule \end{tabular} \caption{FSC-BT1035 design checks. Datasheet: \texttt{Hardware/DATASHEET/FSC-BT1035\_Datasheet\_EN.pdf}; AT commands: \texttt{FSC-BT1035\_programming\_user\_guide\_1.1.1.pdf} ยง5.} \label{tab:hw-val-bt1035} \end{table} \begin{drref}[Programming guide defaults] Module defaults (Feasycom release 1.1.1): BR/EDR name \texttt{FSC-BT1035}, UART 115200/8/N/1, SSP on, auto-reconnect configurable via \texttt{AT+AUTOCONN=0..15}. DigiRadio overrides the name from EEPROM identity (\texttt{AT+NAME=,0} disables the module MAC suffix). \end{drref} \subsection{System-level summary} \label{sec:hw-val-summary} \begin{table}[htbp] \centering \begin{tabular}{@{}lll@{}} \drhead Area & Item & Status \\ \midrule Si4684 & RSTB pull-down, 1.8\,V rails, bypass caps, SPI & verified \\ Si4684 & RSTB release only in \texttt{Si4684Driver::boot()} & verified \\ ADAU1701 & clock loopback, master mode, 256$\times$f\textsubscript{S} & verified \\ ADAU1701 & I\textsuperscript{2}C 2\,k\(\Omega\) pull-ups (R1/R16) & verified \\ FSC-BT1035 & UART + flow control, I\textsuperscript{2}S slave & verified \\ Clocking & single 48\,kHz domain, ADAU master & verified \\ \bottomrule \end{tabular} \caption{Consolidated pre-fabrication validation status.} \label{tab:hw-val-summary} \end{table} The consolidated pre-fabrication validation is complete for all damage-class items (Si4684 power sequencing and supply levels) and the shared I\textsuperscript{2}C bus.