SPI - 180D-FW-2023/Knowledge-Base-Wiki GitHub Wiki
Introduction
Created in the 1980s by Motorola to offer an interface capable of supporting serial, synchronous, and full-duplex communications, Serial Peripheral Interface (SPI) has quickly become a mainstay in modern-day electronics. It has become one of the most commonly used interfaces in embedded systems for facilitating communication between a microcontroller and one or more peripherals due to its strong capabilities.
It functions by having one main device, known as the controller or master, provide a clock signal and chip select signals to control one or more subservient devices, known as peripherals or slaves. Its full-duplex serial protocol makes it a simpler yet stronger method of communication than its predecessors. This article will go in detail of how it works as well as its advantages/disadvantages to help determine if this is the correct protocol to use for your personal project.
SPI Properties
SPI has three main properties that make this communication protocol what it is that help determine its hardware complexity as well as its data transfer capabilities. This section explains the choice for each property as well as its counterpart to offer insight into why one was chosen over the other.
Serial vs. Parallel
In order to communicate with each other, electronic devices speak through bits in a similar fashion that we speak to each other using words formed from letters. Unlike for example the English alphabet that has 26 letters, bits are binary meaning they can only take on two values, a 0 or 1. Bits are communicated by quick changes in voltage where a 0 is represented by a short pulse of 0V and a 1 is represented by a short pulse of a higher potential, where the higher potential is determined by the operating voltage of the system such as 5V, 3.3V, etc.
Serial and parallel transmission refer to the method in which bits are transmitted between two devices. In parallel transmission, bits are transmitted in parallel across multiple lines compared to serial transmission where bits are transmitted in sequential order along the same line. Serial interfaces as a result have simpler wiring and are also less prone to crosstalk, signals creating undesired effects to other signals, among signal lines.
SPI utilizes serial transmission which helps reduce hardware complexity. Necessitating 8 data lines to generate a signal can be disadvantageous as it requires more pins on devices when you may already be limited on your main microcontroller. This also helps to reduce the number of traces that would be required on a printed circuit board to further reduce complexity in your design. Serial transmission does result in a slight suffer of speed but the simplicity it offers makes it a much more viable option to parallel and the decrease in speed is compensated by another property of SPI to be touched on.
Synchronous vs. Asynchronous
Asynchronous and synchronous refer to two methods of synchronization among data transmission. Asynchronous transmission has no control over when data is sent nor does it guarantee that both devices are operating at the same rate. Since this can be an issue if your devices are not synchronized to the same “clock”, asynchronous transmission adds start and stop bits to each byte to allow the receiver to sync up to the data as it arrives. It must also be ensured that both sides agree on the same transmission speed, such as a baud rate of 9600, otherwise the receiver will sample bits at the wrong time thus sampling the wrong bits and resulting in garbage data. Synchronous transmission offers a solution to this problem by using separate lines, one for data and one for a clock. A clock line ensures that both devices are synchronized allowing the receiver to always exactly sample the bits on the data line. The point at which data is sampled can be on either the rising edge, low to high, or falling edge, high to low, of the clock and typically is specified on datasheets of a chosen device. This also makes it such that since the clock is sent along with your data, there is no need to specify a transmission speed like with asynchronous, although some devices will have a top operating speed so that is the sole limiting factor.
SPI utilizes synchronous transmission which in turn helps to reduce hardware because the receiving device can be a simple shift register compared to the UART setup that asynchronous transmission would require. It also results in faster speeds because of the removal of overhead that is imposed by the need of a start and stop bit. One disadvantage for synchronous compared to asynchronous is the need for precisely synchronized clocks between both devices, but since SPI devices are connected utilizing a clock line, this disadvantage is no longer applicable. This makes synchronous transmission the preferred method for SPI to help give it further increased speed.
Half-Duplex vs. Full-Duplex
Duplex refers to a point-to-point communication system composed of two or more devices that allows for communication with each other in either direction. There are two types of duplex systems you can have, half-duplex and full-duplex. Half-duplex supports bidirectional communication but only one device can transmit at a time. This means that a device cannot both transmit and receive data simultaneously but can only do one at a time. This is in contrast to full-duplex which allows for simultaneous transmission between both devices meaning they can each transmit while simultaneously receiving the other’s data.
SPI employs a full-duplex system allowing for simultaneous transmission between the main controller and its peripherals. This allows for much faster transmission speeds since there is no need to delay sending data to avoid collisions. Having two signal lines allows for data to be sent and received simultaneously and independently of each other. This can result in complex hardware which will increase the cost, but the substantial gain in speed outweighs the negatives.
How does it work?
SPI is commonly implemented through the use of a 4-wire configuration: a line for the main to send data to the peripheral, a line for the peripheral to send data to the main, a line for the clock, and a line for the main to choose what peripheral to send data to. The names for the lines are typically MOSI, MISO, SCK, and SS with movement to change these names due to the culturally sensitive nature of master and slave as part of the naming convention. It is common to see master replaced with controller, slave replaced with peripheral, and SS replaced with CS.
SCK
The SCK (serial clock) line is responsible for generating the clock signal that synchronizes the controller with its peripherals. The controller generates the clock signal which will synchronize to sampling of the bits by the peripheral. The frequency of the clock signal will determine the speed at which data is transferred between your controller and its peripherals.
CS
The CS (chip select) line is responsible for allowing the controller to choose which peripheral it should communicate with. It does so by writing a low signal to activate the peripheral and writing a high signal to disconnect the peripheral from the SPI bus. A controller can have multiple chip select pins allowing for multiple peripherals to be wired in parallel, which means theoretically you can have an infinite number of peripherals so long as you have sufficient pins on your controller. It is also possible to only utilize one CS pin which would then require you to daisy-chain your peripherals together by connecting the MISO of one peripheral to the MOSI of the next peripheral.
MOSI/MISO
The MOSI (master output slave input) and MISO (master input slave output) lines are responsible for data transmission between the controller and its peripheral. The MOSI line is utilized for the controller to send data to its peripheral while the MISO line is utilized for the peripheral to send data to its controller. Separation of the data lines is what allows SPI to exhibit a full-duplex system since data can be both sent and received by both devices.
Interfacing
There are multiple ways to interface SPI depending on the amount of peripherals you are utilizing. The controller will typically be a microcontroller of your preference but the amount of peripherals will vary the wiring. For one peripheral it’s pretty simple: SCK connects to SCK, MOSI connects to MOSI, MISO connects to MISO, CS connects to CS. For multiple peripherals there are two options for the wiring. The first is the standard option which is typically more common. For this, the SCK pin on each peripheral connects to the same SCK line, the MISO pin on each peripheral connects to the same MISO line, and the MOSI pin on each peripheral connects to the same MOSI line where the only line not shared between each peripheral is the CS line. Each peripheral gets its own isolated line that isn’t shared among the other devices. This allows you to differentiate between each peripheral by utilizing the CS pin to choose which peripheral will have data written to it and which will not. The second option is the daisy-chain method. For this the SCK and CS lines are shared between all peripheral devices. The difference for this is that the MISO pin of the controller connects to the MISO of the first peripheral, then the MOSI of the first peripheral connects to the MISO of the next peripheral and so on. Then for the last peripheral in your system, the MISO pin connects to the MISO pin of your controller. This allows data to overflow from one peripheral to the next meaning to transmit data to a certain peripheral, you need to send enough data to flow through all peripheral devices to reach your desired one. This method would also take away SPI’s full-duplex capabilities since there’s only one path for data to transmit compared to separate lines for your peripheral and controller to send data.
While the hardware can be self-explanatory and easy to wire up, there still needs to be code written in order to make sense of the data that is being sent along the signal lines and interpret it properly. There are many libraries that are already written that take advantage of the internal SPI hardware built into microcontrollers that make it easy to include SPI peripherals in projects. If writing your own library to potentially get more out of your device, there are certain aspects that need to be taken into consideration regarding both the peripheral and main microcontroller. The first thing that must be noted is whether data is sent with the most significant bit or least significant bit first. This is important to note because expecting the wrong order of bits will result in nonsensical data. The next is whether your peripheral reads data on the rising or falling edge of the clock pulse which typically can be found in a datasheet for your component. This is important because the peripheral will attempt to sample the bits on the data line on only one of those so it is imperative that data is sent on the correct part of the clock pulse to ensure proper data transfer. The last thing is to understand the speed capabilities of both your microcontroller and peripheral devices. SPI can operate at extremely high speeds which might be too fast for certain devices thus necessitating the need to observe what is the acceptable speeds for data transfer. This can also typically be found in a datasheet allowing you to get the most out of your SPI setup.
Advantages and Disadvantages
The advantages of SPI are numerous and make it a viable option for communication. Its synchronous capability allows for a much faster stream of data because there is no necessity for stop and start bits allowing for a continuous stream of information with no interruption. The CS system allows for easy differentiation between multiple peripherals unlike for example I2C, another communication method, that has a complicated addressing system. Separate MOSI and MISO lines allow for a full-duplex system that can support simultaneous transmission and receiving between devices to further boost data transfer speeds.
Despite the advantages, there will always be disadvantages. The first is that its multiple signal lines mean it requires more wires than some other protocols which can be difficult to manage if your microcontroller has limited pins. The need for the CS pin can potentially drastically limit the capabilities of your system if your controller has a limited amount of GPIO pins. This is in contrast to another protocol such as I2C which makes use of an addressing system allowing for a large number of devices communicating over only two data lines. There is only one main controller which controls everything meaning there can be no communication between peripherals. No confirmation of data being sent successfully can result in faulty data and hinder successful communication between your controller and peripherals for a streamline of data.
Conclusion
Through its powerful capabilities, SPI has become a strong communication method to interface devices together, most commonly microcontrollers with other sensors. It has numerous advantages that make it a top candidate for being included in personal projects to bolster the strength and speed of your system. Despite this, it still has numerous disadvantages that make it subpar to other communication methods so it is imperative to decide what the requirements for your system are. So when choosing your next sensor and deciding whether to get one with SPI functionality it’s important to take into consideration whether potential hardware complexity is negligible compared to the high fast speeds that you can gain. No matter what you decide, SPI will always be a premier communication method that is sure to be a mainstay for a very long time.
References
[1] https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all
[2] https://www.circuitbasics.com/basics-of-the-spi-communication-protocol/
[3] https://www.techtarget.com/whatis/definition/serial-peripheral-interface-SPI