Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

PulseView & Sigrok Firmware

ESP32-S3 firmware that turns your board into a USB logic analyzer compatible with sigrok and PulseView. No dedicated hardware needed — just an ESP32-S3 you already have.

How it works

ESP32-S3 (SUMP firmware)
  ↓ USB cable (CDC serial)
Your computer
  ↓ PulseView (ols driver)
Waveform display, 131+ protocol decoders, export

The firmware implements the SUMP protocol over USB CDC. PulseView connects to it using the built-in Openbench Logic Sniffer (ols) driver — the same driver used for Arduino-based SUMP analyzers and the original OLS FPGA board. No custom sigrok driver needed.

Why ESP32-S3

ESP32-S3 is the best ESP32 variant for this. Two reasons:

1. USB. S3 has both USB Serial/JTAG (fixed-function serial port) and USB-OTG (TinyUSB device stack). The MVP uses USB Serial/JTAG, which appears as /dev/ttyACM* on Linux or COM* on Windows. Later you can switch to USB-OTG for better throughput.

USB-OTG and USB Serial/JTAG share one PHY on ESP32-S3. You can’t use both at the same time. If you switch to OTG mode, the built-in USB flash/debug path stops working.

2. Sampling hardware. S3 has dedic_gpio — a dedicated GPIO peripheral that reads 8 GPIOs in a single CPU cycle via the Xtensa ee.get_gpio_in instruction. Combined with a tight polling loop pinned to core 1, this achieves 10-80 MSa/s on 8 channels. S3 also has RMT with GDMA for single-channel high-speed paths. C3 and C6 lack these — they only have a single I2S and fixed-function USB Serial/JTAG, making them poor choices for a general-purpose logic analyzer.

Note: The LCD_CAM peripheral on ESP32-S3 is output-only at the ESP-IDF API level (v5.3+). There is no documented camera/DVP input API. The firmware uses dedic_gpio CPU polling instead, which is simpler and comfortably exceeds the 10 MSa/s target.

C3 / C6 comparison

ESP32-S3ESP32-C3ESP32-C6
USBSerial/JTAG + OTGSerial/JTAG onlySerial/JTAG only
Parallel samplingdedic_gpio (8ch) + RMT/GDMANoNo
I2SMultiple11
VerdictBest for LALimited — few channels, low speedSame as C3

C3/C6 can work as simple SUMP devices for 1-2 channels at low speed, but don’t expect multi-channel general-purpose analysis from them.

What is sigrok

sigrok is an open-source signal analysis stack with four layers:

LayerComponentWhat it does
HardwareYour deviceCaptures digital/analog signals
Driver + firmwarelibsigrokTalks to hardware, uploads firmware, reads samples
Protocol decodinglibsigrokdecodeDecodes captured bitstreams into protocols
FrontendPulseView or sigrok-cliDisplays waveforms, annotations, exports

sigrok supports 258+ devices (logic analyzers, oscilloscopes, multimeters, power supplies). The firmware side ranges from open-source fx2lafw (for Cypress FX2 devices) to vendor blobs that need extraction.

What is SUMP

SUMP is the capture protocol between your device and the host. It’s a finite-depth capture model: the device arms, waits for a trigger, captures pre/post-trigger samples into a local buffer, then uploads everything to the host.

This matches how MCUs work — you have limited RAM, so you capture a fixed number of samples, then send them. It’s NOT a continuous streaming protocol.

PulseView and sigrok-cli connect using:

sigrok-cli --driver=ols:conn=/dev/ttyACM0

or in PulseView: device dropdown → Openbench Logic Sniffer → pick the serial port.

Protocol decoders

sigrok ships 131+ protocol decoders (Python, running in libsigrokdecode). They can be stacked — lower decoders feed into higher ones.

Common decoder chains:

Wires →Base decoder →Upper decoder
SDA, SCLI2C24xx EEPROM, EDID, HDCP
TX, RXUARTModbus RTU
TDI, TDO, TCK, TMSJTAGARM ITM, EJTAG, STM32
D+, D−USB signallingUSB packet → USB request
CLK, MOSI, MISO, CSSPISPI flash, SD card

Also supported: CAN, I2S, 1-Wire, WS2812, infrared, FlexRay, USB PD, S/PDIF, and many more. Each decoder is a Python module in libsigrokdecode/decoders/. You can write your own.

Firmware architecture

The SUMP firmware has four layers:

