Ohmforge UART, I²C and SPI Protocol Decoder
Decode UART (auto baud), I²C and SPI from logic-analyzer or scope CSV captures.
Try an example: UART at 115200 baud, automatic detection (sigrok CSV) · I²C EEPROM write, repeated-START read and a NACK (sigrok CSV) · SPI mode 0 JEDEC ID read (one row per change) · UART 9600 8E1 with one parity error, captured by a scope (Siglent-style CSV)
How it works
Decodes serial buses from a capture: UART with automatic baud-rate detection and 5–9 data bits, parity and stop bits (8N1, 8E1, 7E1 …), I²C with START/repeated START/STOP, 7- and 10-bit addresses, read/write and ACK/NACK, and SPI in all four CPOL/CPHA modes with chip select, 4–32 bit words and MSB or LSB first. Reads sigrok/PulseView and logic-analyzer CSV (sampled or one row per change) and oscilloscope CSV, where analog channels are converted to logic levels with a threshold and hysteresis. Returns a frame table with error flags (framing, parity, break, NACK, incomplete words) and a timing diagram.
- Channels: 0/1 columns are logic channels; analog channels are converted with a Schmitt trigger (threshold midway between the IEEE 181 state levels unless given, hysteresis 10 % of the amplitude) and the edge times are interpolated. Roles are taken from the names you give, then from channel names (SCL, SDA, MOSI, MISO, CS, CLK, RX …), then by position.
- UART: a frame starts at a falling edge after idle; every bit is sampled at its centre measured from that edge. The baud rate is detected from the shortest pulse width that several pulses share, refined over all pulses up to 12 bits long, and snapped to a standard rate within 3 %. A stop bit of 0 is a framing error, all-zero data with a 0 stop bit a break.
- I²C (NXP UM10204): START/repeated START = SDA falls while SCL is high, STOP = SDA rises while SCL is high; data bits are sampled at SCL rising edges, 8 bits MSB first then the ACK bit (low = ACK). The first byte after START is the address with R/W; 11110XX starts a 10-bit address. A NACK on an address or written byte is flagged; the controller's NACK after the last byte of a read is the normal end.
- SPI: CPOL = idle clock level, CPHA = 0 samples on the leading clock edge, CPHA = 1 on the trailing edge (modes 0–3). Words are framed by chip select; a word cut off by chip select is flagged as incomplete. Without chip select, words are counted from the first clock edge.
Decoding needs a clean capture: sample at least 4× faster than the fastest bit (10× or more for UART), and use a threshold that suits the logic family. Glitches shorter than one sample are invisible. SMBus/PMBus packet error checking, UART flow control and multi-drop addressing are not interpreted.
Sources
- NXP UM10204: I²C-bus specification and user manual, Rev. 7.0 (NXP Semiconductors)
- Motorola/NXP SPI Block Guide V04.01 (clock polarity and phase) (NXP Semiconductors)
- sigrok wiki: CSV file format (output module options and header comments) (sigrok project)
Part of Ohmforge
-
Ohmforge Virtual electronics workbench
Draw a circuit, switch it on, and measure it with real-feeling bench instruments.
Related tools
- Ohmforge Oscilloscope Capture Analyzer – Scope CSV or WAV in: Vpp, RMS, frequency, duty, rise time, FFT, THD and SNR out.
- Ohmforge Transient Simulation – Simulate a circuit over time: waveforms, Vpp/RMS/frequency, CSV and a chart.
How to use the Ohmforge UART, I²C and SPI Protocol Decoder
Decode UART, I²C and SPI traffic from logic-analyzer or oscilloscope CSV captures, with automatic baud rate and error flags.
What it is for
A logic analyzer shows you ones and zeros. What you actually want to know is which bytes went over the wire. This tool decodes a captured serial bus into a table of frames, so you can see whether a sensor answered, which register was written or why a UART prints garbage.
It reads CSV exports from sigrok/PulseView, from logic-analyzer software that writes one row per change, and from oscilloscopes. Analog scope channels are converted to logic levels with a threshold and hysteresis. It decodes UART (5–9 data bits, parity, 1–2 stop bits, automatic baud rate), I²C (7- and 10-bit addresses, repeated START, ACK/NACK) and SPI in all four modes. It does not interpret higher-level protocols such as SMBus packet error checking.
Worked example
The I²C example is a sigrok CSV sampled at 1 MHz. The tool finds 3 transactions at 100 kHz (Standard-mode):
| Address | Direction | Data | Acknowledged |
|---|---|---|---|
| 0x50 | write | 0x00 0x10 | yes |
| 0x50 | read (repeated START) | 0x42 0x17 | yes |
| 0x3C | write | — | no |
This is a typical EEPROM read: the controller writes the memory address 0x0010, then reads two bytes after a repeated START. The NACK after the last read byte is the normal end of a read, so it is not counted as an error. The third transaction is flagged because no device answered at address 0x3C.
For a different case, we decoded a 400 kHz capture (one row per change) of the write 0x68, 0x6B, 0x00 and got exactly those three bytes, all acknowledged, at 400 kHz (Fast-mode). The UART example detects 115200 bit/s by itself and decodes the 18 characters "Hello, Ohmforge!" plus CR and LF without errors.
How to read the result
The frame table lists every decoded byte or word with its start time, value and error flags. For UART it also shows the character and the parity result. For I²C it shows address or data, the direction and ACK/NACK. For SPI it shows the MOSI and MISO words. The timing diagram draws the channels and the first decoded frames, with errors in red.
The summary tables group the data: I²C by transaction (START to STOP), SPI by chip-select transfer. For UART, "Received text" contains only frames without errors. The assumptions list which channel was used for each role and, for analog channels, the threshold.
Tips and common mistakes
- Sample at least 10 times faster than the UART bit rate, and at least 4 times faster than the I²C or SPI clock.
- If every UART frame has a framing error, the baud rate or the frame format is wrong. Try the detected rate, 8N1 first, and check whether the line is inverted (idle low).
- Automatic baud detection needs single-bit pulses. Text, which mixes bits, always has them. A stream of 0xF0 bytes does not, so type in the rate for such data.
- For SPI, CPOL is detected from the idle clock level, but CPHA cannot be. If the words look shifted by one bit, switch CPHA.
- Name your channels SCL, SDA, MOSI, MISO, CS or RX in the logic analyzer, and the tool will assign them by itself.
- No START found usually means SCL and SDA are swapped.
FAQ
Can I decode an oscilloscope capture instead of logic-analyzer data?
Yes. Analog channels are thresholded midway between their low and high levels, with 10 % hysteresis. You can also set your own threshold in volts, for example 1.4 V for 3.3 V logic with slow edges.
What does "NACK before the last byte of a read" mean?
The controller rejected a byte but kept reading. That breaks the I²C rule that a NACK ends the read, and it usually means a firmware bug or a glitch on SDA.
Why are my SPI words shifted?
The clock phase does not match the device. CPHA 0 samples on the first clock edge after chip select, CPHA 1 on the second. Swap the setting and decode again.
Is my capture uploaded?
In the Ohmforge workspace (Instruments → Capture analyzer…), files are read in your browser. The standalone tool and the API process the file in memory and do not keep it.
Guide last updated:
For scripts and AI agents
- JSON API:
POST https://ohmforgeprotocoldecoder.usefulweb.app/api/v1/calculate(same calculation as this page) - Interface description: OpenAPI 3.1 · AI guide: llms.txt
- MCP server (Streamable HTTP):
https://ohmforgeprotocoldecoder.usefulweb.app/mcp· tool nameohmforge_protocol_decoder
Example request
curl -s -X POST https://ohmforgeprotocoldecoder.usefulweb.app/api/v1/calculate \
-H 'content-type: application/json' \
-d '{…see OpenAPI examples…}'