Prefer to click through the interactive model?

SPI — study guide

The same fragments the interactive model serves, read in order. One source, two views.

SPI — a shared clock and a select wire

SPI (Serial Peripheral Interface) is a fast serial bus for wiring a controller to the chips around it — a display, a memory, a high-rate sensor. Two things define it. It is synchronous: the controller sends a clock signal alongside the data, and that clock times every bit, so the two ends never have to agree on a speed in advance. And it is full-duplex: data moves in both directions at once, on the same clock ticks, rather than taking turns.

The other defining move is how the controller picks who it is talking to. Every peripheral on an SPI bus shares the same clock and data lines, but each one also gets its own dedicated select wire back to the controller. To talk to a particular chip, the controller activates that chip's wire; the others stay quiet and ignore the shared lines. Selection is physical — one wire per peripheral — not an address sent over the bus. Unlike a bus that shares one addressed pair among many devices or a point-to-point pair with no clock at all, SPI combines a shared clock with a per-peripheral select line.

A note on names before the mechanics. SPI grew out of a 1980s convention that labeled the two roles master and slave; current practice, following an industry resolution, calls them controller and peripheral, and this concept uses those throughout. The old data-line names MOSI and MISO still cover most datasheets, and the inclusive renaming writes them COPI and CIPO. The wires and the behavior are identical whichever labels a datasheet prints.

The four logical lines

controller (drives all) SCLK clock, controller drives MOSI / COPI controller out MISO / CIPO peripheral out three lines shared by every peripheral peripheral A peripheral B CS A: private select wire CS B: private select wire
SPI wires SCLK, MOSI, and MISO as three lines shared by every peripheral, while each peripheral also has its own private chip-select line back to the controller.

An SPI link is built from four logical lines. The first is the clock, SCLK, driven by the controller and only ever by the controller. The second and third are the data lines, and they are one-way each: MOSI carries bits from the controller out to the peripheral (controller-out, peripheral-in), and MISO carries bits the other way (controller-in, peripheral-out). The fourth is the chip-select line, CS, which the controller uses to pick which peripheral it means. In the inclusive naming the two data lines are written COPI and CIPO, but they are the same two wires.

The reason SPI is called a bus is that three of those four lines are shared. SCLK, MOSI, and MISO fan out to every peripheral on the link at once — one clock line, one outbound data line, one inbound data line, no matter how many chips hang on them. That sharing is what keeps the wire count from exploding as peripherals are added.

The one line that is not shared is CS. Every peripheral gets its own chip select back to the controller, because that private wire is how the controller singles one out from the crowd on the shared lines. So the wiring is a fixed three plus a growing one: three common lines for the whole bus, and one more select line for each peripheral the controller needs to reach.

The controller owns the clock

The clock line is what makes SPI synchronous, and it belongs entirely to the controller. The controller drives SCLK up and down, and each edge of that clock marks the instant a bit is presented and the instant it is read. A peripheral never drives the clock; it watches the edges the controller sends and moves its bits to match. The beat comes from one place, and everyone follows it. like a conductor setting a tempo the whole ensemble plays to: nobody agrees on a speed beforehand, they just follow the beat as it is given

That single shared beat is why an SPI link needs no agreed speed baked into both ends the way a clockless serial link does. When there is no clock wire, a receiver has to time each bit against a rate both sides set beforehand, and if their timing drifts apart the bits land in the wrong places. SPI sidesteps the whole problem by shipping the timing on its own wire: the receiver does not guess when to read, because the clock tells it.

The practical payoff is that the controller can simply run the clock as fast as the wiring and the peripherals will tolerate, slow it down for a fussy device, and speed it back up for a quick one — all without renegotiating anything. The timing is handed over on every edge, so changing the pace changes nothing about how the two ends stay in step.

A bit out and a bit in on every tick

full-duplex: one bit out and one bit in on the same tick controller shift register 1 0 1 1 0 0 1 0 peripheral shift register 0 1 1 0 1 0 0 1 MOSI: bit out MISO: bit in SCLK from the controller each edge shifts every register one position
On each SCLK edge the controller shifts one bit out on MOSI while shifting one bit in on MISO, so a byte is sent and a byte received cost the same clock ticks.

Full-duplex is the part of SPI that surprises people. On each clock edge the controller puts one bit onto MOSI and, at the very same edge, reads one bit off MISO. A bit leaves and a bit arrives on the same tick. Data is not flowing one direction and then the other; it is flowing both ways continuously, paced by the one clock. like two people passing cards, each handing one over at the very moment they take one back, so giving and receiving happen in a single motion instead of taking turns

The mechanism underneath is a pair of shift registers, one in the controller and one in the selected peripheral, wired into a loop. Each clock edge shifts every register along by one position: the bit that falls off the controller's end travels down MOSI into the peripheral, and the bit that falls off the peripheral's end travels back down MISO into the controller. After eight edges the controller has shifted a whole byte out and, without spending a single extra tick, shifted a whole byte in.

