# ModulosDSP — ESP32-S3 WiFi Bridge for ADAU14xx DSP An Arduino sketch for the **Waveshare ESP32-S3 Zero** that provides a WiFi interface to Analog Devices ADAU1401/1701 DSP chips: - **SigmaTCP bridge** (port 8086) — lets SigmaStudio connect wirelessly to a physical DSP over I²C - **HTTP EEPROM uploader** (port 80, path `/`) — flash DSP firmware binaries to a 24C256 EEPROM from a browser - **HTTP OTA updater** (port 80, path `/ota`) — update the ESP32 firmware itself over WiFi This sketch runs on the companion **MSD ADAU14-1701 Adapter** PCB. --- ## Hardware | Component | Part | Notes | |-----------|------|-------| | Microcontroller | Waveshare ESP32-S3 Zero | Onboard WS2812 NeoPixel on GPIO 21 | | DSP | ADAU1401 / ADAU1701 | I²C address 0x68 (7-bit: 0x34) | | EEPROM | 24C256 (32 KB) | I²C address 0xA0 (7-bit: 0x50) | | Display | 20×4 hd44780 I²C LCD | Boot status and IP address (optional) | ### Pin Assignments | Signal | GPIO | |--------|------| | I²C SDA | 13 | | I²C SCL | 12 | | Status LED (NeoPixel) | 21 (built-in) | The DSP, EEPROM, and LCD all share the same I²C bus at 400 kHz. The LCD is optional — if not detected at boot the sketch continues without it. --- ## Arduino Libraries Required Install via **Sketch → Include Library → Manage Libraries**: | Library | Purpose | |---------|---------| | `WiFi` | ESP32 WiFi (built-in with ESP32 core) | | `WebServer` | HTTP server (built-in) | | `Wire` | I²C master (built-in) | | `Update` | OTA flash write (built-in with ESP32 core) | | `LittleFS` | Embedded filesystem for web assets (built-in) | | `Adafruit NeoPixel` | WS2812 status LED | | `hd44780` | I²C LCD driver | **Board:** select **ESP32S3 Dev Module** (or Waveshare ESP32-S3 Zero if your board package includes it) via the ESP32 Arduino core. --- ## Configuration Before flashing, edit `ModulosDSP_101.ino` and update the WiFi credentials: ```cpp const char* ssid = "your_network_ssid"; const char* password = "your_network_password"; ``` There is no runtime configuration — credentials are compiled in. --- ## Status LED The onboard NeoPixel (GPIO 21) shows current activity at a glance: | Color | Meaning | |-------|---------| | Off | Idle — no TCP client connected | | Green | DSP write in progress (SigmaTCP) | | Blue | DSP read in progress (SigmaTCP) | | Yellow | EEPROM write via SigmaTCP | | Magenta | EEPROM upload via HTTP | | Cyan | OTA firmware flash in progress | | Red flash | Error (I²C failure, buffer overflow, bad packet) | --- ## Using with SigmaStudio 1. Power on the board. The LCD displays the assigned IP address; Serial (115200 baud) also prints it. 2. In SigmaStudio, open **Settings → Hardware Configuration**. 3. Add a **USBi** interface and switch the connection type to **SigmaTCP**. 4. Enter the ESP32's IP address and port **8086**. 5. Click **Link → Compile Download** — SigmaStudio pushes firmware to the DSP wirelessly. The bridge handles both **direct writes** and **safeload writes** (glitch-free atomic parameter updates on a live DSP). If the connection drops mid-safeload, any partial pending slots are flushed to parameter RAM on disconnect so the DSP's internal safeload counter is clean for the next session. --- ## EEPROM Uploader (Web UI) Navigate to `http:///` in any browser: 1. Click **Choose File** and select a SigmaStudio-exported binary. 2. Optionally tick **Verify (CRC32)** to read back and confirm the write. 3. Click **Upload** — the Magenta LED pulses during the write. The 24C256 holds **32 KB**. The DSP reads this EEPROM at power-up via its SELFBOOT pin, allowing standalone operation without the ESP32 actively driving it. --- ## Firmware Update (OTA) Navigate to `http:///ota` in any browser: 1. In Arduino IDE, export the compiled binary: **Sketch → Export Compiled Binary** (produces a `.bin` file). 2. Click **Choose File** and select the `.bin`. 3. Click **Flash Firmware** — the Cyan LED indicates the write is in progress. 4. On success the device reboots automatically. The page waits 5 seconds then redirects back to `/`. --- ## How It Works ### SigmaTCP Bridge SigmaTCP is the protocol used by Analog Devices' SigmaStudio to talk to hardware like the USBi programmer. This sketch implements the server side over TCP/WiFi and forwards all register traffic to the DSP or EEPROM via I²C. **WRITE (opcode 0x09):** - 10-byte header: command, safeload flag, placement, totalLen, chipAddr, dataLen, startAddress - `totalLen` is validated against `WRITE_HDR_LEN + dataLen` before buffering — mismatched packets drop the connection - Payload forwarded to DSP or EEPROM via I²C - I²C errors are reported in the 4-byte ACK `{0x09, 0x00, 0x04, status}` so SigmaStudio sees real write failures **READ (opcode 0x0A):** - 8-byte header: command, totalLen, chipAddr, dataLen, startAddress - I²C data read in 32-byte chunks - 6-byte response header (`0x0B, totalLen_hi, totalLen_lo, status, dataLen_hi, dataLen_lo`) + payload sent back - On I²C failure, zeros are sent rather than dropping the connection (allows SigmaStudio to probe an unresponsive DSP) **Safeload:** When the safeload flag is set, parameters are queued into the DSP's 5 hardware safeload slots and committed atomically by writing `0x003C` to the Core Register. This avoids audio clicks when updating parameters on a running DSP. Any pending safeload slots are flushed at both the start and end of every TCP session to keep the DSP's internal counter in sync. The TCP receive loop drains all available bytes into a 50 KB buffer every iteration (keeping the TCP receive window open), then processes complete packets from the buffer. This correctly handles large program downloads that span multiple TCP segments. ### WiFi Watchdog The sketch monitors WiFi status every 5 seconds. If the connection drops it attempts `WiFi.reconnect()` on each check. On recovery it restarts the TCP server socket and updates the LCD with the current IP address. ### EEPROM Writes Writes are chunked to ≤28 bytes, aligned to 64-byte page boundaries. After each chunk, the firmware polls the EEPROM for ACK (up to 120 ms) to wait for its internal write cycle before continuing. ### Fixed-Point Format The ADAU1401 uses **5.23 fixed-point** for parameter RAM (4 bytes per word). Safeload registers add a leading `0x00` padding byte, making them 5 bytes. The `DataConversion` class handles conversion from `float`, `int32_t`, and other C types. --- ## File Structure ``` ModulosDSP_101/ ├── ModulosDSP_101.ino Main sketch: WiFi, TCP/HTTP servers, I²C bridge ├── DSPWriter.h DSP register write interface and address map ├── DSPWriter.cpp I²C write and safeload implementations ├── DataConversion.h 5.23 fixed-point conversion declarations ├── DataConversion.cpp Fixed-point conversion implementations ├── index_html.h Embedded HTML for the EEPROM upload web UI └── ota_html.h Embedded HTML for the OTA firmware update web UI ``` --- ## ADAU1401 Address Map | Region | Address Range | I²C bytes per register | |--------|--------------|------------------------| | Parameter RAM | 0x0000–0x03FF | 4 | | Program RAM | 0x0400–0x07FF | 5 | | Interface Registers 0–7 | 0x0800–0x0807 | 1 | | GPIO Register | 0x0808 | 1 | | ADC 0–3 (read-only) | 0x0809–0x080C | 1 | | Safeload Data 0–4 | 0x0810–0x0814 | 5 | | Safeload Address 0–4 | 0x0815–0x0819 | 2 | | Core Register | 0x081C | 2 (R0 reset) | | MpCfg 0–1 | 0x0820–0x0821 | 1 | | Analog Power Down | 0x0822 | 1 | | Analog Interface 0 | 0x0824 | 1 | --- ## Build / Version The build identifier uses `YYMMDD_rev` format (e.g. `260304_13` = 4 March 2026, revision 13). It is displayed on the LCD and printed to Serial at boot. When cutting a new build, update both the file header comment and the `version` constant in `ModulosDSP_101.ino`. --- ## References - [SigmaStudio TCP interface for ESP32 — Analog Devices forum](https://ez.analog.com/dsp/sigmadsp/f/q-a/164008/sharing-tcpi-interface-for-sigma-studio-using-esp8266-or-esp32) - [roTDSP — ADAU1401 carrier board](https://github.com/roTbear/roTDSP) - [SigmaDSP Arduino library (MCUdude)](https://github.com/MCUdude/SigmaDSP) - [Elektor AudioDSP — ESP32 + ADAU1701](https://github.com/ClemensAtElektor/Elektor_AudioDSP) - [How to program an Analog Devices DSP](https://daumemo.com/how-to-program-an-analog-devices-dsp/)