h0m3us3r / eSpDR
git clone https://github.com/h0m3us3r/eSpDR.git
—
+1
stars, 24h · #16,285
+~19
stars, 7 days · #8,332
+362
stars, 30 days · #2,272
362
★ total · +6% this week
36
forks · 5 open issues
Star history (as recorded here)
LanguageC++
License—
Created2026-09-25 (27d ago)
Last push21d ago
Watchers10
OwnerUser
Links
- GitHub: github.com/h0m3us3r/eSpDR
- Releases · Issues · Hacker News mentions
README excerpt
# eSpDR: 80 Msps ESP32-S3 SDR eSpDR (ESP + SDR) streams raw baseband IQ from an ESP32-S3 radio to a Linux host at 80 Msps, with lossless compression and end-to-end integrity checks. Its host tool, `iqstream`, handles capture, receiver control and the live web frontend. [code] * 80 million IQ pairs per second, I and Q as 10-bit two's complement, centred on a 2440 MHz LO (a sampled span of 2400–2480 MHz). The analog response is not flat across that span, and out-of-band signals can alias into it. The raw ESP convention is LO minus RF for I+jQ. * The whole stream is checked: every compressed record carries a CRC, and at the end the pair counts and a whole-stream CRC are reconciled across the ESP, the FPGA and the host. If the FPGA ever fails to receive a link unit (about 190 µs of samples), the stream continues and the loss is reported as an exact gap in sample time. * Typical over-the-air input compresses to about 1.2 bytes per pair, around 95–100 MB/s. The USB path sustains about 190 MB/s. Incompressible input needs 202.5 MB/s including record headers; the 256 MiB DDR buffer absorbs about 20 s of it, or about 2.5 s of a completely stalled host at typical rates. Any lost samples are counted and reported. * Receive only. * `iqstream serve` shows a live spectrum and waterfall in a web browser, with receiver controls, live stream counters and DDR buffer usage. ## About this project This project is a technical capability proof of concept and a starting point for further tinkering. Most of the implementation ideas and the system architecture are mine. All original project code was written by AI: GPT 6 Astra and Opus 5.5 took turns over about two weeks, with my direct guidance and supervision. The entire web frontend was one-shotted by Opus 5.5 with the prompt "make an SDR#-inspired WebGL-based web frontend." Getting the actual acquisition working took _much_ longer. ## How it works For the radio details, see Inside the eSpDR receiver: how the hardware supplies I/Q, PLL tuning, sample rates, filters, gain and DC/IQ correction, with results from the development measurements. ### The radio IQ path The samples come from the Wi-Fi/Bluetooth radio's internal receive path after RF downconversion. The selected radio dump format supplies signed **10-bit I and 10-bit Q**. An undocumented hardware sample-dump engine writes those pairs directly to internal SRAM. The supported dump rates are **80 million IQ pairs/s** and **16 million IQ pairs/s** (`rate=80` and `rate=16`). Radio configuration and capture live in `radio.c` and `capture.c`. ### Four SRAM banks and two CPU-driven output lanes The dump engine stores each pair in a **32-bit word**: I in bits 0–9, Q in bits 10–19, with the remaining bits unused. At 80 Msps that is **320 MB/s** entering SRAM. To keep acquisition running while completed samples are sent, the firmware rotates through four 64 KiB banks holding 16,384 pairs each. Core 0 services banks 0 and 2; core 1 services banks 1 and 3. They