Serial Peripheral Interface (SPI)

SPI is a 4-wire common communication protocol used to communicate with ICs. It is full-duplex, meaning it can receive and transmit at the same time! We use it in our car for high-speed communication with ICs, SD card logging, and in our BMS.

Hardware:

image-20240824-062146.png

MOSI = Master out slave in = Streams binary data
MISO = Master in slave out = Receives binary data
SCLK = Serial clock = Synchronizes binary data. 4 modes to determine the sampling period
CS = Chip select = CS idles high and is pulled low when transmission starts
Standard-Speed SPI - 100 kHz to 1 MHz and High-Speed SPI - 1 MHz to 50 MHz

Clock Polarity and Phase (CPOL and CPHA):

4 SPI modes determine how the data is sampled.

image-20240824-153750.png

Mode 0: CPOL = 0, CPHA = 0 (Data is sampled on the rising edge of SCLK)
Mode 1: CPOL = 0, CPHA = 1 (Data is sampled on the falling edge of SCLK)
Mode 2: CPOL = 1, CPHA = 0 (Data is sampled on the falling edge of SCLK)
Mode 3: CPOL = 1, CPHA = 1 (Data is sampled on the rising edge of SCLK

An easy way to remember:

Polarity refers to the “idle” state. When CPOL = 1, the clock signal idles high. When CPOL = 0, the clock signal idles low.
Phase determines if you're sampling when switching from your “idle” state, or returning to it.

For example, if CPOL = 0 CPHA = 1, your idle state is 0. CPHA of 1 means we will sample the data when it returns to 0, so the falling edge of the clock signal.

If CPOL = 1 and CPHA = 0, the idle state is 1. CPHA of 0 means we will sample when we switch away from the idle state. This means we will sample on the falling edge of the clock signal.

 

Packet Protocol:

Here is an example message with the standard SPI transmission defined:

  1. Pull the CS line low, indicating the start of a transmission. It must remain low until transmission ends

  2. Generate a clock signal with the selected SPI mode (CPOL and CPHA). This determines when we sample the MOSI/MISO lines. In the example photo it is in mode 1. So CPOL = 0 and CPHA = 0. Clock speed is set by the master and must be compatible with the slave device’s specifications

  3. Transmit the Instruction [0:8]. Typically each IC defines how to communicate correctly. When getting data (reading a register) you often mark it with a READ bit. In the example, we can assume bit 8 is the WRITE/READ bit. The standard is 0 = Write, 1 = Read.

  4. Complete the Instructions [8:]. If MOSI wrote a write bit, then the SPI slave expects more data to be transmitted. If MOSI wrote a read bit (the photo example), then the SPI slave will transmit data back.

  5. End Transmission. Pulling the CS line back high releases the bus, signalling the end of the communication. Sometimes the CS line is kept low, indicating more data is being transmitted (This is how 2+ byte messages work).

 

Multi-Slave Busses

When our SPI bus has multiple slaves, we can use multiple chip select lines!

Each slave listens to the same MOSI/MISO/SCLK line, but the CS line is what enables communication. In the situation 2+ CS lines are pulled low, and both receive the same instructions, contention over the bus can occur. SPI has no built-in mechanism to prevent this. It is best practice to implement a software check to prevent multiple CS lines from being pulled low (ie: Mutexes or Binary semaphore).

 

Daisy-Chaining:

What if we have 1 chip select line for 3 slaves? That’s called daisy chaining! We use it in our AFEs LTC6811. Practically, you would only use it when all slaves are the same IC with built-in daisy chaining support.

Notice that only SLAVE 1 has direct access to the MOSI line. SLAVE 1’s output is SLAVE 2’s input. Daisy chaining relies on the fact that each IC will propagate the data onto the next slave. There will always be a 1 command cycle delay between subsequent slaves. If the CS line goes back high, each slave will process the command written to their DIN.

Consider a daisy-chained 3 slave system:
Typically we transmit a package consisting of commands for each slave. It is organized such that SLAVE 3 is the first command packet, SLAVE 2 is the second command packet and SLAVE 1 is the third command packet:

SLAVE 3 Command → SLAVE 2 Command → SLAVE 1 Command

SLAVE 3 Command is the first to be transmitted

Step 1: Transmitting SLAVE 3 Command:

  • SLAVE 1 stores SLAVE 3 Command into its shift register

Step 2: Transmitting SLAVE 2 Command:

  • SLAVE 1 now receives SLAVE 2 Command

  • SLAVE 1 passes SLAVE 3 Command to SLAVE 2

  • Slave 2 stores Slave 3 Command and passes Slave 2 Command to Slave 3

Step 3: Transmitting SLAVE 1 Command:

  • SLAVE 1 receives SLAVE 1 Command and passes SLAVE 2 Command to Slave 2

  • SLAVE 2 now holds SLAVE 2 Command and passes SLAVE 3 Command to SLAVE 3

  • SLAVE 3 receives and stores SLAVE 3 Command

Final State:

  • SLAVE 1 has its own command (Message 3 originally)

  • SLAVE 2 has the command intended for it (Message 2 originally)

  • SLAVE 3 has the command originally sent for it (Message 1 originally)

 

Basics of the SPI Communication Protocol

Serial Peripheral Interface

Daisy-Chaining SPI Devices | Analog Devices