Friday, October 7, 2011

Enabling SPI on Beagleboard xM

This is a short tutorial on enabling SPI on Beagleboard xM.

Background : SPI (Serial Perhiperal Interface) is a general-purpose digital I/O interface. SPI bus consists of at least three pins:
- Clock signal
- Slave-input/master-output (SIMO) pin
- Slave-output/master-input (SOMI) pin
- Zero or more chip-select (CS) pins.

The Beagleboard xM has four McSPI controllers out of which only SPI-3 and SPI-4 are bought out on the board. Each is capable of driving an SPI interface at up to 48 MHz.

- McSPI1: 4 channels
- McSPI2: 2 channels
- McSPI3: 3 channels (2 chip select brought out)
- McSPI4: 1 channel (1 chip select brought out)

Pre-requisite :

1. You have installed Angstrom Linux on the board. The current kernel version is 2.6.32.

2. You are using Ubuntu on the development machine. If you are using something else then the commands and package names might change. The development machine is the one on which you are doing all the development usually a x86 based system, also called as host machine. The target machine is the Beagleboard xM.

3. You need to install the ARM gcc cross-compiler on the development machine. In Ubuntu, you can do
$sudo apt-get install gcc-arm-linux-gnueabi

4. Also you will need git.
$sudo apt-get install git

Steps :

1. Download the Angstrom Linux kernel sources from and check out the "beagleboardXM" branch. The commit id that I have used in this tutorial is "12ca45fea91cfbb09df828bea958b47348caee6d"

$git clone git://
$cd angstrom-linux
$git checkout 12ca45fea91cfbb09df828bea958b47348caee6d
$git checkout -b spi

Alternatively, you can download the tar.gz file without the git history. The download link is available on on the right column "Download beagleboardXM as tar.gz"

$tar -zxvf angstrom-angstrom-linux-beagleboardXM.tar.gz

2. The SPI signals coming out of the SOC are multiplex with other signals. So, you need to set the pin multiplexer properly. There are two ways to do this, one is by setting it in the u-boot and another way is to set it in the kernel. The kernel settings will override the u-boot settings. In this guide I have not changed the u-boot, it is the default one that is available in the Angstrom demo. I have change the pin multiplexer in the kernel sources in the board file.

$gedit arch/arm/mach-omap2/board-omap3beagle.c

Add the following lines as per this patch If you not able to apply the patch you need to make the modifications manually.

Note : Always set the clock for SPI-3 & SPI-4 in input mode as :
omap_mux_init_signal("sdmmc2_clk.mcspi3_clk", OMAP_PIN_INPUT);
omap_mux_init_signal("mcbsp1_clkr.mcspi4_clk", OMAP_PIN_INPUT);

This will set the correct pin multiplexing mode and also register the SPI buses with the kernel.

3. Compile the kernel for Beagleboard

$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- mrproper
$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- omap3_beagle_defconfig
$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig

Enable the SPI related driver and make sure to compiled them directly into kernel and NOT as module.

Device Drivers > SPI Support > Debug support for SPI drivers
Device Drivers > SPI Support > McSPI driver for OMAP24xx/OMAP34xx
Device Drivers > SPI Support > User mode SPI device driver support

Save the configuration and finally compile the new kernel

$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage

4. For testing, compile the SPI test program available in kernel sources at "Documentation/spi/spidev_test.c" and save the binary output as "spitest"

$arm-linux-gnueabi-gcc Documentation/spi/spidev_test.c -o spitest

Also you need to short the SPI-4 SIMO and SOMI pins of the expansion header on the Beagleboard so that whatever data is sent the same is received back. These details are available in the ref. manual of Beagleboard

Note :
Refer page no. 107 - Figure 51 - Main Expansion Header Processor Connections
Refer page no. 108 - Table 22 - Expansion Connector Signals

You need to SHORT the PIN NO. 12 and 18 for SPI-4 of the expansion header on the Beagleboard. When you run the above test program whatever data is sent on input pins will be received back on the output pins.

5. Final step is to copy the "uImage" generated in the Step 3 and the "spitest" generated
in the Step 4 to the Beagleboard SD-Card. The "uImage" is copied to the "/boot" directory and "spitest" program is copied to the main "/" of the "ext3" partition. On booting the Beagleboard and you will get the following device files in the /dev directory. Whatever you read and write to these files in sent to the SPI pins.


Run the test program for SPI-4 and you will see the same input as output.

$./spitest -D /dev/spidev4.0

If you do not see the device files then check whether you have correctly enable the SPI drivers in the kernel in Step 3.