Skip to main content SPI | IoT Worker

SPI

SPI

Not every board-level peripheral link is worth squeezing into a shared-arbitration model like I2C just to save two wires. Devices like Flash, ADCs, and display controllers often care about something else: can the host send a stream of bits steadily, quickly, and directly, then get the result back?

SPI solves exactly that kind of problem. It optimizes first for clear timing, higher throughput, and simple controller implementation rather than for pin savings when many devices share the bus. If I2C tries to keep order on two shared wires, SPI goes the other way: it gives the master stronger control first, then accepts the cost of more wires and weaker scalability.

The most stable first mental model for SPI is this: SPI is a synchronous shift exchange inside an exclusive time window defined by chip select, with the master providing the clock and both shift registers advancing on the same rhythm. CS, SCLK, MOSI, MISO, CPOL, and CPHA are all answers to three questions: are we talking to this slave now, on which edge do we change data, and on which edge do we sample it?

SPI First Solves Exclusivity, Not Addressing

The difficulty with I2C is that once the bus is shared, you first have to answer “who are we talking to this time?” SPI deliberately avoids that problem. It usually does not broadcast addresses. Instead, it gives each slave a dedicated chip-select line:

  • CS or SS: chip select, usually active low
  • SCLK: serial clock, generated by the master
  • MOSI: master out, slave in
  • MISO: master in, slave out

When the master drives one slave’s CS active, it is effectively saying, “this next window of clock and data belongs only to you.” That is direct, and the payoff is obvious:

  • no extra address phase
  • data can start moving immediately
  • slave logic is often simpler, which is especially useful for high-speed streaming transfers

The cost is just as real:

  • every extra slave usually needs another chip-select pin
  • boards with many devices feel pin pressure and wiring pressure quickly
  • it is not naturally suited to many low-speed devices sharing a common bus the way I2C is

So SPI’s main choice is not “the protocol is more advanced.” It shifts complexity away from shared arbitration and back toward board wiring and host resources.

How One Transfer Is Framed

SPI does not use START and STOP the way I2C does to broadcast transaction boundaries on a shared wire. It usually uses chip select to define the boundaries.

The most common host-side sequence is:

  1. Pull the target slave’s CS active
  2. Start outputting SCLK
  3. Shift and sample on the clock edges
  4. Stop the clock after the expected number of bits
  5. Release CS

The important judgment here is this: for many SPI devices, CS is not just “is this device selected?” It is the hard boundary for where a frame starts and where it ends.

That creates two common engineering facts:

  • some devices require CS to stay continuously active for the whole frame and will fail if it glitches
  • some devices latch commands, commit writes, or reset their internal bit counter when CS is released

So “as long as the clock is there” is a dangerous first impression. Many SPI bugs are not caused by the SCLK frequency. They are caused by CS being asserted too early, released too late, or split incorrectly by the driver.

Why SPI Is Faster

SPI’s speed advantage does not come from a fancy encoding. It comes from doing less.

It usually does not have these costs:

  • no address broadcast phase
  • no per-byte ACK/NACK
  • no arbitration or stretching on a shared bus
  • no mandatory common higher-level frame format

Once the master pulls CS low, it can start moving bits immediately. For Flash reads and writes, display pushes, and ADC sampling transfers, that “send the command and keep the data streaming” model is a very good fit.

Fast still has limits. SPI only feels “fast” when these conditions hold:

  • short board-level distance
  • the master and slave agree on clock and sampling behavior
  • line length, impedance, and signal integrity are still manageable
  • the transaction boundary is maintained correctly by software or the controller

Once the clock gets high enough, many SPI problems stop looking like protocol mistakes and start looking like electrical problems. That is one of the major differences from I2C: I2C often dies first because of the shared mechanism, while SPI often dies first because of edges and waveforms.

What Full Duplex Really Means

SPI is often introduced as a full-duplex interface, and that is technically correct. But it is easy to misread.

Full duplex does not mean every device is always sending useful data while it receives commands. It means MOSI and MISO shift in lockstep under the same clock. Every time the master toggles one clock:

  • one bit goes out on MOSI
  • one bit comes in on MISO

So the link-layer behavior is inherently synchronous in both directions.

In practice, though, many devices do not give both directions equal business meaning all the time. A very common pattern is:

  • the master sends a command or address on MOSI
  • the slave sends placeholder bits on MISO during that phase
  • only after the command phase does the slave start returning real data on MISO

So SPI is full duplex at the link layer, but often half duplex in business semantics. If you mix those two layers together, it is easy to misread a waveform or write a driver that thinks the first few bytes are “garbage” when they are actually expected placeholders.

Why Modes Keep Going Wrong in CPOL and CPHA

The common SPI bug is not the names of the wires. It is whether both ends agree on which edge is valid.

Most controllers describe SPI mode with two parameters:

  • CPOL: the clock idle level
  • CPHA: which edge data is established and sampled on

