FPGARelated.com

SPI

Category: Protocols | Also known as: Serial Peripheral Interface

SPI (Serial Peripheral Interface) is a synchronous serial communication protocol that is typically full-duplex, using separate clock, data-out, data-in, and chip-select lines to connect a controller device to one or more peripheral devices. It was introduced and popularized by Motorola in the mid-1980s and remains one of the most common short-distance peripheral buses in embedded systems.

In practice

SPI appears in almost every embedded product category: flash memory (W25Q series, AT45DB), SD cards, display controllers (ILI9341, ST7789), DACs, ADCs, IMUs (ICM-42688, LSM6DSO), Ethernet controllers (ENC28J60, W5500), and RF transceivers (nRF24L01, CC1101). The protocol is attractive because it is conceptually simple, has no formal standard body enforcing it, and can operate at speeds from a few kHz up to tens of MHz, depending on the peripheral and the MCU's SPI peripheral capabilities. Many MCUs support SPI clock rates in the range of roughly 10–50 MHz on their dedicated SPI peripherals, though actual limits vary widely by MCU family and peripheral.

The four standard signals are SCLK (clock), MOSI (controller-to-peripheral data), MISO (peripheral-to-controller data), and CS/SS (chip select, active-low on most devices, though some implementations differ). When multiple peripherals share the same bus, each gets its own CS line driven by the controller; only the asserted peripheral drives MISO. Because there is no addressing on the wire, the controller manages device selection entirely through GPIO. Some peripherals also support daisy-chaining, where MISO of one device feeds MOSI of the next.

A critical configuration detail is the clock polarity and phase, collectively called the SPI mode (0–3). Mode 0 (CPOL=0, CPHA=0) is the most common, but devices vary. Mismatching the SPI mode is one of the most frequent causes of garbage data when bringing up a new peripheral. Always verify CPOL and CPHA in the device datasheet, not just the mode number, since some vendors label them differently.

On the software side, SPI transfers are often done in three ways: blocking (polling the status register until the byte is shifted out), interrupt-driven (ISR fires on transfer complete), or DMA-driven (preferred for long transfers to a display or flash chip). DMA-based SPI frees the CPU entirely during bulk transfers and is commonly used when streaming pixel data to TFT displays or reading large blocks from SPI flash. One pitfall with DMA SPI is ensuring that the CS line is deasserted only after the DMA transfer is truly complete, not just after the DMA engine signals done, because the SPI shift register may still be clocking out the last byte.

Frequently asked

What is the difference between SPI modes 0, 1, 2, and 3?
The four modes are defined by two bits: CPOL (clock polarity, idle level of SCLK) and CPHA (clock phase, whether data is sampled on the leading or trailing edge). Mode 0 is CPOL=0/CPHA=0 (idle low, sample on rising edge); Mode 1 is CPOL=0/CPHA=1 (idle low, sample on falling edge); Mode 2 is CPOL=1/CPHA=0 (idle high, sample on falling edge); Mode 3 is CPOL=1/CPHA=1 (idle high, sample on rising edge). Mode 0 and Mode 3 are most common in practice. Always confirm against the peripheral datasheet timing diagrams rather than relying on the mode label alone.
How fast can SPI run?
SPI speed is limited by the slower of the MCU peripheral's maximum clock rate and the peripheral device's rated maximum. Many MCU SPI peripherals support 10–50 MHz (for example, STM32 SPI peripherals can reach up to APB clock / 2, which is 45 MHz on an STM32F4 running at 90 MHz APB). Flash memories like the W25Q128 are rated up to 104 MHz in standard single-bit mode. PCB trace length, capacitance, and level-shifter delays reduce the practical maximum in real layouts.
Does SPI support multiple controllers on the same bus?
The classic SPI topology has a single controller. Multi-controller configurations are possible but require arbitration logic or careful software coordination to prevent two controllers from driving MOSI or SCLK simultaneously. Most embedded designs stick to a single controller. If multi-master operation is needed, I2C or CAN are more commonly used protocols with built-in arbitration.
What is Quad-SPI (QSPI) and how does it differ from standard SPI?
Quad-SPI uses four data lines (IO0–IO3) instead of one, multiplying throughput by roughly four in data phases. It is widely used for external flash memory access (e.g., the QSPI peripheral on STM32F4/F7/H7 series, or the OSPI peripheral on STM32L5/U5). Some MCUs can memory-map QSPI flash so the CPU fetches code directly from it (execute-in-place, XIP). Standard SPI peripherals cannot be used for QSPI without dedicated hardware support.
Why does my SPI peripheral read back 0xFF or 0x00 for every byte?
The most common causes are: wrong SPI mode (CPOL/CPHA mismatch), CS line not asserted before the transfer begins (or released too early), MISO not connected or floating, the peripheral requiring an initialization sequence before it responds, or the clock frequency exceeding the peripheral's rated maximum. Check each in order. Scope or logic-analyze SCLK, MOSI, MISO, and CS together to verify timing before assuming a software bug.

Differentiators vs similar concepts

SPI is often compared to I2C. SPI is faster (typically 10+ MHz vs. I2C's 100 kHz–400 kHz in standard modes, up to 1 MHz in Fast-mode Plus and 3.4 MHz in High-speed mode), typically full-duplex, and requires no addressing overhead, but it uses more pins: a dedicated CS line per peripheral versus I2C's two-wire bus with 7- or 10-bit addressing. I2C is better suited for boards with many low-speed peripherals and limited pins. SPI is preferred when throughput matters (displays, flash, ADCs) or when the peripheral simply does not have an I2C interface. SPI is also sometimes confused with SSI (Synchronous Serial Interface), which is a similar clocked serial format but typically point-to-point and often unidirectional in common usage; however, SSI is a broad term applied to various vendor-specific clocked serial interfaces and implementations vary.