This is in continuation of my last article on Device Drivers. I would be using the SPI interface to demonstrate the situation which would make it simpler.
Before we delve into the nitty-gritty of programming, hardware, and whatnots, we need to understand the basics of the SPI protocol so that we can check the output(s) and (hopefully) draw correct conclusions from it. Then and only then, we would like to move on to the Linux system and device drivers which will employ the SPI protocol hardware.
What is SPI Protocol?
SPI protocol is the abbreviation (short form) for Serial Peripheral Interface. As the name suggests, this was designed for use with peripheral devices. Now, you might just ask what in the world a peripheral device is. So, let’s just say that it is any device which increases the functionality of your system. If you have ever used a computer system, you must have used peripherals. What blasphemy – you say, well, the mouse, the keyboard, the audio system, etc. are nothing but peripheral devices. So, are you satisfied? If not, you can search this word on the internet (in another tab of course, don’t close this one!).
I digress. Now, where were we? Ah, the SPI protocol. Coming back to the discussion about SPI protocol, it is a master-slave protocol. One device (generally the main computing unit) behaves as the master and requests data from the slave device (generally the peripheral device). To have all this functionality, it uses multiple wires for communication. How many – you ask. To clarify, it is a 4-wire protocol (technically 5 wire if you count the ‘ground’ line as well). These 4 lines are: CS (chip select), MISO (Master in slave out), MOSI (Master out Slave in) and CLK (Clock).
The CS line is used to get the attention of the slave device. The slave device generally has its own work to do. Whenever the master needs to communicate with the slave, it changes the logic level on the CS line, either from 1 to 0 or from 0 to 1. This causes something called an ‘interrupt’ in the slave device which attracts its attention and it is ready for communication with the master. As soon as the CS line goes back to its original logic level the transmission is assumed to be terminated (even in the middle of a byte being transmitted).
The MISO line is exactly what it sounds like. It brings data IN to the Master from the Slave. Thus, Output of Slave device goes to the Input of the master device. This implies that this line is unidirectional which means the data goes only in one direction (from the slave to the master).
Similarly, the MOSI line carries data/command from the master to the slave. Now you might ask why do we need this at all? Why would I want to send data to the keyboard or to the mouse? Well, you wouldn’t if you picked these 2 examples. But think about gaming controllers. When you are driving a car in the game and collide with something, you feel a buzz in the controller. This is nothing but the gaming console telling the controller to turn its vibration motor on (and maybe tell you how bad a driver you are, who knows). This is where the MOSI line comes in. Note that keyboard, mouse, etc. DO NOT use SPI interface, I am just using them as examples because, well, it is my article.
The CLK line sends clock pulses from master to the slave and in each clock pulse, one bit (1/8th of a byte) is transferred. Now you ask what is wrong with asynchronous (clockless) protocols? Like UART? To that, I say, “you ask a lot of questions, don’t you?”. But to answer the question, asynchronous protocols need both the communicators to agree on the clock speed and they need to transfer a start-bit and a stop-bit to signal the start and end of the transmission. This introduces extra hardware to detect and decipher the start and stop bits.
For a better explanation of direction of data flowing across the bus, see below the typical configuration of SPI bus. If you understand very well, you can skip to the next paragraph. Don’t skip too ahead! Or you might miss something important.
The direction of the arrows in the above figure imply the flow of information. For example, the clock line is controlled by the master and the slave just ‘listens’ to the clock signal.
Below is the ‘snip’ of the SPI protocol in action. I grabbed this image using WaveFormsTM (a software from DIGILENT).
You should notice how the Select line (CS) is high before, in-between and after the transmission of bytes. And you must be wondering what and how the data is read. Thus, I must tell you that I have configured the SPI bus to read data on rising edge of the clock. This means that at each point when the clock signal goes from 0 to 1 and CS line is asserted (i.e. held low), the status of the Data line represents the bit. Is your head spinning from all these rules? Mine is. To understand this better, just look at the diagram below which is a zoomed in version of the previous snip that we saw.
Now, notice the rising edge of the clock line (given by a red upwards arrow). At exactly each of those points, notice the value of Data line. Let us note it down together starting from left. First one is obviously a 0. The next one is 1, the next one is again 1. And so on. So, the final answer is: (01101000)2. Notice how I have written ‘2’ in the subscript, that is because it is a binary number. Converting it to hexadecimal and then referring the ASCII table for the value, we know that it is (68)16, and represents the character ‘h’. If have noticed that the SPI line in the diagram above shows h68 (which is just a way of representing (68)16), then hats off to your attention to detail.
Could you do the next one? What does the second byte represent in the first image?
If you figured out that it is the character ‘o’ then kudos! Good work!
I believe that this is sufficient information about the SPI interface. If you wish to pursue this topic further, you will find a huge number of articles out there on the internet. I will take you through the actual SPI driver source code in next article , Stay Tuned.
Lastly, thanks for taking out the time to go through this article. I hope that you guys like, or better yet, love it!
Author: Aniruddha Kanhere
Aniruddha is a graduate student at NC State University – studying computer engineering. He came in contact with embedded systems during his undergraduate education while he was in the RoboCon team. Till this point, he has done numerous projects and has presented 2 papers in international conferences which are to be published. Apart from this, his interests lie mainly in the domain of RTOS, device drivers and Optimization.
If you are not very much comfortable with C Language , You may be interested in Learn C Practically
You may find interesting topics at HowTo
Thanks for reading till end. Please provide your feedback regarding this article. Also subscribe Embedkari for other interesting topics. .
Embedkari has introduced its first low cost technical training .