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 http://gitorious.org/angstrom/angstrom-linux and check out the "beagleboardXM" branch. The commit id that I have used in this tutorial is "12ca45fea91cfbb09df828bea958b47348caee6d"

$git clone git://gitorious.org/angstrom/angstrom-linux.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 http://gitorious.org/angstrom/angstrom-linux/commits/beagleboardXM on the right column "Download beagleboardXM as tar.gz"

$wget http://gitorious.org/angstrom/angstrom-linux/archive-tarball/beagleboardXM
$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 http://elinux.org/BeagleBoard/SPI/Patch-2.6.37. 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
http://beagleboard.org/static/BBxMSRM_latest.pdf.

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.

/dev/spidev3.0
/dev/spidev3.1
/dev/spidev4.0

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.

21 comments:

  1. Hey thanks for posting this! though im getting an error...

    on running :
    $make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage

    i get:

    /tmp/ccC0IXP0.s: Assembler messages:
    /tmp/ccC0IXP0.s:299: Error: selected processor does not support ARM mode `smc #0'
    /tmp/ccC0IXP0.s:337: Error: selected processor does not support ARM mode `smc #0'
    make[1]: *** [arch/arm/kernel/sysfs_v7.o] Error 1
    make: *** [arch/arm/kernel] Error 2

    any clue how i can fix this? Seems im not the only one (http://comments.gmane.org/gmane.comp.hardware.beagleboard.general/22312)
    Appreciate the help!
    --Z

    ReplyDelete
  2. this fixed it!

    http://wakefang.blogspot.com/2011/08/error-selected-processor-does-not.html

    ReplyDelete
    Replies
    1. Yhy dont you try the latest kernel 3.2.5. It should work without requiring any patches.

      Delete
  3. Hi pshah,

    I'm trying to follow your great tutorial, but I cannot apply the Patch-2.6.37 against the downloaded angstrom-angstrom-linux-beagleboardXM.tar.gz kernel.

    When I try, I receive the following error:

    ####

    $ patch -p1 --dry-run < spi-patch-2.6.37
    patching file arch/arm/mach-omap2/board-omap3beagle.c
    Hunk #1 succeeded at 30 with fuzz 2 (offset 1 line).
    Hunk #2 succeeded at 666 (offset 166 lines).
    Hunk #3 FAILED at 616.
    1 out of 3 hunks FAILED -- saving rejects to file arch/arm/mach-omap2/board-omap3beagle.c.rej

    ####

    The result is a partially edited file. Maybe the downloaded kernel version doesn't match with the version against which the Patch-2.6.37 was created.

    How can I fix this?

    Thank you in advance,

    Daniele

    ReplyDelete
    Replies
    1. Hi Daniele,

      Either checkout $git checkout 12ca45fea91cfbb09df828bea958b47348caee6d

      Or manually apply the patch lines - its really simple and only few lines of patch. Inside the omap3beagle_flash_init() function add the four lines as given in the end of the patch.

      Delete
    2. Hi pshah,

      thanks for the prompt reply!

      I tried to apply the patch against the kernel obtained via git with no luck. The downloaded kernel version is 2.6.32, while the spi patch was obtained against a 2.6.37 version.
      In fact, I successfully applied that patch against a vanilla 2.6.37 kernel.

      By the way, I manually edited the board-omap3beagle.c as you told me but it didn't works. BB xm boots fine, but no spi devices in /dev. Obviously I'm missing something.

      One thing I don't understand: you told me to add only four lines of code (taken from the end of the patch) into the omap3beagle_flash_init() function. I did it but
      it cannot be sufficient. Those lines are only function invocations (like omap3_beagle_config_mcspi3_mux()), so I added the relative function body too, as it is in the patch.
      Then I added the struct spi_board_info beagle_mcspi_board_info[] because it's needed. Finally, I removed the struct spi_board_info beaglefpga_mcspi_board_info[] because it's
      trying to use chipselect 0 on mcSPI 4 for an unknown external fpga expansion board I don't need.

      Please take a look at http://pastebin.com/NpCxxuaA

      It's my board-omap3beagle.c. Can you tell me what I am doing wrong?

      Thank you in advance!!!

      Daniele

      Delete
    3. Sorry I think there is some misunderstanding. You need to those 4 lines since

      Hunk #1 succeeded at 30 with fuzz 2 (offset 1 line).
      Hunk #2 succeeded at 666 (offset 166 lines).
      Hunk #3 FAILED at 616

      Only the Hunk #3 had failed. So you need to add that manually.

      Delete
    4. I saw the your code. It seems correct except that you need to move the 4 lines after omap_serial_init() which is in static void __init omap3_beagle_init(void) function (line no. 800)

      Also make sure that you carry out step no. 3 correctly and enable the SPI related drivers in the kernel config.

      Let me what happens.

      Delete
    5. here is the patch for 3.6.32

      http://elinux.org/BeagleBoard/SPI/Patch-2.6.32

      hope this helps.

      Delete
  4. Hi pshah,

    sadly the elinux.org Patch-2.6.32 doesn't apply to the downloaded kernel from gitorious.org, even if it's the same version.

    I was again forced to edit board-omap3beagle.c manually. The good news is spi now it's working!

    On the bb xm now I see the following:

    root@beagleboard:~# ls /dev | grep spi
    spidev3.0
    spidev3.1
    spidev4.0

    Thank you for the support!!!

    Daniele

    ReplyDelete
  5. hello,
    I patched the available patch 2.6.37 to my kernel version 2.6.39 ... and I did the procedure you state in this page..

    I could make the spi diver be available at user pins, but my problem is I am always receiving zeros. I shorted pins 12 and 18 and compiled the code "spitest"..

    could you tell me where the source of my problem is?

    thanks

    ReplyDelete
  6. sources from git have been updated and when trying to compile gets ERROR, I recommend to download the .tar source

    David Calero

    ReplyDelete
  7. I would highly recommend switching your distribution to: ArchLinux ARM http://archlinuxarm.org

    ArchLinux ARM runs just like your desktop linux system: no cross compiling.

    On BeagleBoardxM, spi is already built into the current 3.4.1 linux-omap kernel package. To enable spidev just pass the kernel parameter "buddy=spidev" (add to uEnv.txt)

    HTH...

    johnea

    ReplyDelete
  8. Hi all,

    I followed the option that johnea told to install an ArchLinux instead of Angstrom and I was surprised of how easy was to setup de spidev and to test it. It works perfect!!!

    Download the compiled sources from http://archlinuxarm.org/platforms/armv7/beagleboard-xm
    and follow the instructions of installation. To configure the spidev just pass the buddy=spidev parameter to the kernel(from the boot.scr).

    Thank You so much Johnea!!!!

    ReplyDelete
  9. Hi, Johnea and Calero, I tried with the arch linux procedure and couldn't get no spidev... on my devices. the kernel version I'm using is 3.4.4. I typed buddy=spidev inside the uEnv.txt file. later I removed it and made a new boot.scr with the spidev as the buddy. but none of it worked, do you have any suggestion?

    ReplyDelete
  10. Hello,

    When i follow this tutorial, i need to use a patch in order to avoid this error:
    /tmp/ccC0IXP0.s: Assembler messages:
    /tmp/ccC0IXP0.s:299: Error: selected processor does not support ARM mode `smc #0'
    /tmp/ccC0IXP0.s:337: Error: selected processor does not support ARM mode `smc #0'
    make[1]: *** [arch/arm/kernel/sysfs_v7.o] Error 1
    make: *** [arch/arm/kernel] Error 2

    This is the link for the patch:
    http://wakefang.blogspot.com/2011/08/error-selected-processor-does-not.html

    After generating the uImage i replace it with the one located on de EX3 formated partition in the sub directory /boot

    As a result of this action the beagleboard won't boot. So next i placed the uImage on the boot partition, as a result of this i am able to boot the BB, but i don't any SPIDEV file in the directory /dev

    has anyone any idea/experience where my problem could be situated?

    regards,
    Bart

    ReplyDelete
  11. can you give me link download toolchain for beagleboard rc4 ?? and source kerner?
    thanks!!!!!!!

    ReplyDelete
  12. i am using omap3730 processor with 2.6.32 kernel version .. i can able to create /dev/spidev3.0 device entry. If i tried to read or write there is no waveform on the respective pins. Clock also not able to see

    ReplyDelete
  13. I dont have the board anymore with me. So I cant help any further.

    ReplyDelete