What is the SPI communication protocol

Humans have languages and devices have communication protocols to chat with each other. Just like languages, there are a bunch of communication protocols. When working with Arduino and electronics, you’ll only need to know just a few. SPI is among them, and you’ll tend to find it almost everywhere. Let’s learn more about it.
Basics in a few words
SPI or Serial Peripheral Interface is a synchronous serial communication interface used for short-distance communication. It is mainly used in embedded systems to transfer data from one device to another. It was designed by Motorola in 1979 and developed in the mid-1980s. It has since become an unofficial standard in the electronics community and industry.
SPI is a full-duplex interface used for communication between a controller and a peripheral device. This means that both devices can send data at the same time. SPI uses a separate clock line to synchronize the rate at which the data bits are transmitted. The data is synchronized on the rising or falling clock edge. Thus, SPI communication doesn’t rely on only one data line.
The SPI connection has four logic signals:
- SCLK: Serial Clock (output from the controller)
- COPI: Controller Out, Peripheral In (data output from the controller)
- CIPO: Controller In, Peripheral Out (data output from the peripheral)
- CS: Chip Select (output from the controller which signals that data is being sent)
One thing we like about SPI is the COPI and CIPO names for data lines. They are descriptive so you don’t have to figure out which devices the RX or TX lines are referring to.
Serial Clock is also sometimes abbreviated as CLK or SCK. The COPI line on the controller device is connected to the COPI line on the peripheral device. Likewise, CIPO on the controller is connected to the CIPO on the peripheral. Unlike the addresses concept in I2C, SPI uses the chip select, a line that indicates which peripheral will receive data. While some communication protocols can have multiple controllers, SPI always has only one controller. If you wanted to connect multiple controllers on a bus, you’d want to use a different communication protocol.
Sending data
To begin a new data transmission, the controller will first put the chip select pin from high to low. In other words, from logical 1 to logical 0. Once a peripheral is selected this way, the controller will then generate a clock and start sending data signals. To simplify this, we will first focus on only one peripheral.
Let’s send the first letter of our name with SPI. The controller will send bits of data on either the rising or falling edge of the clock signal. Let’s make it simple for this example and say it will use the rising edges.
Capital S in ASCII is 01010011. Since serial communication usually sends data with the least significant bit (LSB) first, we will reverse that order to get 11001010. When the receiver (device receiving data) detects the rising edge on the clock, it will look at the data line (COPI) to read the information bit.
Receiving data
When you want to send the data from the peripheral to the controller, you will use the separate CIPO line. As the name suggests, the data goes “in” the controller, and “out” of the peripheral. The data will be sent back on the predetermined number of clock cycles. The controller will have to know beforehand whether the peripheral will return some data and how much. If it doesn’t, it won’t know how many clock signals it should send, and some data might get lost.
Let’s look at another example. This time, let’s make the peripheral send capital E when it receives data from the controller. Capital E in ASCII is 01000101, so it will be sent as 10100010. As seen from the image below, the controller will generate two clock cycles. During the first, the controller will send data, and the peripheral will be idle. During the second cycle, the controller will be idle, and the peripheral will send some data back.
Since SPI is full-duplex, this could’ve happened simultaneously. For simpler illustration purposes, we divided this to make it clear.
Multiple peripherals configuration (Chip select)
As mentioned before, multiple peripheral devices can be connected to one SPI controller. To communicate with a peripheral, the controller will select it by enabling the CS signal. There are two ways to do this: regular mode or daisy-chain mode.
Regular mode
Let’s look at the regular mode first. The controller will have one of each SCLK, COPI, and CIPO line, but it will have multiple CS lines, depending on the number of peripherals. Peripherals can’t share the same CS line, each one must have its own.
To send data to a specific peripheral, the chip select signal needs to be enabled by the controller. This means that the signal on the CS line will be pulled low, while others remain high. This, figuratively speaking, makes the peripheral take a look at the data. All the others will see the data being sent, but since their signals are high, they won’t look at it.
The clock and data on the COPI/CIPO lines are only available to the selected peripheral. If more than one peripheral is selected (their signals are low), the data on the CIPO line will be corrupted. There will be no way for the controller to figure out which peripheral is sending the data to it.
As seen from the image below, as the number of peripheral rises, so does the number of CS lines. This easily takes up a lot of I/O pins from the controller and limits the number of peripherals. This mode sacrifices the number of peripherals that can be connected for the speed of data transmission.
Daisy-chain mode
The other mode is daisy-chain. In it, the controller and all peripherals have one of each SCLK, COPI, CIPO, and CS line. Contrasting the regular mode, in a daisy-chain mode, a single CS line goes to all connected peripherals.
The mode starts by connecting the COPI line on the controller to the COPI line on the first peripheral. Each peripheral after that connects its CIPO line to the next peripheral’s COPI line. When the last connected peripheral is reached, it will connect its CIPO line to the CIPO line on the controller. Once that happens, the CS line is then raised, which activates all the chips at the same time.
The controller will send all the data at once. The data will overflow from one peripheral to the next. Essentially, a peripheral will take the data and pass it along to its neighbor. Thus, the first bit of data sent will end up in the last peripheral. Enough data will need to be sent from the beginning for it to reach all the connected peripherals.
Imagine it like filling the water bottle, where the water is data and the bottle is the peripherals. The bottom (in our case the last peripheral) needs to be filled first. The last thing to be filled with water will be the top of the bottle (the first peripheral).
This mode is typically used in output-only systems, where the controller doesn’t need to receive any data back. You don’t necessarily need to connect the controller’s CIPO line in those situations, it won’t make a difference. However, if the data needs to be returned to the controller, keep that CIPO line connected.
Daisy-chain allows you to connect more peripherals than regular mode, at the cost of data transfer speed. One thing to keep watch out for: this mode is NOT supported by all SPI devices. Check the datasheet to see if you can connect your device this way.
SPI modes (clock polarity and clock phase)
We mentioned earlier that data bits can be sent on either rising or falling edge. So far we’ve only been talking about data transfer on the rising edge. To determine whether the data is sent on the rising or falling edge, the controller configures clock polarity (CPOL) and clock phase (CPHA).
CPOL sets the polarity of the clock signal when it is not active, or in the so-called idle state. The idle state is a period when the chip select is high and transitioning to low at the start of a transmission, as well as when it is low transitioning to high at the end of that transmission. CPHA selects the clock phase, meaning it uses rising or falling clock edge to sample and/or shift the data.
Clock polarity and phase enable the SPI communication with different types of serial devices. Both CPOL and CPHA can have two states, either 0 or 1. Four SPI modes are available depending on the states of CPOL and CPHA bits. Let’s check the table below to get a clearer view.
One thing to keep in mind, if CPHA is 0, data is captured on the first clock edge, no matter if it’s rising or falling. If CPHA is 1, the data is captured on the second clock edge. The data must be stable for a half-cycle before the first full clock cycle if this is the case. Below are some visual examples of these four SPI modes.
In SPI mode 0, there is no delay in clock pulses. The data is sampled on the rising SCLK edge and shifted out on the falling edge. The clock polarity in the idle state for this mode is low.
In SPI mode 1, the clock pulses start after a bit of delay (half-cycle). The data is sampled on the falling SCLK edge and shifted out on the rising edge. The clock polarity in the idle state for this mode is low.
In SPI mode 2, there is no delay in clock pulses. The data is sampled on the falling SCLK edge and shifted out on the rising edge. The clock polarity in the idle state for this mode is high.
In SPI mode 3, the clock pulses start after a bit of delay (half-cycle). The data is sampled on the rising SCLK edge and shifted out on the falling edge. The clock polarity in the idle state for this mode is high.
The most common modes are 0 and 3 and most SPI devices will support them.
Pros and cons of SPI
Like every other communication protocol, SPI has both benefits and drawbacks. Now that we know how it works, let’s take those pros and cons into consideration.
Pros:
- Can have multiple peripherals
- Can be used for communication with simple devices
- Full-duplex interface allowing bilateral communication
- Faster than UART and I2C protocols
- Clock defines the data rate, no manual specification is needed
- Doesn’t require data framing
Cons:
- Can only have one controller
- Uses more pins than UART and I2C
- For short distances only (less than a meter)
- Chip select takes additional pins away from the processor
- Usually requires individual CS lines for each peripheral
- Peripherals can’t talk directly to each other
Real-life applications
SPI is ubiquitous. It can be found pretty much everywhere, from consumer electronics to industrial equipment, cars, and even aerospace engines. It allows communication with simple devices. It is one of the most widely used interfaces between the microcontroller and peripheral devices, such as sensors, shift resistors, ADCs, DACs, LCDs, SD cards, and a lot more.
We use SPI quite a lot here in Soldered. It is our go-to communication protocol when working with SD cards. The reason you’ll want to use SPI in your projects is the speed of up to 8 megabits per second. Sometimes it can go even higher than that.
Now that you’re familiar with SPI communication protocol, you’ll want to learn more about both UART and I2C as well. Once you understand these three protocols, you’ll be well on your way in the maker and electronics world!
Products used in this tutorial
No products found