Day 12 · UART RX · SPI · Integration

SPI Protocol

Video 3 of 4 · ~9 minutes

Dr. Mike Borowczak · Electrical & Computer Engineering · CECS · UCF

RX OversamplingRX ImplSPIIP Integration

🌍 Where This Lives

In Industry

SD cards. SPI flash memory (where your FPGA's config bitstream lives). Accelerometers, gyroscopes, magnetometers, barometers — every MEMS sensor you've ever owned. OLED and E-ink displays. Temperature sensors. ADC/DAC chips. SD/MMC protocols layer on SPI. NAND flash uses SPI variants. SPI is the peripheral interface in the embedded world. Any time a small device needs to talk fast to a microcontroller, it's usually SPI.

In This Course

Today introduces the protocol. Your capstone may use SPI to talk to a display or an external flash. Real embedded careers spend half their time driving SPI peripherals. You'll see how SPI compares to UART (much faster, requires shared clock) and how it layers on the shift registers you already know.

⚠️ Synchronous: Clock Is Shared

❌ Wrong Model

“SPI is like UART but with more wires. Same async framing, different protocol.”

✓ Right Model

SPI is synchronous — master and slave share a common clock (SCK). The master drives SCK and MOSI (data to slave); slave drives MISO (data to master). Simultaneously on every clock edge. No baud-rate negotiation, no start/stop bits, no oversampling needed. Can run at tens or hundreds of megabits/s — orders of magnitude faster than UART. The cost: more wires (4 typically: SCK, MOSI, MISO, CS).

The receipt: Synchronous = shared clock = no timing negotiation = faster, simpler, more wires. SPI at 50 MHz moves 6.25 MB/s. UART at 115200 baud moves 11 KB/s. ~500× difference.

👁️ I Do — SPI Signals

    Master (FPGA)                          Slave (sensor, flash, ...)
    ┌─────────────┐                       ┌─────────────┐
    │       SCK ──┼───────clock──────────►│── SCK       │
    │             │                       │             │
    │      MOSI ──┼──master out, slave in►│── MOSI      │
    │             │                       │             │
    │      MISO ◄─┼──master in, slave out─┼── MISO      │
    │             │                       │             │
    │        CS ──┼───chip select (low)──►│── CS_n      │
    └─────────────┘                       └─────────────┘
    
My thinking — four signals, each named for its function:
  • SCK (clock): master drives, toggled once per bit
  • MOSI (master-out, slave-in): data from master to slave
  • MISO (master-in, slave-out): data from slave to master
  • CS_n (chip select, active-low): master asserts to begin transaction, deasserts to end

🤝 We Do — An SPI Transaction

                   ◄───── 1 byte (8 bits) ─────►
                   │                              │
   CS ────────┐                                        ┌────────
              └────────────────────────────────────────┘
                                                          (deassert)

   SCK  ─┐   ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐    ┌─────
         └───┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └────┘
         idle  ^   ^   ^   ^   ^   ^   ^   ^
               │   │   │   │   │   │   │   │
   MOSI  ─X═════╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═════X────
              D7  D6  D5  D4  D3  D2  D1  D0
              (MSB first — opposite of UART!)
    
Together: Master asserts CS, then pulses SCK 8 times. On each SCK edge, 1 bit of MOSI is driven by master and 1 bit of MISO is captured from slave. MSB-first (opposite of UART!). After 8 SCK pulses, 1 byte has been transferred in each direction simultaneously. Master can then either pulse SCK more (multi-byte transaction) or deassert CS.

UART vs. SPI vs. I²C

FeatureUARTSPII²C
Wires2 (TX, RX)3-4 (+CS per slave)2 (SCL, SDA)
ClockAsync (baud agreement)Sync (SCK shared)Sync (SCL shared)
Speed (typ.)9.6k - 1 Mbaud1 - 50+ MHz100k / 400k / 1M / 3.4M
Full-duplexYes (both directions)Yes (MOSI + MISO)No (half-duplex)
Multi-slaveNo (point-to-point)Yes (1 CS per slave)Yes (7-bit address)
Typical useConsole, debug, configurationFast peripherals: flash, display, sensorSlow/shared: sensors, I/O expanders, EEPROM
Rule of thumb: UART for console/debug. SPI for fast one-to-one peripherals. I²C for many slow devices sharing a bus. Knowing when to reach for each is a key embedded engineering skill.

🧪 You Do — Pick the Protocol

For each scenario, pick UART, SPI, or I²C:

  1. Reading a BMP180 pressure sensor (1 Hz, shared with other sensors)
  2. Streaming 24-bit audio samples at 48 kHz
  3. Debug console printing from your FPGA to your laptop
  4. Reading a bitstream from an SPI flash chip at chip config time
  5. Talking to 10 LED drivers on the same bus
Answers:
  1. I²C — shared bus, slow rate, standard sensor interface
  2. SPI — high throughput (48k × 24 = 1.15 Mbps)
  3. UART — standard console interface
  4. SPI — literally named SPI flash; MHz-rate
  5. I²C — addressable shared bus wins at 10 devices
▶ LIVE DEMO

SPI Master Talking to an ADC

~5 minutes

▸ COMMANDS

cd labs/week3_day12/ex3_spi/
cat spi_master.v    # CPOL=0, CPHA=0
make sim            # ADC model responds
make wave
# see SCK, MOSI, MISO, CS
# aligned 8-bit transaction

▸ EXPECTED STDOUT

TX byte: 0x42 (start conv)
RX byte: 0xA5 (ADC result)

PASS: CS falls, SCK toggles
PASS: 8 edges, 8 bits
PASS: MSB-first order
PASS: CS rises after transfer
=== 16 passed, 0 failed ===

▸ GTKWAVE

Signals: cs_n · sck · mosi · miso. Classic SPI waveform: CS falls, 8 SCK pulses, MOSI transmits byte MSB-first, MISO returns byte MSB-first, CS rises. Two 8-bit shift registers running synchronized — left edge to sample, right edge to shift.

🔧 SPI Modes (CPOL/CPHA)

SPI has 4 variants based on clock polarity (CPOL) and clock phase (CPHA):

ModeCPOLCPHAClock idleSample edge
000LowRising
101LowFalling
210HighFalling
311HighRising
Rule of thumb: Mode 0 is the most common; check your slave's datasheet. SPI flash and most sensors use Mode 0. Some ADCs use Mode 3. Get the mode wrong and you capture on the wrong edge — garbage data every time. Always check the datasheet.

🤖 Check the Machine

Ask AI: “Design an SPI master (mode 0) that transfers 16-bit words. Include CPOL/CPHA rationale, clock divider from 25 MHz to 1 MHz SCK, and a simple AD7476-style slave testbench.”

TASK

AI designs SPI master + TB.

BEFORE

Predict: MSB-first shift reg, SCK divider, CS state machine, 16-bit counter.

AFTER

Strong AI explains mode 0 choice. Weak AI picks one without explaining why.

TAKEAWAY

Mode choice depends on slave datasheet. AI should always reference it.

Key Takeaways

 SPI is synchronous: shared clock, no timing negotiation.

 4 wires: SCK, MOSI, MISO, CS. MSB-first (opposite of UART).

 SPI >> UART on speed (MHz vs kHz), at cost of more wires.

 4 modes (CPOL/CPHA). Check your slave's datasheet.

UART for consoles. SPI for peripherals. I²C for buses. Pick deliberately.

🔗 Transfer

IP Integration

Video 4 of 4 · ~8 minutes · Week 3 Capstone

▸ WHY THIS MATTERS NEXT

You've now built UART TX, UART RX, and SPI master — three major IP blocks. Video 4 is the Week 3 capstone: how to integrate these, plus third-party IP, into a complete system. The IP Integration Checklist you'll learn is what distinguishes junior engineers (who hack) from senior engineers (who integrate reliably).