┌─────────────────────────────┐
│  transport                  │
│  Receives SUMP commands,    │
│  sends samples back.        │
│  USB Serial/JTAG or CDC.    │
├─────────────────────────────┤
│  capture                    │
│  Arms the sampler, waits    │
│  for trigger, captures      │
│  into the ring buffer.      │
│  Uses dedic_gpio on core 1. │
├─────────────────────────────┤
│  buffer                     │
│  Ring buffer in SRAM for    │
│  pre-trigger + post-trigger │
│  samples.                   │
├─────────────────────────────┤
│  upload                     │
│  Packs samples per SUMP     │
│  spec and sends them over   │
│  the transport.             │
└─────────────────────────────┘

The capture layer is where the ESP32-S3’s hardware matters. The dedic_gpio peripheral reads 8 GPIOs in one cycle, and a tight unrolled loop on core 1 achieves 10-80 MSa/s depending on rate limiting.

Build the firmware

The sigrok firmware is an ESP-IDF project. Build it through espctl:

1. Ask your AI assistant: "Build the sigrok firmware for esp32s3"
2. Or use the MCP Console at esphome.cloud/mcp/esp-idf
3. Or run: espctl build <project> --target esp32s3

The build produces a flash_bundle.tar.gz in the project’s build/ directory. The bundle contains manifest.json plus the bootloader, partition table, and app binaries — everything espctl flash needs in a single file. There is no separate fetch step; the bundle is returned atomically in the same session as the build.

Flash

Flash the firmware over USB:

  • From the browser: Use the Flash tab in the MCP Console or Browser Wizard.
  • From the CLI: espctl flash build/flash_bundle.tar.gz --port /dev/cu.usbmodem*

espctl flash uses the pure-Rust espflash library under the hood — no Python esptool.py dependency. Do not pip install esptool as a workaround if something goes wrong; file a bug report under docs/espctl-flash-bugs-YYYY-MM-DD.md instead so the real cause gets fixed.

After flashing, the ESP32-S3 re-enumerates as a USB CDC device. Your OS should see a new serial port (/dev/ttyACM0 on Linux, COM3 on Windows).

Two-USB-cable topology. On an ESP32-S3-DevKitC-1, the “UART” port (via the on-board USB-UART bridge) is what you flash and monitor through. The “USB” port (native USB-OTG straight to the S3 USB pins) is what sigrok-cli / PulseView talks to for SUMP data. For the full workflow — flash firmware, watch boot log, run sigrok-cli --scan against the device — keep both cables plugged in.

Connect PulseView

  1. Open PulseView.
  2. Pick the driver: Device dropdown (top-left) → Openbench Logic Sniffer → pick your serial port.
  3. Set sample rate and sample count in the toolbar.
  4. Click Run (play button).

The ESP32-S3 arms, captures samples, and uploads them. PulseView displays the waveform.

Or from the command line:

sigrok-cli --driver=ols:conn=/dev/ttyACM0 \
           --config samplerate=1M \
           --samples 1000 \
           --output-file capture.sr

Wiring

Connect the signal you want to capture to an ESP32-S3 GPIO pin. Connect ground between the ESP32-S3 and the target circuit.

Target circuit                ESP32-S3
─────────────                 ────────
Signal pin  ─────────────→  GPIO pin (input)
GND         ─────────────→  GND

Voltage warning: ESP32-S3 GPIOs are 3.3V only. Do not connect 5V signals directly — use a level shifter or voltage divider.

Protocol decoding walkthrough

After capturing:

  1. Click + next to the channel list.
  2. Pick a decoder (UART, SPI, I2C, …).
  3. Map decoder channels to your GPIO pins.
  4. PulseView decodes and shows annotations on the waveform.

Decoders stack: add I2C, then add 24xx EEPROM on top of it. The EEPROM decoder reads the I2C decoder’s output and shows memory addresses and data values.

Best for

This firmware is a protocol analysis tool, not a Saleae/FX2/FPGA replacement. Best uses:

  • Checking UART baud rates and framing
  • Verifying SPI clock polarity and chip-select timing
  • Debugging I2C address conflicts
  • Decoding 1-Wire, WS2812, infrared timing
  • Quick “is this bus alive?” checks

Limitations

  • Sample rate: 10-80 MSa/s with dedic_gpio (8 channels). Actual rate depends on loop unrolling and rate-limit settings. Not 100+ MHz like FPGA analyzers.
  • Buffer depth: Limited by ESP32-S3 SRAM (~32 KB default, up to 200 KB). SUMP is finite-depth, not streaming.
  • Input only. Captures signals — doesn’t generate them.
  • 3.3V logic only without external level shifting.
  • USB PHY shared. If you use USB-OTG mode, you lose the built-in USB Serial/JTAG flash/debug path.
  • macOS successive captures. On macOS, the kernel TTY driver caches USB CDC data across port close/open. This causes the second sigrok-cli capture to fail with “Invalid ID reply”. Workaround: power-cycle the device between captures. Linux does not have this issue.

See also