Serial Peripheral Interface (SPI) is a high speed communication protocol for short distances between devices using four signal wires:
Unlike I2C, there is no upper limit on the speed of SPI devices, so clock speeds of
100MHz or more are generally possible. However, SPI is intended to be used over very short distances, with an absolute maximum of around 3 meters, and performs best when it’s traveling over 10cm or less.
Because of its high speed, SPI is often used for data-heavy, low-latency communications with devices such as cameras and displays.
SPI uses a master + client bus architecture which enables a master controller to communicate with multiple client peripherals using shared communication wires but each client being addressed by individual chip select (
In addition to the chip select, SPI requires two lines for bidirectional communication (
MISO), as well as a shared clock line for each peripheral. However, some peripherals only require one-way communication, and therefore only need three wires in total.
COPI (Formerly MOSI)
COPI stands for Controller-Out, Peripheral-In and transmits data from the controller to the client peripheral.
CIPO (Formerly MISO)
CIPO stands for Controller-In, Peripheral-Out, and is used to transmit data from the client peripherals to the controller.
All the peripherals are on the same clock, which is set by the master controller and pulsed over the
SCK line, which stands for Serial Clock.
SPI uses the Chip Select line to select individual devices to communicate with. Usually, there is one
CS per device, and it’s pulled
0V for the device that the messages are intended for.
Note: SPI supports shared
CS lines in a daisy-chain configuration, but it’s rarely used and is unsupported in Meadow.
Meadow SPI Pins
The SPI pins on the F7 Feather are labeled
CIPO) and can be found between
Any pin that supports digital output can be used as a chip select line.
Using the Meadow SPI API
Creating an SPI Bus
To use SPI in Meadow, first create an
ISpiBus from the
ISpiController you’re using:
ISpiBus spiBus = Device.CreateSpiBus();
Working with SPI Peripherals
Once the SPI Bus has been created, peripherals can be created by passing in the SPI Bus and the
IDigitalOutputPort that is connected to the chip select on the peripheral:
IDigitalOutputPort spiPeriphChipSelect = Device.CreateDigitalOutputPort(Device.Pins.D03); ISpiPeripheral spiPeriph = new SpiPeripheral(spiBus, spiPeriphChipSelect);
Generally, you won’t need to handle low-level SPI peripheral communication directly, as the peripheral drivers in Meadow.Foundation expose high level APIs for working with their features. However, if you’re creating a new driver, or want to talk to a peripheral directly, there are a number of communications methods exposed via the
IByteCommunications interface, which SPI peripherals implement. Among these are methods to read and write bytes directly to the device as well as read and write to memory registers on the device:
These methods are also available via the SPI bus, but require the chip select port of the device to be explicitly passed: