I2C-SPI: Basics (SPI)

An alternative to I2C is the Serial Peripheral Interface (SPI), which uses shift registers to shift data in and out of masters and slaves. A good analogy for how SPI works can be found in the neighborhoods of Cambodia. Here, frequent flooding and waterlogged lands limits movement on foot. In order to go to a neighbor’s house during flood season, residents will oftentimes have to swim, which can be challenging to do if the person is carrying goods to give to their neighbor. As a result, rope-and-belt system was devised to make tasks such as borrowing sugar easier. Attached to the rope would be a bucket. One neighbor would place something in the bucket, pull the rope chain to transport the bucket across the water, and the other neighbor would receive it. Then, the other neighbor would put something else in the bucket, pull his/her end of the rope chain to carry the bucket back again across the water, and the original neighbor would receive the bucket. This exchange of goods is similar to how the masters and slaves interact in SPI: by exchanging data.

Slaves in SPI have four terminals: one for shared clock, two for data exchange, and one slave select terminal. Masters have all of these terminals and potentially extra slave select terminals depending on the number of slaves. The shared clock allows for synchronous communication, just like I2C. The data exchange terminals have the names master-in, slave-out (MISO) and master-out, slave-in (MOSI). You may also see slave-out, master-in (SOMI) and slave-in, master-out (SIMO). These terms have the same function as their respective counterparts. As the names implies, the terminals specify the direction of data flow. From the master’s perspective, data is shifted out of the MOSI port and into the MISO port. From the slave’s perspective, data is shifted out of the MISO port and into the MOSI port. Finally, the slave select terminal allows the master to select a slave at will. For each slave in the SPI system, the master needs additional slave select terminals. Selecting a slave is as simple as “turning on” the slave select terminal corresponding to the target slave.

By nature of using a shift register, bits are sent sequentially, one at a time. Thus, data is transmitted serially in SPI. Additionally, since data transmission happens in both directions simultaneously, SPI is full-duplex. A simple way to see this can be shown in the figure below. As one bit, for example, is shifted out of the master’s register, it causes the slave’s register to also shift a bit out in order to receive this new bit. In doing so, the bit that was shifted out ends up in at the end of the master’s register. After all bits have been sent, the master and slave have essentially swapped data. The data originally in the slave’s register is now in the master’s register, and vice versa.

But if the master and slave are just shift registers, where does the original data come from? Wouldn’t the master and slave just exchange the same data back and forth? Similar to I2C, SPI peripherals also use buffers. The ones in SPI are known as FIFO buffers. FIFO stands for “first in, first out,” describing a data structure where the first set of data received is also the first set of data that leaves. A queue is a good example of a FIFO data structure, where the first item that enters a queue is also the first item that leaves a queue. In the context of SPI, there are two FIFO buffers used: Tx-FIFO and Rx-FIFO. As the names imply, Tx-FIFO holds data that is ready to be transmitted, where as Rx-FIFO holds data that has been received.

Because there are no wasted bits in communication and data can be received and transmitted simultaneously, SPI has relatively high communication speeds. The cost, however, is the amount of wires needed with each additional slave. Every slave in the SPI system necessitates four wires and an extra slave select terminal on the master. As such, the complexity and pinouts needed increases as the number of slaves does.