Exploring Edison - SPI
Written by Harry Fairhead   
Thursday, 02 June 2016
Article Index
Exploring Edison - SPI
SPI Functions
A Loop Back Example
Implementing The User Mode Driver
General SPI Problems

The SPI bus can be something of a problem because it doesn't have a well defined standard that every device conforms to. Even so, if you only want to work with one specific device it is usually easy to find a configuration that works - as long as you understand what the possibilities are. 

This is a chapter from our ebook on the Intel Edison. The full contents can be seen below. Notice this is a first draft and a work in progress. Use the comments or email harry.fairhead@i-programmer.info with your queries or suggestions.



Now On Sale!

You can now buy a print edition of Exploring Intel Edison.
You can buy it from:

USA and World  Amazon.com
Canada              Amazon.ca
UK                      Amazon.co.uk
France                Amazon.fr
Germany            Amazon.de
Spain                  Amazon.es
Brazil                  Amazon.br
Italy                    Amazon.it
Japan                 Amazon.co.jp
Mexico               Amazon.com.mx 

Chapter List

  1. Meet Edison
    In this chapter we consider the Edison's pros and cons and get an overview of its structure and the ways in which you can make use of it. If you have ever wondered if you need an Edison or an Arduino or even a Raspberry Pi then this is the place to start. 

  2. First Contact
    When you are prototyping with the Edison you are going to need to use one of the two main breakout boards - the Arduino or the mini. This chapter explains how to set up the Edison for both configurations. 

  3. In C
    You can program the Edison in Python, JavaScript or C/C+ but there are big advantages in choosing C. It is fast, almost as easy as the other languages and gives you direct access to everything. It is worth the effort and in this chapter we show you how to set up the IDE and get coding. 

  4. Mraa GPIO
    Using the mraa library is the direct way to work with the GPIO lines and you have to master it. Output is easy but you do need to be aware of how long everything takes. Input is also easy but using it can be more difficult. You can use polling or the Edison interrupt system which might not work exactly as you would expect.

  5. Fast Memory Mapped I/O
    There is a faster way to work with GPIO lines - memory mapped I/O. Using this it is possible to generate pulses as short at 0.25 microsecond and read pulse widths of 5 microseconds. However getting things right can be tricky. We look at how to generate fast accurate pulses of a given width and how to measure pulse widths.

  6. Near Realtime Linux 
    You need to be aware how running your programs under a non-realtime operating system like Yocto Linux effects timings and how accurately you can create pulse trains and react to the outside world. In this chapter we look the realtime facilities in every version of Linux. 

  7. Sophisticated GPIO - Pulse Width Modulation 
    Using the PWM mode of the GPIO lines is often the best way of solving control problems. PWM means you can dim an LED or position a servo and all using mraa. 

  8. Sophisticated GPIO -  I2C 
    I2C is a simple communications bus that allows you to connect any of a very large range of sensors. 

  9. I2C - Measuring Temperature  
    After looking at the theory of using I2C here is a complete case study using the SparkFun HTU21D hardware and software. 
  10. Life At 1.8V
    How to convert a 1.8V input or output to work with 5V or 3.3V including how to deal with bidirectional pull-up buses.

  11. Using the DHT11/22 Temperature Humidity Sensor at 1.8V 
    In this chapter we make use of all of the ideas introduced in earlier chapters to create a raw interface with the low cost DHT11/22 temperature and humidity sensor. It is an exercise in interfacing two logic families and implementing a protocol directly in C. 

  12. The DS18B20 1-Wire Temperature 
    The Edison doesn't have built in support for the Maxim 1-Wire bus and this means you can't use the very popular DS18B20 temperature sensor. However with a little careful planning you can and you can do it from user rather than kernel space. 

  13. Using the SPI Bus 
    The SPI bus can be something of a problem because it doesn't have a well defined standard that every device conforms to. Even so, if you only want to work with one specific device it is usually easy to find a configuration that works - as long as you understand what the possibilities are. 

  14. SPI in Practice The MCP3008 AtoD 
    The SPI bus can be difficult to make work at first, but once you know what to look for about how the slave claims to work it gets easier. To demonstrate how its done let's add eight channels of 12-bit AtoD using the MCP3008.

  15. Beyond mraa - Controlling the features mraa doesn't. 
    There is a Linux-based approach to working with GPIO lines and serial buses that is worth knowing about because it provides an alternative to using the mraa library. Sometimes you need this because you are working in a language for which mraa isn't available. It also lets you access features that mraa doesn't make available. 


SPI Bus Basics

The SPI bus is commonly encountered as it is used to connect all sorts of devices from LCD displays, through real time clocks, to AtoD converters. It is also used for high data rate streaming, for example, getting video data from a camera. 

