How DigiRadio was built

How the radio came to be, from the first board to firmware 0.13, and how the second version was reviewed with BoardLab before going to fabrication.

Where it started

I wanted a DAB+ and FM radio that sent its audio to my Bluetooth speaker without going through a phone and without losing quality. I couldn't find one, so I designed it.

The core idea never changed: a fully digital audio path, I²S at 48 kHz and 24 bits, from the tuner to the Bluetooth link. In the middle there's a DSP for equalisation, source mixing and presets. An ESP32-S3 runs everything and talks to an iPhone app.

FM / DAB+→Si4684→ I²S →ADAU1701 DSP→ I²S →BT1035→aptX

Board v1

The assembled DigiRadio v1 board

The first board is a 6-layer, 50 × 90 mm design with four main chips: the Silicon Labs Si4684 tuner, the Analog Devices ADAU1701 DSP, the FSC-BT1035 Bluetooth module with aptX Adaptive, and the ESP32-S3.

A QFN tuner, an LQFP DSP, two 2.4 GHz modules and a USB-C connector on 6 impedance-controlled layers can't be assembled by hand. The board was fabricated and assembled by PCBWay, who sponsored part of the cost. The only part they didn't stock was the BT1035, which I soldered myself.

The first weeks were spent bringing it up. Two examples:

The firmware, one version at a time

The firmware runs on the ESP32-S3, is written with ESP-IDF in C++23, and grew version by version:

One story sums up the work well: one morning the radio rebooted exactly when the alarm went off. The cause was a 4 KB buffer created on the stack for every command sent to the tuner. It worked from the app, because that task has a large stack, but the alarm task only had 6 KB. With a 64-byte buffer and more stack for the alarm the problem went away, and the next day the alarm played without a reboot.

The igiRadio app

The iPhone and iPad app is the radio's remote: stations, presets, equaliser, alarms, updates. It talks to the radio over Wi-Fi through a REST API and finds it on its own with mDNS. Audio presets live on the radio, not on the phone, so they stay even if you switch devices.

The app will soon be on the App Store for iOS, and the Android version will be available to download from this site. In the meantime, if you'd like to try it, open an issue on GitHub and you'll get the test version.

The sound: the DSP

The ADAU1701 program is designed in SigmaStudio. The ESP32 reloads it at every power-up, so it can be updated over Wi-Fi without reflashing anything.

With version 2 of the program I reworked the chain: a lighter compressor that no longer cuts the quiet passages, more headroom before the bass stage, six factory presets (Neutral, Voice, Music, Bass, Classical, Night) and up to ten user presets. Some of the SigmaStudio changes were made by script, so the project is reproducible.

Board v2

v1 works and I use it every day, but it has clear limits. https web radio streams are tight on memory, the DSP is full, and the radio only runs on mains power. v2 is designed to fix that:

The ADAU1452 is not a drop-in swap. It needs a 1.2 V rail that can reach almost 700 mA, so I added a dedicated buck converter. It comes in an LFCSP-72 package with a thermal pad, with different clocking and a different pin map. Every pin was checked against the datasheet.

So as not to rely on memory alone, I compared v2 with Analog Devices' evaluation board for the ADAU1452. That brought a few fixes: NP0 crystal capacitors, an extra 1 µF on the 1.2 V rail, ESD protection on the antenna and the right footprint for the EEPROM.

BoardLab: the review before the Gerbers

I had the v2 layout reviewed by BoardLab, a PCB analysis tool I develop myself.

What it is

KiCad's DRC checks geometric rules: clearances, widths, connections. It knows nothing about what the chips do. A board can pass DRC with zero errors and still not power up.

BoardLab starts where DRC stops. It reads the schematic and the PCB, reads the component datasheets and checks the design against them, the way an experienced colleague would in a design review:

Connections and power

Checks that every chip is powered, that mandatory pins are connected and that power domains don't back-feed each other.

Datasheet rules

Decoupling capacitors next to the right pins, short power loops, ground vias where they're needed. Every finding cites the datasheet page.

Traces and currents

Checks that power traces are wide enough for the current they carry.

Antennas and noise

Estimates how much the 2.4 GHz modules couple into nearby traces, scenario by scenario.

Ground planes

Flags plane splits under differential pairs and under switching nodes.

