# Ohmforge UART, I²C and SPI Protocol Decoder > Decode UART (auto baud), I²C and SPI from logic-analyzer or scope CSV captures. 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. Part of usefulweb.app (https://usefulweb.app/). Part of [Ohmforge](https://ohmforge.usefulweb.app/) (ownerApp: ohmforge). Results are deterministic calculations from the inputs and the listed assumptions; the API returns exactly what the web page shows. ## Use it - Human interface: https://ohmforgeprotocoldecoder.usefulweb.app/ (interactive tool at https://ohmforgeprotocoldecoder.usefulweb.app/tool) - JSON API: POST https://ohmforgeprotocoldecoder.usefulweb.app/api/v1/calculate with a JSON object of inputs (schema: https://ohmforgeprotocoldecoder.usefulweb.app/api/v1/tool) - OpenAPI: https://ohmforgeprotocoldecoder.usefulweb.app/openapi.json - MCP (Streamable HTTP): https://ohmforgeprotocoldecoder.usefulweb.app/mcp - tool `ohmforge_protocol_decoder` ## Inputs - file (file): Capture file - CSV from a scope (Rigol, Siglent, Keysight, Tektronix or any "time, channel…" table), a sigrok/PulseView or logic-analyzer CSV, or a WAV recording; up to 25 MB and 2 million rows. Files are processed in memory and not kept. - csv (textarea): Or paste the CSV text - Used when no file is uploaded. - sampleRate (number): Sample rate (only if the file has no time column) - protocol (select, required): Protocol - rx (text): UART: channel to decode - Channel name from the file header, e.g. RX, D0 or CH1. Empty = automatic. - scl (text): I²C: SCL channel - sda (text): I²C: SDA channel - sclk (text): SPI: clock channel - mosi (text): SPI: MOSI channel - "none" if not captured. - miso (text): SPI: MISO channel - "none" if not captured. - cs (text): SPI: chip-select channel - "none" if not captured. - baud (integer): UART: baud rate - Empty or 0 = detect from the shortest pulses. - dataBits (select): UART: data bits - parity (select): UART: parity - stopBits (select): UART: stop bits - inverted (boolean): UART: inverted line (idle low) - cpol (select): SPI: clock polarity (CPOL) - cpha (select): SPI: clock phase (CPHA) - wordBits (integer): SPI: bits per word - bitOrder (select): SPI: bit order - csActive (select): SPI: chip select active - threshold (number): Logic threshold for analog channels (optional) - Empty = midway between the low and high levels found in the capture. ## Method - 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. ## Limits - 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.