In the previous tutorial, we discussed interfacing with the ADXL345 accelerometer sensor with Raspberry Pi using the I2C interface. UART, I2C, and SPI are the most common serial communication interfaces used in embedded systems. UART is used for point-to-point full-duplex asynchronous serial communication between two devices. I2C is used for synchronous serial communication among multiple devices over two wires only.
Serial Peripheral Interface (SPI) allows full-duplex or half-duplex synchronous serial communication with multiple devices over 3 or 4 wires. SPI can be seen as a multi-device synchronous version of the UART standard. It allows high-speed data communication with multiple devices, unlike I2C, which is a low-speed standard for data communication among multiple devices.
However, the number of devices that can have full-duplex communication with a controller/computer over SPI is limited. Generally, SPI is good only for full-duplex high-speed data communication with multiple devices, not more than four. As SPI allows full-duplex high-speed data transfer, it is used by a number of embedded sensors and devices that require high-speed bidirectional data communication with a controller/computer. SPI is the preferred serial standard for time-critical embedded applications. It is not limited to any maximum clock frequency and can offer throughput as high as 10 Mbps.
SPI is a serial bus developed by Motorola. SPI is a master-slave type interface. There can be only one master of an SPI bus; however, the number of slaves can be one or more. Though, it is possible to have multi-master protocol over SPI, it gets cumbersome, and multi-master SPI communication is possible with only a single slave.
Generally, the SPI bus is used within a PCB for high-speed serial communication between a controller/processor and on-board peripherals like RTC (Real Time Clock), ADC, DAC, memory devices (EEPROM and FLASH memories), on-board sensors, display devices, and peripheral chips. The data communication over SPI off PCB has its own limitations. As SPI is designed for very high data speeds, the bus line cannot be extended. As the length of the bus increases, its reactance also increases, which makes the bus unusable. Despite these limitations, SPI is suitable for high-speed uninterrupted data communication over short distances. That is why the SPI bus is used by many sensors, SD cards, RFID card readers, and 2.4 GHz Wireless Transmitter/Receivers.
SPI bus has four wires, of which two are data lines, and two are control lines. SPI bus has the following data lines:
Master Out Slave In (MOSI) – Over this line, the master device transmits data to the slave(s). This line is also referred to as Serial Data In (SDI) in specifications of many parts.
Master In Slave Out (MISO) – Over this line, the master device receives data from the slave device(s). This line is also referred to as Serial Data Out (SDO) in the specifications of many parts.
SPI bus has the following control lines:
Serial Clock (SCK or SCLK) – SPI Master generates a clock signal over this line to synchronize data transfer between itself and the slave(s).
Slave Select (SS)/Chip Select (CS) – This line is used for the selection of the slave device over the SPI bus. It is referred to as Slave Select (SS) on the master device and Chip Select (CS) on the slave device. The SS signal is active low and is always generated by the SPI master. If the SPI master is interfaced to a single slave, the CS pin on the slave can be hard-wired to ground. If there are multiple slaves, either there should be separate SS/CS lines for each slave device or the slave devices must be daisy-chained.
The master is the controlling device of the SPI bus. It means that the clock signal is controlled solely by the SPI master. The slave devices have no control of the SCK/SCLK line. The slaves can neither drive SCK/SCLK high or pull SCK/SCLK low. The data communication is always initiated and controlled by the SPI master. When slave devices have to talk back to the SPI master, it is always prearranged. That is, the slave devices talking over SPI have a strict command structure, and the SPI master already knows when a slave device will respond back data and what size that data will be.
SPI is different from UART and I2C/TWI standards. The data is not communicated in packets/frames over the SPI bus. There is an uninterrupted continuous transfer of data arranged in no packets on the SPI bus. The data and clock signals are generated simultaneously by the SPI master. The bits are sampled at every rising or falling edge of the clock signal. Even when the SPI master receives data from the slave(s), it already knows when it will receive data and how much data it will receive after passing a command to a slave. Accordingly, it samples the receiving data over the following clock signals. It can be noted that there are dedicated lines for the master to transmit data and receive data. Both MOSI and MISO lines are unilateral.
Some parts that only require receiving data from an SPI master may only have a MOSI line and no MISO line. An example of such a part is the LCD controller. Similarly, some parts that only require transmitting data to an SPI master may only have a MISO line and no MOSI line. ADC chips are an example of such parts.
SPI hardware and voltage levels
SPI interface is simpler than UART but more complex than I2C. A device needs dedicated hardware for being an SPI master. However, a slave device over the SPI bus can be as simple as a shift register. That is why there are many sensors that use SPI for bidirectional data communication with controllers/processors.
All four lines on the SPI bus involve digital signals. Therefore, the voltage level of the SPI signals depends upon the devices, whether they are 5V or 3V3. SPI bus usually interconnects compatible devices on the same PCB or over short wires. The devices that may talk over different logic levels can be connected together over the SPI bus using a suitable level translator.
How SPI protocol works
On the SPI bus, data communication is always initiated and synchronized by the SPI master. The SPI master, first of all, configures the clock signal to a frequency that should be less than or equal to the maximum frequency that slave devices can support. There is no maximum clock speed, and the data transfer rate can go as high as 10 Mbps. As it is the master that initiates data communication, the first bits are always transmitted by the SPI master. The bits are synchronized according to the clock signal and accordingly sampled by the slave device. One bit of data is transferred over MOSI and/or MISO for each clock pulse. Therefore, the data transfer rate always depends on the clock frequency from the SPI master.
The sampling of the bits can depend upon the clock polarity or clock phase. SPI master decides whether bits should be generated and sampled according to a particular clock polarity or clock phase. If clock polarity is used by the SPI master, it can decide whether bits should be sampled on rising or falling edge of the clock, and accordingly, bits are generated by the SPI master. If the clock phase is used by the SPI master, it can decide whether bits should be sampled on the first or second edge of the clock signal irrespective of that being rising or falling edge, and accordingly, bits are generated by the SPI master.
After configuring clock frequency and start generating clock signals, the SPI master selects a slave to which it has to transmit data. The SPI master selects a slave by driving its CS line to low. The CS line of other slaves, in case of multi-slave SPI, must be driven to high while a slave is selected. Therefore, SPI master should have as many SS lines as many are there SPI slaves. If there is only one SS line on the SPI master, the SPI slaves must be daisy-chained. Only one slave can be selected by the SPI master at a time.
The slaves that are not selected at a time must disregard the SPI clock and MOSI signals. Therefore, the SPI bus can be shared only between those peripherals that have tri-state outputs, i.e., the pins/channels of the devices must have electronic output stage consisting of a logic gate that exhibits three possible logic states – logic 1, logic 0, and an inactive (high-impedance or open-circuit) state. Most of the devices and peripherals do have tri-state outputs and can share the SPI bus without any hassle.
The SPI master may need to wait for some period in case of SPI communication with some parts before generating clock signals for a sampling of bits. For example, an SPI master may need to wait for analog-to-digital conversion when talking with an ADC.
After selecting a slave, the SPI master starts sending data bit by bit with simultaneous clock signals. Though there is no data packet or frame defined in SPI protocol, the data is usually organized using shift registers of fixed word size (mostly 8-bits) on both SPI master and slave(s). When the SPI master shifts register value out one bit-by-bit, the SPI slave shifts data into its register on each clock pulse. When the master sends data to slave over MOSI, data is sent bit-by-bit serially with the most significant bit (MSB) first. After exchanging a register value, the SPI slave takes the value and perform necessary operations. If no more register values are to be transferred, the SPI master stoops the clock signal; otherwise, the same process of loading register value and serially shifting value bit-by-bit is repeated. The SS line may be pulled high in-between transmitting register values.
Sometimes, SPI masters operate in multiple-byte stream mode. In this mode, the SS line is kept low all-time, and bits are continuously shifted by the SPI master through its registers.
When a slave sends back data to the SPI master over the MISO line, it is serially transferred bit-by-bit with the least significant bit (LSB) first. Obviously, both SPI master and slave must have separate shift registers for storing transmitted and received data values as they have separate lines (MOSI and MISO) for full-duplex data transfer. A slave usually sends back data in response to a received command from the SPI slave. The SPI slaves have a strict command structure, and data transfer from slave to SPI master is always prearranged. The transfer of data along the MISO line can be simultaneous to data transfer along the MOSI line over the same clock pulses allowing full-duplex communication between the SPI master and the slave.
Sometimes, SPI slaves have a dedicated signal line for sending interrupts to the SPI master. Such interrupt lines are used for specific functions like a temperature sensor may generate an interrupt for thermal limit alert, a touch screen may generate a pen-down interrupt, an audio device may generate an interrupt for headset jack insertion, and RTC chips may generate interrupts for alarms.
SPI modes, clock polarity, and phase
SPI master needs to configure clock polarity and clock phase with respect to the data for its proper sampling. According to the clock polarity and clock phase, there can be four SPI modes as listed in the table below:
Multiple Slaves SPIIf the clock phase is 0 and clock polarity is 0 (SPI mode 0), data is latched at the rising edge of the clock pulse. If the clock phase is 0 and clock polarity is 1 (SPI mode 2), data is latched at the falling edge of the clock pulse. If the clock phase is 1 and clock polarity is 0 (SPI mode 1), data is latched at the falling edge of the clock pulse. If the clock phase is 1 and clock polarity is 1 (SPI mode 3), data is latched at the rising edge of the clock signal.
Multiple slaves can be connected to the SPI bus in two ways:
Parallel or Independent Configuration – In this configuration, the SPI master has as many SS pins as are the number of SPI slaves. The CS pin of each slave is connected to one of the SS pins of the SPI master. The SPI master can independently select a slave at any time. All the clock lines are connected together. All the MOSI lines are connected together, and all the MISO lines are connected together. Note that despite separate SS/CS lines, only one line can be driven low by the SPI master, and only one slave can be selected at a time.
- Daisy-chained/cascaded slaves – When the SPI master has only one SS pin, the SPI slaves must be daisy-chained. In this configuration, all clock lines are connected together, and all chip select (CS) pins are connected together. The MOSI pin of the SPI master connects to the MOSI pin of the first slave, and the MISO pin of the first slave is connected to the MOSI pin of the second slave. Then again, the MISO pin of the second slave is connected to the MOSI pin of the third slave, and it goes on. The MISO pin of the last slave is then connected to the MISO pin of SPI master.
In the cascaded configuration, the data passes through all slaves from the master, and data transmitted by one slave passes through all other slaves cascaded in line before reaching the master. The cascaded configuration works only with SPI slaves that require single-byte data communication. The cascaded slaves form a wider data register, and the SPI master needs to generate enough data that it reaches the target slave. For example, if the SPI master has to transmit data to the 4th slave, it needs to generate four bytes so that the first byte reaches successfully to the 4th slave. The SPI slaves that need talking multiple bytes cannot be connected to the SPI bus in a cascaded configuration.
Advantages of SPI
SPI standard offers a number of advantages over UART and I2C. It does not require any dedicated hardware at the receiver end except a shift register, and the hardware required at the master device is not that complicated as compared to UART. Data can be continuously streamed between devices using SPI at speeds twice fast than I2C. There is no limit to clock frequency, and the data transfer rate can be arbitrarily decided by the SPI master. There is no in-band addressing of slave devices, and so, no complicated address schemes are involved. SPI allows full-duplex communication with multiple devices. This makes SPI better than UART, which can have full-duplex communication only between two devices and that too involving much-complicated hardware and protocol.
Disadvantages of SPI
The biggest disadvantage of SPI is that it uses four wires for connecting two devices. For multi-byte communication, the SPI slaves need to be connected in a parallel configuration, and that requires an additional SS pin on the SPI master for each slave. This limits the number of SPI slaves that can be practically connected to an SPI bus. Not all SPI masters can have many SS pins. Secondly, SPI is practically a single-master bus. If multiple masters are connected to the SPI bus, then only one slave can be connected, and managing bus contention in multi-master protocol over the SPI bus is a lot more difficult.
Any data communication from SPI slave to SPI master needs to be prearranged. This means that only slave devices with strict command structures can talk over the SPI bus. An SPI slave must have responses of fixed length for commands transferred to it over the SPI bus. It is not possible for an SPI slave to respond to a variable-size data over the SPI bus as the SPI master must know what length of data it is about to receive over the MISO line after passing command over the MOSI line.
There is no acknowledgment of data over the SPI bus, and there is no error-detection (like parity bit or something like that) mechanism in SPI protocol.
SPI is most suitable for high-speed full-duplex data communication of a controller/processor within a PCB with multiple peripherals. It can also be used for full-duplex high-speed data communication with sensors and devices that have a strict command structure and always need to be interfaced in close proximity (over short wires) to a controller/embedded computer. Due to its high data speed, low hardware complexity, and multi-slave capability, SPI is the best alternative to UART when interfaced devices are in close proximity. If the devices are to be interfaced over a greater distance, only UART is the resort provided the data communication has to be between only two devices, or one needs to compromise with data speed using the I2C bus.
In the next tutorial, we will discuss synchronous serial communication in Raspberry Pi using the SPI interface.
(Editor’s note: this article first appeared in EEWorldonline’s sister publication, EngineersGarage.com)