Each finding is classified as blocker, to review or info, together with how much of the board the analysis covered.

The subtle errors it caught

The dangerous errors are not the ones DRC sees. They are the ones that pass every KiCad check, let the board power up, and only show themselves later: with the audio off, or when the Wi-Fi transmits. BoardLab found several of them on v2, before ordering.

Chips powered through their pins

Two SPI pull-ups were on the always-on digital 3.3 V, while the chips they served are on the audio 3.3 V, which the firmware switches off. With audio off, those chips would have stayed half-powered through their pins' protection diodes: a problem that is hard to track down on the bench.

At every power-up and whenever firmware clears ENABLE_ANALOG, U13's CS and SPI/I2S inputs sit at 3.3 V while its IOVDD is 0 V, forward-biasing the input ESD diodes and phantom-powering the 3V3_AUDIO rail through the 10 kΩ pull-upsBoardLab, report 2 · PCB-U2-005

The reset next to the antenna

The DSP reset trace ran close to the ESP32 antenna. With the Wi-Fi transmitting, the DSP could have reset now and then for no visible reason. The kind of fault that is hardest to track down on the bench.

U2 radio tx radiates into U13 logic in near (60.9, 111.0) mm: about 150 mV induced against 120 mV (-2 dB margin).BoardLab, report 1 · PCB-U13-003

A buck on the edge

The enable pin of the DSP's 1.2 V regulator sat at 1.34 V against a 1.2 V threshold. It works, but with only 0.14 V of margin. One resistor change raised it to 1.65 V.

Increase the EN divider margin: change R28 from 68 kΩ to 100 kΩ (EN = 3.3 V × 100/200 = 1.65 V, margin 0.45 V over VIH max)BoardLab, report 3 · U4-070

The missing capacitor

The DSP's 1.2 V rail was missing the 1 µF capacitor the datasheet asks for on page 193. The same point came out of the evaluation board comparison.

1V2 (U13 DVDD pins 20/35/53/71) carries four 100 nF (C44, C49, C50, C64), four 10 nF (C67–C70), two 10 µF (C61, C80) and ferrite FB4; there is no 1 µF capacitor on the rail.BoardLab, report 7 · PCB-U13-007

In the first reviews it also caught big errors hidden in the hierarchical schematic: the BT1058 Bluetooth module with no power, the BQ25896 charger disconnected from USB and from the rest of the board, and the charger interrupt not reaching the ESP32. KiCad doesn't flag these, because each sheet on its own is correct.

The rest were layout refinements: 0.127 mm power traces in the inductor loops, capacitors and ground vias to move closer to the pins, a forgotten copper zone on an I²S signal.

From one report to the next

Report 4Report 6Report 7Report 12
Blockers0000
To review17222110
Info125106—88
Coverage49 %62 %—55 %

Between report 4 and report 6 the "to review" count went up, but not because the board got worse. Report 6 checked one more part and applied the layout rules from the Bluetooth module, charger and regulator datasheets. Coverage went from 49 to 62 %.

Report 7 closed every recommendation from report 6 and added a new one: a 1 µF capacitor on the DSP's 1.2 V rail, as the datasheet asks on page 193. It's the same point that came out of the evaluation board comparison.

In the end v2 reached 0 blockers, 0 DRC errors and a schematic and PCB in sync: ready for Gerbers.

How I use it

BoardLab doesn't decide for me. I check every finding against the netlist and the datasheet, then I choose. Some I accepted as they are: 18 vias under the DSP's thermal pad instead of 49 are enough for half a watt. Others were false positives, for example a badly extracted Si4684 pin table.

What matters is that the review happens before ordering, when a fix costs a click and not a new board. The result on the final board is in the commented report.

Fabrication and community

The v1 PCB was fabricated and assembled by PCBWay (except the Bluetooth module), who sponsored part of the cost, and you can order it from the project page: always kind, courteous and very professional. I'm assembling v2 myself: I order only the bare PCBs from PCBWay and solder the components on my own.

The project is also documented on Hackaday.io, on Hackster.io and on r/esp32.

Fully open

Schematic, PCB, bill of materials and firmware are on GitHub: hardware under CERN-OHL-S v2, firmware under Apache 2.0.

What's next