INSTALL
First you'll need to download the beta "Wheezy" debian package from here. Then follow the normal instructions for installing it to your board. Once you have installed it and booted up for the second time i ran some updates (That took hours!!)
sudo apt-get update
sudo apt-get upgrade
While that is updating lets talk a little bit of SPI background knowledge is needed in order to get this working. First off Serial Peripheral interface (SPI) is made up of 4 wires normally. It is a standard that was designed by Motorola for use with their micro controllers. If you're interested in learning more about SPI i've added the Wikipedia link. Here is what a standard SPI setup looks like, multiple slaves is optional.
SS - Slave Select (Beagleboard community calles this Chip Select (CS))
MOSI - Master Out Slave In
MISO - Master In Slave Out
CLK - Clock

More INSTALL
Next it was time to update to the latest firmware for the board, as the latest has brought out the SPI controller. To do so I used Andrews Hexxeh rpi-update to do this. Some needed tools...
sudo apt-get install git
Now lets download his tool and install change who has access to read/write the tool.
sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update
sudo chmod +x /usr/bin/rpi-update
Once this is done you can run it by calling the following command. (mine took a while).
sudo rpi-update
*NOTE - while I was doing this I ran out of space on my 4GB drive. I figured I wasn't really low on space and when I checked it I found my windows tool originally only made me a 2GB partition. There are many ways to do this, but I used GPARTED to expand my space to the real 4GB. It's a live CD...
SanDisk 4GB Extreme 3 SD Card w/Reader
So once the updates are all completed. I rebooted my Pi.
sudo shutdown -h now
Unplug the power and plug it back in. And when I rebooted I went to my /dev/ directory and found my spidev devices!
The last part of this is to test the SPI signal. I'm going to download spidev_test.c
wget http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/spi/spidev_test.c -O spidev_test.c
Next we want to short the MISO and MOSI pins. Located as GPIO 9 & GPIO 10 as seen below.
We want to edit the spidev_test.c file so it it uses the correct spidevice in our /dev/ folder.
nano spidev_test.c
scroll down and change the device to "spidev0.0" and then save it by pressing the Ctrl+O to save and Ctrl+X to exit. lets compile this thing and run it now.
gcc spidev_test.c
sudo ./a.out
If you see this it's working.
If you see this it's not working.
For more information on how to control your SPI with python try checking out my post for how to do so on the beagleboard xm. Many have found it useful and i'm sure you will too. Python controlling SPI on the Beagleboard XM

