SPI is an extremely versatile serial communication peripheral in embedded systems. SPI or Serial Peripheral Interface is a full-duplex (both sides can talk transmit and receive data simultaneously) serial bus that consists of primarily 4 main signals – SCK (Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out), CS/CE (Chip Select/Chip Enable).
SPI has a master-slave configuration wherein a single master can be connected to one or more SPI slaves. If there are more than one slaves, the master can talk to them one at a time – this decision of which slave is being talked to is done using the CS signal – if the CS of a slave is asserted (i.e. low), that SPI slave is selected by the master for the communication.
In a multi-slave system, only one slave’s CS should be asserted at a given point of time!
This is what the bus looks like.
There are various configurable parameters of an SPI bus – these are the most important ones.
- Clock Speed – the frequency in Hz for the communication protocol
- Operation Mode – this is composed of two configuration parameters – polarity and phase. The polarity indicates the level of clock when the bus is idle i.e. no slave is selected. The phase indicates the edge at which the data is sampled and (consequently) the edge at which the serial data is shifted out.
- (Less commonly used) Communication delays – some slaves require that there be a minimum delay between the assertion of chip select (i.e. chip select going LOW) and start of clock from the master. It is possible in most modern SPI masters to configure this delay.
The good thing is that these configuration parameters are clearly indicated in the data sheet of the slave that the master wants to talk to!
SPI in Linux
As we know, Linux is an extremely popular OS kernel in the embedded world. The makers of every processor capable of running the Linux kernel, want to run the Linux kernel as well as they can! Among a lot of other things, one of the biggest benefits the Linux kernel brings to the table is the ability to abstract out the “nitty-gritties” (read gruesome low-level technical details) of hardware peripherals allowing the application code to remain same across processors. This requires a lot of work on the part of the processor companies but this is often a one-time activity with a long-running reward. This is motivation enough for these companies to provide high-quality hardware drivers that just work in the linux kernel.
Of course, no software development today is bug-free and software maintenance does happen over a period of time but you get the idea! 🙂
SPI in Linux is not an alien to this idea – a framework called spidev in the linux world makes it possible for you to write SPI applications in the user-space which are extremely abstracted in nature, allows you to configure your SPI bus the way you want and lets you hit the ground running for your next project within minutes!
Here’s a video about using the SPI bus on a Raspberry Pi running linux.
Here, we discuss the various options you have for using the SPI bus at the application level and then actually use one the ways (spidev in C) to first do a loopback and then drive a simple OLED display.
The code used in the video is located on GitHub: https://github.com/sckulkarni246/ke-rpi-samples/tree/main/spi-c-ioctl
Check it out! Do like and subscribe to the channel if you appreciate this content.