UNIT 10 · LESSON 3 OF 6

SPI and Synchronous Serial Communication

What does it take to get it right?

INTERACTIVESPI clock polarity and phase
SPI chip select, clock and data for one byte in the chosen modeCSSCKMOSI10100101SPI mode 0: clock idles low; data is sampled on the leading edge, which is rising (redlines), and changes on the otherbyte 0xA5 = 10100101, most significant bit first
SPI chip select, clock and data for one byte in the chosen modeCSSCKMOSI10100101SPI mode 0: clock idles low; data is sampled on theleading edge, which is rising (red lines), andchanges on the otherbyte 0xA5 = 10100101, most significant bit first

Try this

CPOL (clock idle level)
CPHA (sampling edge)
Byte sent
Mode 0: sample on the rising edge.

SPI sends one bit per clock edge pair: one edge launches the next bit, the other samples it. CPOL sets the clock’s idle level; CPHA picks whether data is sampled on the first (leading) or second (trailing) edge after chip select goes low. The mode number is CPOL × 2 + CPHA. Controller and device must use the same mode; the device’s datasheet timing diagram shows which.

What you will be able to do
  • Name the SPI signals and explain why every transfer is full duplex.
  • Choose the SPI mode (CPOL, CPHA) from a device’s timing description and predict the sampling edge.
  • Connect several devices with separate chip selects and explain why MISO must be released when a device is not selected.
  • Compute the SPI clock a divider can produce and the time a transfer takes.
  • Read a device register over SPI, including the dummy bytes needed to clock data out.
Before you start
  • Synchronous versus asynchronous links (lesson 1).
  • Push-pull outputs and alternate pin functions (unit 7, lessons 1 and 2).
Steps in this lesson
  1. Four wires, one clock
  2. Clock polarity and phase
  3. Several devices
  4. Clock rate
  5. Beyond the clock limit
  6. Worked example: reading an accelerometer
  7. Common misconceptions

The puzzle

A flash memory, a display and an accelerometer share three wires to the microcontroller. The accelerometer returns 0x00 for every register, or values that look shifted by one bit. The display works only at half the speed the datasheet promises. SPI has no addresses, no acknowledgements and hardly any rules. What does it take to get it right?

STEP 1

Four wires, one clock

SPI has a controller that generates the clock and one or more devices (targets):

  • SCK, the clock, always driven by the controller;
  • MOSI (controller out, device in, also called COPI or SDO on the controller);
  • MISO (controller in, device out, CIPO);
  • CS (chip select, usually active low, one per device).

Each clock cycle shifts one bit out on MOSI and one bit in on MISO at the same time: SPI is inherently full duplex. To read, the controller must send something, often dummy 0x00 or 0xFF bytes, because only its clock makes the device shift data out. The clock runs only while there are bits to move, so the rate can be anything up to the device’s limit, and the link never needs the matched clocks a UART does.

STEP 2

Clock polarity and phase

Devices differ in which clock edge they use. CPOL sets the idle level of SCK; CPHA sets whether data is sampled on the first (leading) or second (trailing) edge after CS falls, with data changing on the other edge. The mode number is CPOL × 2 + CPHA; modes 0 and 3 are the most common.

↑ This step uses the figure at the top of the page.

With the wrong CPHA, the controller typically samples at the moment the device changes its output. The result is not random: often every byte appears shifted by one bit, or reads correctly at low speed and fails at high speed. A wrong CPOL alone (mode 0 against 3, or 1 against 2) samples on the same edge direction and may seem to work, except for the first bit after CS falls. The device datasheet’s timing diagram shows the idle clock level and the edge on which it samples.

STEP 3

Several devices

All devices share SCK, MOSI and MISO; each has its own CS. Only the selected device may drive MISO: a device whose CS is high must release it (a high-impedance output), or two devices fight over the line. CS also frames the transaction: many devices reset their command decoder when CS goes high, so a multi-byte command must keep CS low throughout. Some controllers raise their hardware CS between words, so firmware often drives CS as an ordinary GPIO to control exactly when it moves.

STEP 4

Clock rate

INTERACTIVESPI clock: what you ask for and what you get
Requested and achieved SPI clock rate and the resulting transfer timerequested10 MHzactual8.929 MHz125 MHz / (prescale 2 × post-divider 7) = 8.929 MHz: 10.7 % below the request256 bytes = 2 048 bits take at least 229 µs of clocking (1 090 KiB/s), before any gapsbetween bytes or chip-select overhead
Requested and achieved SPI clock rate and the resulting transfer timerequested10 MHzactual8.929 MHz125 MHz / (prescale 2 × post-divider 7) = 8.929 MHz:10.7 % below the request256 bytes = 2 048 bits take at least 229 µs ofclocking (1 090 KiB/s), before any gaps betweenbytes or chip-select overhead
clk_peri
Requested SPI clock
Bytes per transfer
8.929 MHz (prescale 2, post-divider 7).

