Userland SPI on the BeagleBone with Ubuntu

March 26, 2012

For a project I’m working on I want to get a BeagleBone talking to a nRF24L01+ module. The first step is to get userland SPI access working on the BeagleBone, and last week I spent some time getting this going. The good news is that Robert C Nelson has merged my patch into his github repo linux-dev and a prebuilt image is available to download. Read on to learn how to build from source and get details of the patch.

Standard Ubuntu running on the BeagleBone

Reading this post on the BeagleBoard Google Group, led me to Brian Hensley’s blog post SPI working on the Beagleboard XM rev C. With some minor modifications I got Ubuntu installed onto an SD card and running on my BeagleBone; first off download a stable release of Ubuntu for ARM:

wget http://rcn-ee.net/deb/rootfs/oneiric/ubuntu-11.10-r6-minimal-armel.tar.xz

And then extract and change directory:

tar xJf ubuntu-11.10-r6-minimal-armel.tar.xz
cd ubuntu-11.10-r6-minimal-armel

Then run the script to install the files on the SD card (replace ‘/dev/sdd’ with the drive name for your SD card):

sudo ./setup_sdcard.sh --mmc /dev/sdd --uboot bone

Once completed (approx 10 minutes), insert the SD card into your BeagleBone, and all being well, Ubuntu will be up running on your BeagleBone. Verify by running:

uname -a

which should give:

Linux omap 3.2.0-psp6 #2 Thu Mar 22 10:36:44 GMT 2012 armv7l armv7l armv7l GNU/Linux

and

lsb_release -a

should give:

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 11.10
Release:        11.10
Codename:       oneiric

Setup to enable rebuilding the Linux kernel

In order to enable userland SPI we need to be able to rebuild the kernel, so grab the Linux source:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

Install the required tools and libs by running:

sudo apt-get install gcc-4.4-arm-linux-gnueabi git ccache libncurses5-dev u-boot-tools lzma

Note that I am running on Debian 6.04 in a VirtualBox VM and had to add the following sources to /etc/apt/sources.list:

deb http://www.emdebian.org/debian/ squeeze main
deb http://ftp.uk.debian.org/emdebian/toolchains squeeze main
deb http://emdebian.bytesatwork.ch/mirror/toolchains squeeze main

As per these instructions, clone Roberts git repo with:

git clone git://github.com/RobertCNelson/linux-dev.git
cd linux-dev

switch to the am33x-v3.2 branch with:

git checkout origin/am33x-v3.2 -b am33x-v3.2

Now copy system.sh.sample to system.sh and update system.sh with the settings for your setup:

cp system.sh.sample system.sh

For my setup I had to make the following changes to system.sh:

uncomment line 14, change from:

#CC=arm-linux-gnueabi-

to:

CC=arm-linux-gnueabi-

at line 60 update the path to your linux source, change from:

#LINUX_GIT=~/linux-stable/

to:

LINUX_GIT=~/linux-stable/

uncomment line 70 to set the kernel entry point, change from:

#ZRELADDR=0x80008000

to:

ZRELADDR=0x80008000

uncomment line 80 to set the BUILD_UIMAGE flag, change from:

#BUILD_UIMAGE=1

to:

BUILD_UIMAGE=1

and finally at line 89 uncomment and set the path to the SD card, change from:

#MMC=/dev/sde

to:

MMC=/dev/sdd

Build the Linux kernel

We can now run the buid_kernel.sh script which will clone the Linux source from our linux-stable directory, update to the latest version in git and apply the patches for running on the BeagleBone (this includes the userland SPI support patch :-) ).

./build_kernel.sh

Whilst the script is running the Kernel Configuration screen will be shown, to enable SPI scroll down to the ‘Device Drivers’ option, hit enter and scroll down to ‘SPI Support’ and hit enter again, now make sure the following are selected:

[*] Debug support for SPI devices
[*] McSPI driver for OMAP
[*] User mode SPI device driver support

Test userland SPI

Once the build had completed, takes a few hours on my setup, there will be a uImage file in ~/linux-dev/deploy, install this to your SD card with:

./tools/load_uImage.sh

Install the SD card into the BeagleBone, and check that SPI is available by running :

ls /dev/spi*

on the bone, which should give:

/dev/spidev2.0

We can also run a further test by cross compiling spidev_test.c in the VM:

cd ~/linux-stable
arm-linux-gnueabi-gcc Documentation/spi/spidev_test.c -o spitest

Remove the SD card from the BeagleBone and transfer spitest to the SD card:

cp spitest /media/rootfs/home/ubuntu/spitest

reinsert the SD card into the BeagleBone, connect pins 29 and 30 together on header P9, boot and run:

sudo ./spitest -D /dev/spidev2.0

All being well you should see:

spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D

Next step is to connect the SPI to an nRF24L01+ module and get them talking!

Many thanks to Robert C Nelson, Branden Hall and Craig Berscheidt.

Userland SPI support patch details

FYI: the userland SPI support patch is based on the patch from Craig Berscheidt and makes the following changes to ~/linux-dev/KERNEL/arch/arm/mach-omap2/board-am335xevm.c:

Adds the bone_am335x_slave_info struct:

static struct spi_board_info bone_am335x_slave_info[] = {
  {
    .modalias      = "spidev",
    .irq           = -1,
    .max_speed_hz  = 12000000,
    .bus_num       = 2,
    .chip_select   = 0,
  },
};

adds an init function:

/* setup beaglebone spi1 */
static void bone_spi1_init(int evm_id, int profile)
{
  setup_pin_mux(spi1_pin_mux);
  spi_register_board_info(bone_am335x_slave_info, 
    ARRAY_SIZE(bone_am335x_slave_info));
  return;
}

and adds the following line to beaglebone_dev_cfg by:

  {bone_spi1_init,	DEV_ON_BASEBOARD, PROFILE_ALL},