Chapter 5. Interfacing with High-speed Sensors Using SPI
In the previous chapter, you worked with the I2C bus to communicate with an FRAM device that requires far more complex communications than that of the simple on/off digital communications used by GPIOs. I2C is very powerful and flexible, but it can be quite slow.
In this chapter, you will learn how to write an Android app that uses the BBB's SPI capabilities to retrieve environmental data from a high-speed sensor. We will cover the following topics:
Understanding SPI
Multiplexing for SPI on the BBB
Representing SPI devices in the Linux kernel
Building an SPI interface circuit
Exploring the SPI sensor example app
The Serial Peripheral Interface (SPI) bus is a high-speed, serial bus originally developed by Motorola. Its purpose is to facilitate point-to-point communication between a single master device and one or more slave device. The SPI bus is typically implemented using four signals:
Like I2C, the master on the SPI bus sets the pace of communication between the master and the slave by producing a clock signal. With SPI, this clock signal is called the
serial clock (SCLK
). Unlike the bidirectional data bus of I2C, SPI uses dedicated outgoing and incoming data lines for each device. Using dedicated lines results in SPI being able to achieve communication speeds far higher than those of I2C. The master sends data to the slave via the
master out, slave in (MOSI
) signal, and it receives data from the slave via the
master in, slave out (MISO
) signal. The
slave select (SS
) signal, also called
chip select (CS
), tells the slave device whether it should be...
Multiplexing for SPI on the BBB
The AM335X processor of the BBB provides two SPI buses: SPI0 and SPI1. Both buses are accessible via the P9 header. By default, no SPI buses are muxed. The following figure shows each of the potential pins on the P9 header where SPI signals can be muxed in different pinmux modes:
When deciding how you would like your pins to be muxed using SPI in your projects, keep the following in mind:
When in doubt, stick with using the SPI0 bus muxed to the P9.17, P9.18, P9.21, and P9.22 pins.
The SPI1 channel conflicts with the I2C bus used by the capemgr (P9.20) and audio output (P9.28, P9.29, P9.31). Be aware that muxing these pins to use SPI1 can disable some other functionality that you are depending upon for a full-featured Android system.
If you are using other cape boards in your projects, make sure that these capes don't require the use of the SPI buses. Only one device can exist on each SPI bus...
Representing SPI devices in the Linux kernel
The Linux kernel provides a general-purpose SPI driver named spidev
. The spidev
driver is a simple interface that abstracts many of the housekeeping details involved in SPI communications. The spidev
driver is exposed via the /dev
filesystem as the /dev/spidevX.Y
file. Multiple versions of these spidev
files can be present depending upon the number of SPI buses configured in the Device Tree. The X
value in the spidev
filename refers to the SPI controller number (1 for SPI0 and 2 for SPI1), and the Y
value refers to the SPI bus of that controller (0 for the first bus and 1 for the second bus). For the examples in this book, you will only be using the first SPI bus of the SPI0 controller, so /dev/spidev1.0
is the only file with which PacktHAL will interact.
Preparing Android for SPI sensor use
In Chapter 2, Interfacing with Android, you used adb
to push two prebuilt files to your Android system. These two files, BB-PACKTPUB-00A0.dtbo
and init.{ro...
Building an SPI interface circuit
Now that you have an understanding of where SPI devices are connected to the BBB and how the Linux kernel presents an interface to these devices, it is time to connect an SPI device to the BBB.
As we mentioned in Chapter 1, Introduction to Android and the BeagleBone Black, you will be interfacing with a sensor in this chapter. To be specific, we will be using a Bosch Sensortec BMP183 digital pressure sensor. This 7-pin component provides pressure data samples (in 16- to 19-bit resolution) and temperature data samples (in 16-bit resolution) for applications used for navigation, weather forecasting, and to measure changes in vertical elevation and so on.
This particular chip is only available in a
land grid array (LGA), which is a surface mount package that can be difficult to work with when building prototype circuits. Luckily for us, the AdaFruit breakout board for the sensor already has the chip mounted, which makes prototyping simple and easy.
Exploring the SPI sensor example app
In this section, you will examine the example Android app that performs the SPI bus interfacing on BBB. The purpose of this application is to demonstrate how to use PacktHAL to perform SPI reads and writes from within an actual app using a set of interfacing functions. These functions allow you to send and receive data between the SPI bus master (the BBB) and the SPI bus slave (the SPI sensor). The low-level details of the hardware interfacing are implemented in PacktHAL, so you can quickly and easily get your apps interacting with the sensor.
Before digging through the SPI app's code, you must install the code to your development system and install the app to your Android system. The source code for the app and the precompiled .apk
packages are located in the chapter5.tgz
file, which is available for download from Packt's website. Follow the same process to download and add the app to your Eclipse ADT environment that was described in Chapter 3, Handling...
In this chapter, we introduced you to the SPI bus. You constructed a circuit that connected an SPI pressure and temperature sensor breakout board to the BBB, and you learned about the portions of the PacktHAL init.{ro.hardware}.rc
file's Device Tree overlay that are responsible for configuring and making the SPI bus and spidev
device driver available for your app's use. The sensor app in this chapter demonstrated how complex tasks in the HAL can be hidden from the app using a small set of functions that hide the low-level details. These simplified PacktHAL function calls can be made from a class derived from AsyncTask
to perform more complex interfacing tasks simply from within an app.
In the next chapter, you will learn about combining GPIO, I2C, and SPI together into an app capable of providing a complete hardware solution that uses a long-lived hardware-interfacing thread.