The RP2040’s SPI divides clk_peri by an even prescaler (2–254) and a post-divider (1–256). For requests down to clk_peri/512, the pico-sdk’s spi_set_baudrate() picks the pair that gives the fastest rate not above the request; for slower requests (1.5.1) it returns a rate above the request. Only clk_peri divided by an even integer is possible, so a request can come out well away from what was asked. Always use the returned value.

The controller divides its clock by the ratios its hardware supports. On the RP2040, clk_peri is divided by an even prescaler and an integer post-divider, and for requests down to clk_peri/512 spi_set_baudrate() returns the fastest rate that does not exceed the request. Below that, pico-sdk 1.5.1’s prescaler search stops one step early and the result is faster than requested: 100 kHz at 125 MHz gives 122 kHz. Ask for 10 MHz with a 125 MHz clk_peri and you get 125 / 14 = 8.93 MHz; ask for 20 MHz and you get 15.6 MHz.

A transfer of N bytes needs

t≥8NfSCKt \ge \frac{8N}{f_{\text{SCK}}}

of clocking. Real transfers add gaps between bytes while software feeds the transmit FIFO, CS setup and hold times, and command bytes; at high clock rates these, not the clock, often limit throughput, and DMA (unit 12) keeps the FIFO fed.

STEP 5

Beyond the clock limit

Long wires and several devices load SCK and MISO, slowing their edges. The data from the device arrives later than it leaves: its clock-to-output delay plus the trace delay both ways must fit within the half clock period before the controller samples. When a design works at 1 MHz and fails at 20 MHz, lower the clock or shorten the wiring before suspecting the code.

STEP 6

Worked example: reading an accelerometer

A device in mode 3 returns six bytes of X, Y and Z data after a one-byte command whose top bit means “read”. The controller:

  1. drives CS low;
  2. sends the command byte (register address with the read bit set), ignoring the byte received at the same time;
  3. sends six dummy bytes, receiving the six data bytes;
  4. drives CS high.

Seven bytes are 56 bits; at 8.93 MHz that is

t≥568.93×106 Hz≈6.3 μst \ge \frac{56}{8.93 \times 10^{6}\ \text{Hz}} \approx 6.3\ \mu\text{s}

of clocking, plus whatever gaps the software leaves between bytes.

MYTHS AND FACTS

Common misconceptions

Reading needs no transmit

The controller must clock the device, and every clock also sends a bit.

The mode is just a detail

A wrong mode gives shifted or marginal data that may pass at low speed and fail at high speed.

spi_set_baudrate() gives the rate I asked for

It gives the nearest rate its search finds, usually just below the request (above it for very slow requests); use its return value.

SPI speed is set by the clock alone

Gaps between bytes, CS handling and wiring delays often dominate.

Check yourself

Answer in your head, then open the card.

A device datasheet shows the clock idling high and data being latched on the rising edge. Which mode is that?

Idle high means CPOL = 1; the first edge after CS falls is falling, so the rising edge is the trailing edge: CPHA = 1. Mode 3.

With clk_peri at 48 MHz, what does spi_set_baudrate(spi0, 10000000) return?

Prescale 2; the largest post-divider keeping the rate at or below 10 MHz is 3: 48 / 6 = 8 MHz.

Two SPI devices share MISO. Reading device A returns garbage only when device B is fitted. What is the likely fault?

Device B drives MISO while not selected: its CS is not high (for example, a floating or wrongly wired CS), or it does not release MISO. Make sure every unselected device has CS inactive.

How long does it take to read a 4096-byte page from a flash chip at 15.625 MHz, ignoring gaps and the command bytes?

8 × 4096 / 15.625 MHz ≈ 2.1 ms.

Sources (3)
  1. Linux kernel, Documentation/spi/spi-summary.rst — “CPOL=0 means the clock starts low, so the first (leading) edge is rising … CPHA=0 says sample on the leading edge, CPHA=1 means the trailing edge”; “In the SPI mode number, CPOL is the high order bit and CPHA is the low order bit”; “mode-0 and mode-3 are most commonly used”; chip selects “are usually active low”
  2. Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_spi/spi.c — spi_set_baudrate: “Prescale is an even number from 2 to 254 inclusive” (the smallest with freq_in < (prescale + 2) × 256 × baudrate), “Post-divide is an integer in the range 1 to 256 inclusive” (“Find largest post-divide which makes output <= baudrate”); returns freq_in / (prescale × postdiv)
  3. Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_spi/spi.h — spi_set_format(spi, data_bits 4..16, cpol, cpha, order): “order Must be SPI_MSB_FIRST, no other values supported on the PL022”; spi_write_read_blocking writes and reads the same number of bytes