DigiRadio v2
The v2 firmware
v2 has two firmwares: the audio program that runs in the ADAU1452 DSP, and the ESP32-S31 firmware, which controls the radio, Bluetooth and the DSP.
The DSP program
v1 uses an ADAU1701, programmed with SigmaStudio. The ADAU1452 is programmed with SigmaStudio+, which can't open the old projects, so I rebuilt the program from scratch with the same audio path and the same tuning values.
The program takes 706 of the 8192 words of program memory, so the ADAU1452 has plenty of room left. The EQ and bass boost filters and the compressor curve use the same coefficients as v1. Super Bass uses a different algorithm, so its sound will have to be judged by ear.
Compared with v1 there is one more source, the ESP32, and levels are read from cells in the program.
The audio ports
The DSP generates every I²S clock, at 48 kHz, with 32-bit slots and 24-bit data. The tuner, the Bluetooth module and the ESP32 receive those clocks.
| DSP port | Connected to | Direction |
|---|---|---|
| SDATA_IN0 | Si4684 | radio input |
| SDATA_IN1 | FSC-BT1058 | Bluetooth input |
| SDATA_IN2 | ESP32-S31 | web radio input |
| SDATA_OUT0 | FSC-BT1058 | Bluetooth output |
| SDATA_OUT1 | ESP32-S31 | output to the ESP32 |
| S/PDIF | TOSLINK | optical output |
The ESP32 firmware
Everything that doesn't depend on the board is shared with v1: tuner, audio services, web server, web radio, alarms and updates. The v2 folder holds only what changes.
| v1 | v2 | |
|---|---|---|
| Module | ESP32-S3-WROOM-1 | ESP32-S31-WROOM-3-N16R16V: RISC-V, 16 MB flash and 16 MB PSRAM |
| Framework | ESP-IDF 5 | ESP-IDF 6.1, where the S31 is still a preview target |
| DSP | ADAU1701 over I²C | ADAU1452 over SPI, on the same bus as the Si4684 |
| Bluetooth | FSC-BT1035 | FSC-BT1058, UART without CTS and RTS |
| Si4684 firmware | Sent by the ESP32 at every boot | Stored once in the Si4684's W25Q16 |
| Identity EEPROM | 24AA025E48 at 0x52 | 24AA025E64 at 0x50 |
| Power | Always on | 3V3_AUDIO switched by ENABLE_ANALOG, battery read over I²C |
| Audio outputs | Bluetooth | Bluetooth and TOSLINK, generated directly by the DSP |
The ESP32 connections
The pins come from the schematic netlist. While 3V3_AUDIO is off, every pin to that domain stays high impedance, so the unpowered chips aren't fed through their protection diodes.
| Function | GPIO |
|---|---|
| Control SPI: SCLK, MOSI, MISO | 1, 2, 3 |
| Si4684: CS, RESET#, INT, SMODE | 21, 15, 16, 17 |
| ADAU1452: CS, RESET# | 20, 14 |
| I²S to the DSP: BCLK, WS, output, input | 46, 47, 48, 42 |
| BT1058: RX, TX, SYS_CTRL, RESET | 10, 11, 12, 13 |
| I²C: SCL, SDA | 50, 51 |
| ENABLE_ANALOG | 19 |
| POWER_ALERT# | 7 |
POWER_ALERT# joins the open-drain outputs of the BQ25896 charger and the MAX17048 fuel gauge on one line with one pull-up. On each alert the firmware reads both chips over I²C and clears the MAX17048 alert, which would otherwise hold the line low and hide the BQ's pulses. Periodic polling stays as a fallback, and the values show up in GET /api/health.
The boot sequence
- ENABLE_ANALOG turns on 3V3_AUDIO with the audio pins still floating.
- The ADAU1452 goes first: reset, switch to SPI mode, status check. Until it is in SPI mode it would take Si4684 traffic for I²C.
- If the DSP didn't start from the EEPROM, the ESP32 loads the program over SPI.
- The Si4684 loads its patch and checks the images in its flash with a CRC. If they differ, it rewrites them.
- The Si4684 boots from the flash. If writing failed, the ESP32 sends the images as on v1.
- The BT1058 starts in the background.
A DSP failure doesn't stop the boot: the web server and updates stay reachable.
The two memories at first boot
W25Q16, the Si4684 flash. The ESP32 can't see it directly, but the Si4684 has commands to write it (AN649, §6.5). At first boot the firmware writes the FM and DAB images, verifying each block, and from then on checks the CRC at every boot.
25AA1024, the ADAU1452 EEPROM. This one too can only be reached through its chip, and registers aren't enough: the master SPI pins, used as outputs, are driven by the DSP program. So a small "writer" program, loaded into the DSP by the ESP32, moves those pins.
The image to write is still missing, though, because SigmaStudio+ only creates it with a board connected. So at first the EEPROM stays blank and the ESP32 loads the program over SPI at every power-up. With the first prototype I'll write the EEPROM from SigmaStudio+, read it back with the firmware and put the image in the firmware, which from then on writes it to other boards by itself.
Building it
ESP-IDF 6.1 is needed. The Si4684 images aren't in the repository: the script that fetches them is described in the documentation.
idf.py --preview set-target esp32s31
idf.py build
What's left to try
- The sound, above all Super Bass and bass boost.
- Booting from the EEPROM, and the ESP32 writing the EEPROM with the writer program.
- The BT1058 AT commands, written starting from the BT1035 ones: I don't have its programming guide yet.
- Writing the W25Q16 through the Si4684.
- Calibrating the Si4684 crystal, to be redone on this board.
All open
The ESP32 firmware is in the Hardware-v2/firmware folder on GitHub, under Apache 2.0, with the full list of checks to run on the first prototype. The board itself is covered on the DigiRadio v2 page.