Thanks for the Great post!
ReplyDeleteExcellent write-up. Two things:
ReplyDelete1) You might mention you can opt to expand the roor partition from the raspi-config menu on the first boot (saves hassle later).
2) You should add a step after the rpi-update to comment out the blacklist spi-bcm2708 entry in /etc/modprobe.d/raspi-blacklist.conf to load the spi-bcm2708 module on boot. (Otherwise you don't see the spidev modules loaded after the reboot.)
Instructions are clear and my spi is now available !
DeleteBy the way, running 'raspi-config' can also be run at anytime later to expand your root partition.
I actually had to do what you mentioned, thank you for the hint on uncommenting the module!
DeleteThanks for the blacklist tip! I'm pretty green, so I had to go elsewhere to figure out HOW to do that...
Delete$ sudo vi /etc/modprobe.d/raspi-blacklist.conf (to be able to view/edit the file)
press 'i' to be able to insert characters
add '#' in front of 'blacklist spi-bcm2708' to comment it out
press 'i' again to exit insert mode
exit the editor with ':wq'
There may be better/faster ways to do this, I'm just regurgitating. But that worked for me!
Yep, there's a better way. Instead of '$ sudo vi ' use the command '$ sudo nano' It's a way better editor.
DeleteAlso, I hadn't changed my keyboard layout from 'gb' to 'us' when I tried this, and I got '£' instead of '#' when I tried to comment out that line. Like I said, I'm pretty green.
Thanks for this helpful post. The command line to get spidev_test.c needs a bit of tweaking. Here's my version:
ReplyDeletewget http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git\;a=blob_plain\;f=Documentation/spi/spidev_test.c -O spidev_test.c
Thanks for the update :)
DeleteBrian
My apologies for appearing to be nit-picking...
DeleteI think you still need to escape the semicolons in the command (see my line above).
Peter
Is it possible to have a SPI clock > 500khz?
ReplyDeleteI have tested and the SPI is working up to 15 MHz = 15000 KHz. André
DeleteDo you have to compile a new kernel to get past > 500Khz ? I found the "max speed" setting in
Deletearch/arm/machbc2708/bcm2708.c is 500Khz. Why is that set so low anyway? Why not set it to 32Khz in the Kernel and set it lower in a setting that is manageable without editing the kernel? Compiling a kernel proves to be beyond me.
No, i have changed the speed setting in the above spidev_test.c program like
Deletestatic uint32_t speed = 15000000;
And then tested with the same program.
André
It seems Brian's method for installing the SPI drivers doesn't set the SPI speed in the kernel as Occidentalis does (which is good). I am using Adafruit's light painting python script to process images and output to a LPD8806 LED strip http://learn.adafruit.com/light-painting-with-raspberry-pi/software and Brian's method to install the drivers. It works but I can't figure out how to set the SPI speed within a Python script. I just rebooted our website http://stargateeggbeater.com/ spherical POV display
DeleteAlso, any one know how large the SPI hardware buffer is?
ReplyDeleteJust Like to say thank you, got it working in no time
ReplyDeleteAs of right now (Nov 26, 2012, 10:50AM EST) "sudo rpi-update" is failing with the error message:
ReplyDelete/usr/bin/rpi-update: 1: /usr/bin/rpi-update: Syntax error: redirection unexpected
As far as I can tell, I got the rpi-update file as described in this page.
"file /usr/bin/rpi-update" reports
/usr/bin/rpi-update: HTML document, ISO-8059 text, with very long lines
ls -1 /usr/bin/rpi-update reports a 193705 byte file.
I got this once too. I think I spelled the URL wrong.
DeleteThe problem with rpi-update is not a deal-breaker. Likely my Pi is new enough already. "sudo modprobe spi_bcm2708" creates the devices and spidev_test.c works as advertised. Many thanks for this post.
ReplyDeletemodprobe spi_bcm2708 - this worked for the loop test
Deletemodprobe spidev -- I had to do this aswell to get my SPI working with an external microcontroller
Excellent tutorial, nice and clear.
ReplyDeleteI notice the Raspberry Pi comes with the kernel module for the DS3234 RTC,
Any chance of showing how to get that wired in and the used as the RTC rather than NTP?
(as a real-world example of using SPI with the Raspberry Pi...)
ReplyDeleteMany Thanks for your help from Germany. It was very usefull for me. Sorry for my poor english.
ReplyDeleteBest regards
Thomas
Can i install more devices for spi? 2 devices are not so much.
ReplyDeleteThomas
You should be able too since SPI works on the grounds of the same MISO, MOSI and CLK lines but different CS/SS lines. When you use 0.0 or 0.1 SPI devices this should only be using the different CS/SS lines. If you want more than 2 devices you're out of luck for the raspberry pi.
DeleteCheers,
Brian
The Chip Select (CS) line doesn't have to come from the SPI hardware. Any GPIO pin that isn't in use elsewhere for chip select as long as you only have one device on the SPI bus which has its chip select line pulled low.
DeleteThe built in drivers only allow easy access to 2 devices but you could simply combine the SPI driver with your own GPIO code to manage more devices.
No reason the driver couldn't be modified to map more chipselects to the additional IO pins.
Keep in mind, devices like the Arduino don't even HAVE actual chip select lines when in master mode, you just set any other random pin you want thats tied to the SPI device you want to activate. All other GPIO tied to SPI devices are held high to prevent them from talking or listening.
It's possible to send 16 bits per word? I'm trying to change the file with not good results.
ReplyDeleteSPI is a byte oriented interface. If you want 16 bits, you have to send two bytes yourself.
DeleteI have an issue with my CS signalfrom my RPi appearing as a clock with opposite polarity to my SCLK. I am calling the program using: sudo ./a.out -D /dev/spidev0.0
ReplyDeleteIs there another setting I have to change before I can connect to external devices?
I believe the CS line is active low by default. But you shouldn't be seeing it as a clock. How are you determining this is true? Make sure you're using the right pins on the board, and if you have access to an oscilloscope check it. Send me a picture if you can.
DeleteCheers,
Brian
brian (dot) e (dot) hensley (at) gmail (dot) com
.... so what do we do if its not working? I'm very confused. Any suggestions?
ReplyDeleteWell lets define not working. Are you getting any SPI devices showing up in the /dev folder?
Deletecheers,
Brian
Hi Brian! Thanks so much for the reply. I've worked through this whole tutorial and my output is all 0's instead of the decoded output of the spidev_test.c script. I do have the SPI devices in the /dev folder.
DeleteHi Alanna!
DeleteIf you see the SPI device in the /dev folder than that's most the battle. From here I would focus on making sure you have the correct pins (MISO & MOSI) pins connected on the board. Other than that make sure the script calls the correct spi device (hint: either 0.0 or 0.1 should work).
Cheers,
Brian
Hi Brian,
ReplyDeleteThank you again for the fast response! I was not aware that I needed to wire the raspberry pi at all. Can you explain this further? What should I have wired exactly?
Thank You,
Alanna
Hi Alanna,
DeleteIf you look back up at the green picture of the pins on the Raspberry Pi you'll notice pins 9 & 10 are the MISO and MOSI. This is the data out and data in pins. If you don't have those talking to another device or to each other than you won't see data coming back into your device.
I would recommend shorting those two pins together. After that your c program will work. eventually you'll have a SPI device connected and it will send data to and from the SPI stack.
Cheers,
Brian
OH MY GOSH! IT WORKED!!
DeleteDo you have any suggestions on where to look for a quick example of sending data from a GPIO output to go through the SPI?
Brian, your blog has been the most helpful with SPI that I've found so far and I've been doing a lot of researching trying understand all this. I just want to thank you!
Glad it worked for you Alanna!
DeleteMy only example is for sending values through the SPI with python.
http://www.brianhensley.net/2012/02/python-controlling-spi-bus-on.html
Cheers,
Brian
Hi,
ReplyDeleteI have an android board with can spi, I want to know how can we get the details of the data which we send/write through socket to CAN-SPI.
I have a target side application and with that I am sending the data in bytes(a string data) to socket and which should straem in to CAN-SPI
any Idea?
Great post!!!! :D
ReplyDeleteDEAD BEEF BAAD F00D. It works!
ReplyDeleteThanks, brother, for the most direct and successful Pi SPI lesson. Well done.
A ZBasic ZX24 slave will be talking with the Pi before the sun sets. Thanks.
Tom
Great write-up. Other than the non-escaped semi-colons in the last wget, it worked as a charm.
ReplyDeleteThanks,
/Bo
Is it possible to use PIN 10 as MOSI while still using pin 9 as a GPIO pin if you don't need master input. I imagine the answer is No. But I'm hoping it might be "Yes"?
ReplyDeleteAlso I assume that SS or CS isn't part of the driver but rather tied directly to ground or if you want to do it with the Pi you have to drive one of the GPIO pins is that correct?
Thanx for the tutorial but...
ReplyDeleteafter the job in /dev dir no spidev0.0 & spidev0.1
so you must do:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
add # before the 3rd line
$ cat /etc/modprobe.d/raspi-blacklist.conf
# blacklist spi and i2c by default (many users don't need them)
#blacklist spi-bcm2708
blacklist i2c-bcm2708
save, exit & reboot
that's it!
Hi Andrea,
DeleteYes from what i'm seeing on many builds of the OS it is getting simpler. All that is needed is for a couple lines to be commented or uncommented. Like I did for my beagleboard xm SPI tutorial i'll have to go revisit a new download and confirm your findings and update the tutrorial. Its just a matter of when I get time to do it. Thanks for the information though!
Cheers,
Brian
Wow ... thanks for this. Got me pointed in the right direction.
ReplyDelete(With the newest wheezy all I had to do was uncomment the line in the black list and reboot.)
Andre
Yes from what i'm seeing on many builds of the OS it is getting simpler. All that is needed is for a couple lines to be commented or uncommented. Like I did for my beagleboard xm SPI tutorial i'll have to go revisit a new download and confirm your findings and update the tutrorial. Its just a matter of when I get time to do it. Thanks for the information though!
DeleteCheers,
Brian