Datasheets often list Mode 0 through Mode 3 as a table, but the real thing to hold onto is this: the master and slave must agree completely on the idle level, the data transition edge, and the sampling edge.

If the mode is wrong, the result is usually not “nothing works at all.” It is the more annoying half-right failure:

  • data shifted left or right by one bit
  • high and low bits that look random
  • it seems to work at low speed, then fails badly at high speed
  • command bytes are recognized, but the data phase is scrambled

That is why mode configuration should be one of the first things to confirm during SPI debugging. It changes not one field, but the way the entire bit stream is interpreted on the edges.

Bit Order and Word Size Are Not Small Details

The first time you use SPI, it is easy to assume “8 bits per transfer, most significant bit first” is just normal. That is common, but you cannot assume every device uses it.

Typical differences include:

  • MSB first versus LSB first
  • 8-bit words, 16-bit words, or something else
  • whether command, address, and data must stay inside one chip-select window
  • whether the device expects dummy cycles, meaning placeholder clocks

These differences reflect a basic SPI fact: it provides synchronous shifting, but it does not standardize higher-level packet structure for you. Device vendors are free to define their own command widths, address widths, and response delays.

That makes SPI flexible, light, and fast. It also means the “common semantics” across devices are weak, and drivers depend heavily on the specific datasheet.

What a Typical SPI Access Looks Like

Many SPI peripherals follow a similar access pattern:

  1. Pull CS low
  2. Send the command byte
  3. Continue with address, register number, or dummy bytes
  4. The slave starts returning data at the agreed phase
  5. The master releases CS after receiving the expected number of bits

For a Flash read, that may be “read command + address + dummy cycles + data.” For a register write, it may be “write command/register number + data.” For an ADC, the master may just keep clocking so the slave can stream a sample in a fixed format.

This main flow shows the key SPI facts:

  • CS frames the transaction
  • the master owns the clock completely
  • both sides advance bit by bit instead of negotiating messages
  • higher-level meaning is mostly defined by the device’s private command format

When you look at a logic analyzer trace, it is much more useful to restore those four facts first than to stare at individual bytes.

Why Multiple Slaves Can Share One MISO Line

SPI is usually one master and many slaves, but unlike I2C it does not make everyone share the same sending right all the time. The usual rule is: only the selected slave is allowed to drive MISO; all other slaves must go high impedance.

That is how multiple slaves can share a single return line without fighting each other.

Keep three layers separate:

  • protocol intent: an unselected device should not drive the return line
  • common implementation: most standard SPI slaves tri-state their outputs when unselected
  • engineering risk: not every device, bridge chip, or board-level circuit follows that assumption perfectly

So when a multi-slave SPI bus shows strange levels on the line, you should not only check the chip-select logic. You should also suspect a device that never really released MISO, or a board-level isolation problem.

What SPI Is Most Easily Mistaken For

SPI is often mistaken for “I2C, but simpler, so once the wires are there it just works.” That is only half true.

It does have fewer shared-bus rules, and it usually does not need addresses, acknowledgments, or arbitration. But that does not mean it is easier in practice, because the complexity has moved elsewhere:

  • from shared protocol rules to chip-select and command-format management
  • from low-speed tolerance to edge, bit-order, and signal-integrity constraints
  • from a unified bus meaning to device-specific transactions defined by each datasheet

So SPI is not “a simpler I2C.” It is another tradeoff: fewer public rules, stronger master control, and heavier device-specific convention.

What To Check First in Engineering

When implementing, capturing, or debugging SPI, the first thing to verify is usually not throughput. It is the basic timing agreement.

First, check whether CS stays active in the correct window. Many devices require the whole command and data phase to stay inside one chip-select assertion, and a glitch will break the transaction.

Second, confirm the mode, meaning CPOL/CPHA. If the data looks one-bit shifted, shows occasional bit flips, or only fails at high speed, mode mismatch is the first suspect.

Third, confirm bit order and word size. If a device interprets 16-bit frames and you send two 8-bit frames, the result may be completely different.

Fourth, if a read operation returns meaningless leading bytes, do not immediately blame the link. Check whether the device defines a command phase, an address phase, or dummy cycles.

Fifth, when it becomes unstable at high speed, move your attention from “driver logic” to “waveform quality.” Too-steep edges, long traces, poor return paths, and bad termination can all make SPI look like a protocol bug at high frequency.

When It Fits and When It Does Not

SPI is a good fit for:

  • short board-level high-speed communication
  • devices like Flash, display controllers, ADCs, and DACs where throughput and direct timing matter more
  • systems where the master has enough chip-select resources and the topology is relatively simple

SPI is not a good fit for:

  • boards with many small peripherals but very limited pins
  • bus topologies that need unified discovery, addressing, and shared arbitration
  • long-distance links or casual wiring in a noisy environment

So choosing SPI is not about it being “more advanced in the spec.” It is about accepting more wires and more device-specific handling in exchange for higher speed, more direct control, and lower link-layer overhead.

Further Reading