SPI - Serial Peripheral Interface
SPI at a glance
SPI is a protocol that is used to communicate between IC’s
It is typically implemented using TTL logic levels
Can be made full-duplex, and is among the faster protocols
Synchronous Protocol, no addressing between chips, requires a discrete line to each chip to ‘select’
On ZeroPilot, SPI is what we use for ‘interchip’ communication between the Autopilot and Safety chips
Signals Overview
Note, the terms ‘master’ and ‘slave’ are slowly being phased out due to their origins. However, the terms ‘master’ and ‘slave’ are still used in industry at the time of writing. This guide will use the terms ‘controller' to refer to what was conventionally known as ‘master’, while ‘peripheral' will refer to what was conventionally known as ‘slave’.
COPI (formerly MOSI) - Controller Out, Peripheral In, aka Master Out, Slave In
This signal line transmits serial data from the controller to the peripheral
CIPO (formerly MISO) - Controller In, Peripheral Out, aka Master In, Slave Out
This signal line transmits serial data from the peripheral to the controller
CS - Chip Select
SPI has the ability to hook onto multiple IC’s in a single bus. To differentiate between several discrete IC’s, a chip select pin is employed that is either pulled high or low to ‘select’ the device. A chip select pin is required for every IC on the bus.
If there is only 1 IC on the bus, it is possible to tie the CS pin high/low provided the datasheet allows this (be careful though, some IC’s require chip select to be toggled)
This is an inherent disadvantage to SPI when there are many devices on a bus. In the event that a significant amount of devices are on a bus, a demultiplexer can be employed.
- SPI devices on a bus, credit.
CLK
SPI is a synchronous protocol (see https://uwarg-docs.atlassian.net/wiki/spaces/ZP/pages/1995014180 )
Clock Polarity - CPOL and CPHA
With SPI, there are lots of different combos of clock polarity. Some will cycle out data on the rising edge of a clock signal, while others will cycle out data on the falling edge of a clock signal. Additionally, the resting state of the clock must either be high or low in reference to the datasheet. There is little consistency on this topic, every IC is different.
SPI clock polarity timing diagram, credit.
SPI is a push-pull protocol
It is important to understand a bit of the EE theory behind the protocol.
Unlike I2C, SPI is a push-pull protocol. This means, the pins are explicitly driven high or low, rather than pulled low and released high. This is why there is typically no addressing on SPI pins - rather, you employ a chip select line to do the selection for you.
Theory of operation
Since SPI has both a COPI and CIPO line, it is possible to send data in both directions on the same clock pulses. Such is referred to as full-duplex communication.
Since it is synchronous, there is no need for start/stop bits. SPI also lacks default error checking, thus it is up to the user/IC to implement this.
A SPI transaction starts by pulling chip select either low or high depending on the datasheet requirements.
A data packet can be as small or as wide as required, there is no real limitation.
Application Notes
SPI is really good when you have a few devices that require fast read rates. It can still be used in other requirements, but recall that you will need to have a chip select pin for every IC, which can add cost to a board as well as complexity.
Ask your EE to put test points on the CIPO, COPI, and CLK lines, they will be valuable during debugging.
The internal circuitry for SPI is quite simple compared to UART, and you’ll never run into the issue of 2 devices not communicating on the same baud rate.
As alluded to in the theory of operation, there is no set data bit width. Thus, you will need to define what packets are expected when, as well as how much data will be transferred per transaction.
Common mistakes
Not having a CS line to each peripheral
Crossing COPI and CIPO lines accidentally
Further reading
https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all