The SPI bus is strange because there is no standards for it and different companies have implemented it in different ways which means that you have to work harder to implement it in any particular case. However, it does usually work, which is a surprise for a bus with no standard or clear specification.

The reason it can be made to work is that you can specify a range of different operating modes, frequencies and polarities. This makes the bus slightly more complicated to use, but generally it is a matter of looking up how the device you are trying to work with implements the SPI bus and then getting the Edison to work in the same way. 

The bus is odd in another way - it does not use bidirectional serial connections. There is a data line for the data to go from the master to the slave and a separate data line from the slave back to the master. That is, instead of a single data line that changes its transfer direction, there is one for data out and one for data in. 

There is a variation on the SPI bus that does use a bidirectional mode where a single wire is used for the data, but the Edison doesn't support this.

It is also worth knowing that the drive on the SPI bus is push-pull and not open collector/drain. This provides higher speed and more noise protection as the bus is driven in both directions. 


You can see the sort of configuration that the Edison expects. There is a single master and at most two slaves. The signal lines are: 

  • MOSI Master Output Slave Input i.e. data to the slave
  • MISO Master Input Slave Output i.e. data to the master
  • SCLK Serial Clock which is always generated by the master

There can also be any number of SS - Slave Select - or CE Chip Select - lines which are usually set low to select which slave is being addressed.

Notice that unlike other buses I2C for example there are no SPI commands or addresses - only bytes of data. However slave devices do interpret some of the data as commands to do something or send some particular data. 

The Edison has only a single SPI bus exposed on the mini breakout board and only two SS lines. This means that in principle you can only connect two SPI devices. In practice mraa only uses CS1 and so you can only connect a single slave device.  This can be overcome by using GPIO lines as chip select lines and/or using CS0 directly. 


The pins that are used for the Edison's SPI bus are: 

MRAA NumberPhysical PinEdison Pin
9 J17-10 GP111 GPIO-111 SPI-5-CS1
10 J17-11 GP109 GPIO-109 SPI-5-SCK
11 J17-12 GP115 GPIO-115 SPI-5-MOSI
23 J18-10 GP110 GPIO-110 SPI-5-CS0
24 J18-11 GP114 GPIO-114 SPI-5-MISO
29 J19-2 V_V1P80
30 J19-3 GND
43 J20-2 V_V3P30




The data transfer on the SPI bus is also slightly odd.

What happens is that the master pulls one of the chip selects low which activates a slave. Then the master toggles the clock SCLK and both the master and the slave send a single bit on their respective data lines. After eight clock pulses a byte has been transferred from the master to the slave and from the slave to the master.

You can think of this as being implemented as a circular buffer - although it doesn't have to be. 




This full duplex data transfer is often hidden by the software and the protocol used. For example there is a read function that reads data from the slave and sends zeros or data that is ignored by the slave. Similarly there is a write function that sends valid data but ignores whatever the slave sends. The transfer is typically in groups of eight bits and usually most significant bit first but this isn't always the case. In general as long as the master supply clock pulses data is transferred. 

Notice this circular buffer arrangement allows for slaves to be daisy chained with the output of one going to the input of the next. This makes the entire chain one big circular shift register. This can make it possible to have multiple devices with only a single chip select but it also means any commands sent to the slaves are received by each one in turn. For example you could send a convert command to each AtoD converter in turn and receive back results from each one. (See:https://www.maximintegrated.com/en/app-notes/index.mvp/id/3947)

The final odd thing about the SPI bus is that there are four modes which define the relationship between the data timing and the clock pulse. The clock can be either active high or low - clock polarity CPOL and data can be sampled on the rising or falling edge of the clock - clock phase CPHA. All combinations of these two possibilities gives the four modes:

SPI ModeClock Polarity
Clock Edge
0 0 0 Clock active high data output on falling edge and sampled on rising
1 0 1 Clock active high data output on rising edge and sampled on falling
2 1 0
Clock active low data output on falling edge and sampled on rising
3 1 1 Clock active low data output on rising edge and sampled on falling

The way that the modes are named is common but not universal. 

There is often a problem trying to work out what mode a slave device uses. The clock polarity is usually easy and the Clock phase can sometimes be worked out from the data transfer timing diagrams and: 

  • First clock transition in the middle of a data bit means CPHA=0
  • First clock transition at the start of a data bit means CPHA=1

So, to configure the SPI bus to work with a particular slave device you have to 

  1. Select the clock frequency - anything from 125MHz to 3.8KHz 
  2. Set the CS polarity - active high or low
  3. Set the clock mode Mode0 thru Mode3

Now we have to find out how to do this using the mraa library.

Last Updated ( Thursday, 02 June 2016 )