The Serial Peripheral Interface (SPI) bus was put together by Motorola (Freescale/NXP/Qualcomm) in the 1980s for communicating between a processor and one or more external peripherals. SPI is intended for short distance communication, typically between chips on the same board.
SPI is similar to the I2C bus and it has advantages, drawbacks, and similarities:
- Higher speed
- No addresses
- No pullup resistors
- Transmit and receive simultaneously
- More pins necessary
- There are at least 4 ways to set them up
Similarities between SPI and I2C:
- Need to send out dummy data to retrieve results
- Reduced pin count and smaller packages compared to parallel buses
- Might require an oscilloscope to check the signal timing
The topology of the SPI circuit is a bus consisting of a master and one or more slaves. The signals on the bus are called Master Out Slave In (MOSI), Master In Slave Out (MISO), Clock, and Select.
In the following figures I show two typical implementations of SPI with one and three slave peripherals. (A uP is a microprocessor.)
As we see in Figure 2, all of the slave peripherals share MOSI, MISO, and clock. Each will have a unique chip select, which is typically connected to a GPIO pin on the master.
The MOSI signal is used to transfer data out of the master and into the slave. (MOSI stands for master out slave in). Similarly, MISO is used to transfer data into the master and out of the slave.
The timing of the data transfer is controlled by the clock signal.
MOSI, MISO, and clock are sent to all of the slaves on the bus, but only the one that has been enabled using its select pin will accept the data from the master and send data back. When they are not selected, the slaves remove themselves from the bus (go into a high resistance (high Z) state) until enabled by their select pin.
The slave’s select pin will be called Select, chip select, CS, CS with a bar over it, CS#, CS*, or some variation of that. Having a bar over the name or an octothorpe or star following indicates that the chip is active (also called enabled or selected) when the pin is held low (grounded). You will also see the phrase active low used. A lot of SPI slaves are active low. But there are chips, like real-time clock chips, that are active high. Check your data sheets to see what your chip needs.
Before you do a data transfer the master activates the select line, then may have to delay a small amount of time for the slave chip to wake up. This delay is usually in the range of nanoseconds, so you don’t have to worry about it unless you are on a very fast processor.
After the transfer is complete the master deactivates the select line and the slave chip takes itself off of the bus.
Chip select may need to be bit-banged using a GPIO pin, or it may be a part of the SPI controller where select and deselect happen automatically.
When you only have one slave peripheral, you could have the chip selected all of the time by tying the select pin low (or high, depending on what is required), but this can cause problems in low power circuits. SPI slaves commonly go into a low power state when they are deselected. By leaving them selected, you can waste a lot of energy. For instance, a flash memory chip can draw 6mA of current by leaving it selected. That is enough to have a very bright LED; why waste the power on an unused chip?
The clock in SPI is a 50% square wave, where each pulse is used to transfer (clock in) a single bit of the data. So transferring an 8-bit value will take 8 pulses.
The square wave (as shown in Figure 3) has two important parts: the rising edge (when the voltage on the pin transitions from low to high), and the falling edge (when the voltage goes from high to low).
These edges are used to tell the slave when data bits are stable and when they are changing.
Since the data is being transferred serially (one bit after another over a single wire), the clock is used to indicate when the data bits are ready to be used. In the data sheet, the manufacturer of the peripheral chip will tell you how to configure the SPI master to coordinate the clock with the data bits.
The datasheet will tell you if the peripherial is expecting the data bits to be valid when the rising or falling edge of the clock happens. This is called the clock phasing.
When the SPI bus is not being used, the clock can be left constantly high or constantly low. This is called the clock polarity.
The speed that the clock toggles is also specified in the slave chip documentation. If a slave has a maximum clock speed of 20MHz, but your processor can only generate 4MHz, that’s fine, running slower than maximum speed is perfectly valid. But slaves will not work correctly if the clock speed is greater than their maximum. Their circuitry just can’t respond in time.
The master transmits data out of the MOSI pin and receives on the MISO pin. The rule of SPI is that it transmits and receives at the same time.
Think of it like a conversation between two annoying people who just won’t shut up. While one talks, the other will mumble.
|Mumble mumble||Hi there.|
|How are you today?||Mumble mumble|
|Mumble mumble||Pretty good really, and you?|
|Couldn’t be better.||Mumble mumble|
SPI uses a similar method, the transmitters and receivers are active at the same time. As the request is going out, junk is coming in. Then dummy data has to be sent out to retrieve the result. It looks like this:
|Master drives MOSI||Slave drives MISO|
|Read location 42||0xFF or junk|
|0xFF||Location 42 data|
The slaves can support a form of pipelining, where the master can send multiple commands back-to-back and the slave replies as the next command is clocked in.
You may wonder why the slave doesn’t answer while the current command is coming in. The slave hasn’t received the whole command yet, it doesn’t know what to do until the command has been fully retrieved. Then it has to prepare the reply and then wait until the next command is being clocked in, and then clock out the reply.
So, the result of the final command has to be clocked out with dummy data (0xFF being a typical value), like this:
|Read location 1||0xFF|
|Read location 2||Location 1 data|
|Read location 3||Location 2 data|
|Read location 4||Location 3 data|
|0xFF||Location 4 data|
The number of bits in a transfer depends on how the slave is designed. Though it tends to be a multiple of 8 bits for compatibility.
Bringing It Together
Communication is always coordinated by the master. It controls chip select, provides the clock, and sends the commands. Simultaneously, the slave transmits data back to the master.
This is what an oscilloscope trace would look like when looking at the SPI bus. I’ve drawn this example so that the data on MISO and MOSI is sampled on the rising edge of the clock signal.
From the left (time increasing to the right), clock idles high (polarity = 1), CS* (chip select star, the star indicates that the signal is active low) goes low, enabling the chip.
The clock starts toggling. MOSI can change when the clock’s falling edge is encountered, and MOSI must remain stable on the clock’s rising edge since that’s when the slave reads it. I’ve drawn in a couple of indicator lines on the rising edges showing what a 1 and 0 would look like (phase = 1).
The value being transferred here, 1010 0111 would be a 0xA7 (this doesn’t mean anything in particular).
Meanwhile, the slave transmits a value of 0000 0010 or 0x02 on MISO.
Unlike RS-232, SPI has a straightforward signal connection pattern: you connect similarly named pins together. So MOSI on the master is connected to MOSI on the slaves, MISO to MISO, and clock to clock. Each slave gets its own chip select.
The timing relationship between the data on MOSI/MISO and the clock edges is specified by the manufacturer of the slave chips. Two parameters are specified, the polarity of clock (whether it idles high or low), and the phase of the clock (whether data should be read on the rising edge or the falling edge). On some processors, these two parameters are combined into a 2-bit number called the mode, but this encoding is not standardized, so check the data sheets and set up your SPI controller to match.
When you have more than one slave on a bus, they don’t have to have the same clock phasing, clock polarity, clock speed, or chip select polarity. Before you use the slave, you reprogram the SPI controller to match the specs required. You could change the clock speed to run at the maximum for the chip, or use a lowest common clock speed on all of the slaves.
Who Uses This Stuff?
Peripherals supporting SPI are popular because they don’t need very many pins, saving board space. The peripheral/slave chip only needs power, ground, 4 pins for SPI, and whatever is needed to make the chip useful.
There are many memory chips available in small 6 pin packages like flash, non-volatile ferro-electric RAM, and EEPROM. Prior to using SPI, these devices would have about 30 pins and used a lot of board space.
There are many ADCs and DACs, high power switches, and sensors available. But SPI is also used on SD cards and it is even the basis of the JTAG debugger port.
SPI can be used for write-only devices like LCD panels and DACs. MISO is ignored in these cases.
Processors aren’t always a SPI master, either. Some processors can be configured to act as intelligent slave devices as well. One processor acts as a master and another as the slave.
Even though SPI uses extra wires compared to I2C and SPI chips are a little more expensive, SPI gives you a lot more performance without the voodoo of pull-up resistors.
Next time I’ll show how to use SPI to read the 3-axis accelerometer on our development board.
This post is part of a series. Please see the other posts here.
Music to program by - Cool Struttin', Sonny Clark, 1958, Blue Note