This is why an SPI exchange is naturally a swap. Sending a byte and receiving a byte are not two operations that cost twice the time; they are one operation. When the controller only wants to send, it ignores whatever arrives on MISO; when it only wants to receive, it shifts out a throwaway byte just to make the clock run. Either way the clock ticks the same number of times, because on this bus every bit out is a bit in.

Selecting a peripheral by its own wire

the controller pulls exactly one CS line LOW to pick a peripheral controller CS1 = HIGH (idle) CS2 = LOW (selected) CS3 = HIGH (idle) peripheral A ignores the bus peripheral B active: shifting bits peripheral C ignores the bus one wire LOW at a time -- selection is by wire, not by address
The controller selects one peripheral by pulling its chip-select line LOW; that peripheral shifts bits while the others, their chip-selects still HIGH, ignore the shared bus.

The shared clock and data lines reach every peripheral at once, so something has to decide which one is actually part of the conversation. That job falls to the chip-select lines. Each peripheral has its own CS wire back to the controller, and the line is almost always active-low: it rests HIGH, meaning ignore everything, and the controller pulls it LOW to mean this one is you. To start a transfer, the controller drives exactly one peripheral's CS low and leaves the rest high. like picking who speaks by tapping one particular person on the shoulder rather than calling a name across a crowded room and trusting the right one to answer

The selected peripheral wakes up: it watches the clock, shifts its bits onto MISO, and reads what comes in on MOSI. Every other peripheral, seeing its own CS still high, holds still and disconnects itself from the data lines even though the clock is ticking right past it. When the transfer ends the controller lets the line go high again, and the peripheral goes back to ignoring the bus.

The thing to notice is that no address is ever sent. A device on this bus is not picked out by a number the controller broadcasts and the right chip recognizes; it is picked out by which physical wire is pulled low. Selection is wiring, not messaging. That makes each peripheral trivially simple — it only has to obey one line — but it also means the controller spends a real pin on every peripheral it wants to be able to choose.

Clock polarity, phase, and the four modes

There is one setting a controller and peripheral have to agree on before their bits line up, and it concerns exactly how the clock relates to the data. Two choices are involved. Clock polarity is the level the clock sits at when idle — resting low, or resting high. Clock phase is which of the clock's two edges the bit is read on — the first edge of each cycle, or the second. Neither choice changes what SPI does; each just pins down the precise moment a bit is considered valid.

Because there are two independent yes-or-no choices, there are four combinations in total, and SPI names them the modes, numbered 0 through 3. A device's datasheet states which mode it expects, and the controller must be set to the same one. Get it wrong and the clock still ticks and the wires still carry voltages, but the two ends sample on different edges, so the receiver reads its bits half a beat out of step and the byte comes back scrambled.

For most work the mode is a single line of setup copied from the peripheral's datasheet and then forgotten. It matters that it exists — a peripheral that returns garbage on an otherwise correct wiring is often just set to the wrong mode — but the four modes are a small agreement about clock edges, not a deep mechanism to master.

Fast and simple, but a wire per peripheral

SPI's strengths all come from what it leaves out. There is no addressing, no acknowledgement, no packet framing — just a clock and some shift registers — so a peripheral can be almost trivial to build and the bus can run quickly. SPI defines no maximum clock rate at all; how fast it goes is set by the devices and the wiring, and on many parts that means comfortably into the tens of megahertz as of the mid-2020s. Being full-duplex on top of that, it can send and receive in the same ticks, which suits parts that stream data.

The cost is written on the chip-select lines. Every peripheral needs its own CS wire back to the controller, so while the clock and the two data lines are shared, the pin count still climbs by one for each device added. A handful of peripherals is fine; a dozen starts eating pins the controller would rather spend elsewhere. A bus that instead singles out devices by an address sent over shared wires pays a little protocol overhead but keeps its wire count flat as devices are added — the opposite trade.

So SPI sits at a clear point in the design space: reach for it when a peripheral is fast, or streams, or is simple enough that a bare shift-register interface is a feature, and when there are few enough devices that a select wire each is no burden. When the device count grows or pins are scarce, its one weakness — a wire per peripheral — is exactly the reason another bus might win.

Why a build reaches for SPI

On a small self-driving car the controller is wired to a spread of parts, and they do not all want the same kind of link. The ones that move a lot of data quickly are where SPI earns its place: a screen refreshed many times a second, a motion sensor read at a high rate, a camera module feeding frames. These parts want speed and often full-duplex exchange, and a fast shared-clock bus with a select wire each is a natural fit.

What makes SPI comfortable here is exactly the shape laid out in its mechanics. The clock lets the controller run each device as fast as it will go; the full-duplex lines let a command go out while a reading comes back on the same ticks; and the dedicated select wire keeps each peripheral dead simple, which matters when a build already has enough to worry about. The price — a pin per device — is easy to pay when the fast peripherals are only a few.

That is why SPI is one bus among several on a real build rather than the only one. The controller runs it for the quick, streaming, few-in-number parts, and runs other links for the many small sensors or the noisy motor electronics that suit a different trade. Knowing SPI is knowing which peripherals belong on it and why — a fast, full-duplex, wire-per-device bus, chosen where those exact traits are what the peripheral needs.