BeagleBoard/SPI

Background
Serial Perhiperal Interface (also known under the names of Microwire or four-wire) is a general-purpose digital I/O interface used by many ICs including sensors, converters, audio codecs, and various types of memory. An SPI bus consists of at least three pins: a clock, a slave-input/master-output (SIMO) pin, a slave-output/master-input (SOMI) pin, and zero or more chip-select(CS) pins.

The OMAP3 has four McSPI controllers, each capable of driving an SPI interface at up to 48 MHz. Each of these controllers has a finite number of chip select lines. Of these four, only SPI3 and SPI4 are brought out on the BeagleBoard.
 * McSPI1: 4 channels
 * McSPI2: 2 channels
 * McSPI3: 3 channels (2 CS brought out)
 * McSPI4: 1 channel (1 CS brought out)

Below is a description of the steps necessary to use SPI on BeagleBoard. If you are particularly impatient, you can start with one of the patches found in the Kernel Patches section.

Configuring Pinmux
These devices are fully supported by the Linux kernel's mcspi driver. That being said, one will need to make some minor modifications to the BeagleBoard's board file (arch/arm/mach-omap2/board-omap3beagle.c) in order to use them.

First, the pin multiplexer needs to be configured to expose the McSPI signals. As of BeagleBoard rev.C4, the following SPI signals are available on the Beagle's 28-pin expansion header; the SPI signals are available in pinmux mode 1, while mode 0 names are also given for reference.

(*)  Important:  The CLK pins must be put in input mode for the chip to correctly register input on SOMI. Failure to set CLK as an input will result in all reads producing zeros.

Configuring spi_board_info
In addition to the pin multiplexer, one must also tell the kernel a bit about the SPI controller itself. This is done in the board file using an spi_board_info struct. For example, to configure McSPI3.0, one might use the following, static struct spi_board_info beagle_mcspi_board_info[] __initdata = { {	.modalias	= "spidev", .max_speed_hz	= 48000000, //48 Mbps .bus_num	= 3, .chip_select	= 0, .mode = SPI_MODE_1, } };

One would then register this with the SPI subsystem during board initialization (i.e. omap3_beagle_init), with the following, spi_register_board_info(beagle_mcspi_board_info,	ARRAY_SIZE(beagle_mcspi_board_info));

Patches

 * 2.6.37 (config) Patch against kernel 2.6.37 to expose both McSPI 3 and 4 to userspace through spidev.
 * rcn-ee 2.6.38.2-d9 (config) Patch against [rcn-ee patched kernel 2.6.38.2-d9] to expose McSPI3 to userspace through spidev. One of the rcn-ee patches enables MMC2 which overrides mux settings for the McSPI3 pins; this patch disables this. It also disables I2C2 and makes GPIO_144 and GPIO_183 available via /sys/class/gpio.

Little Word about recompiling the Kernel
Ok, one would have acquired by now all the knowledge necessary to get SPI going on the Beagle Board. However, reconstructing the kernel via OE may be a little tricky, since it is a complex tool and some time is demanded to really understand it. Therefore, it is really useful to know how to compile the kernel by yourself, the instructions on tell you how to do it using "Quilt" (very very handy) kernel 2.6.28 is a good option for the ones using Quilt (take a look at the recipe and you will get why).

Debian/Ubuntu: For a more recent kernel, and as an alternative to using Quilt and/or patching the kernel by hand, [Robert C Nelson's rcn-ee omap kernel tools] are recommended. This link is for 2.6.38.2 but other kernel versions are also available. You'll probably need a uInitrd as well; the easiest way is to start at BeagleBoardUbuntu using one of the prebuilt kernels and base system images, then build your own up from there.

Openembedded: Andruk has been very kind to provide his files mux.c(arch/arm/mach-omap2), mux.h(arch/arm/plat-omap/include/mach) and board-omap3beagle.c(arch/arm/mach-omap2) they are not to be copied but to be consulted and adapted to your needs. Philip Balister has also made his patch for OE available (useful because it shows which configuration must be active in the kernel .config file).

They can be found here:

TIP: apply the patches, then modify your board-omap3beagle.c. mux.c and mux.h

TIP2: some people complained about the MMC card stopping when CONFIG_OMAP_MUX is active. One pointed solution was to comment this line "omap_cfg_reg(AH8_34XX_GPIO29);" in the "board-omap3beagle.c" file (apparently u-boot configures this pin in a different way). More about this issue can be found in:   

Chip Select polarity
Some devices expect that the CS lines are active-high (instead of the more common active-low). This can be accomplished by modifying spi_board_info in the board file as follows,

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 58bacb6..44643b7 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -526,7 +526,7 @@ static struct spi_board_info beagle_mcspi_board_info[] = { .max_speed_hz  = 48000000, //48 Mbps .bus_num       = 3, .chip_select   = 0, -              .mode = SPI_MODE_1, +              .mode = SPI_MODE_1 | SPI_CS_HIGH, },

Hardware

 * Trainer Board can be used for access to level shifter SPI and provides prototype area
 * Zippy Board uses Microchip's ENC28J60 via the SPI interface, schematics are available
 * Zippy2 Board uses Micrel's KSZ8851 via the SPI interface, schematics are available

Discussion
Here are some mailing list threads of various peoples' experiences getting SPI running on the Beagle:


 * Installing Ubuntu 12.10 and enabling SPI
 * MCSPI3 Detailed example (BBXm), Start->Finish
 * PYTHON SPI how to, BBXM
 * MCSPI3 working, both ways
 * MCSPI TX works fine, but RX all zeros
 * SPI testing
 * SPI Troubles
 * SPI with Beagleboard (for a newbie in Linux)
 * McSPI with REV C