Raspberry Pi i2c/spi setup

UPDATE-UPDATE: The standard raspbian distro now comes with full support out of the box.

UPDATE: adafruit now has an rpi distribution that is up-to-date and prebuilt with spi and i2c working.  you can get it here: http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/

 

I just got my Raspberry Pi last week and it took me an evening to get the SPI and I2C working (thanks to some great people who wrote drivers!).  I had to dig a decent amount to find the best way to get I2C and SPI working on my RPi.  To help, I’ve decided to collect the links I used to get the default Raspberry Pi Debian image to the point where I could get SPI and I2C working.

Summary:

  1. Start with the latest Debian image
  2. Update firmware on SD card
  3. Install Chris Boot’s 3.2 kernel with drivers precompiled
  4. run ‘modprobe i2c-dev’ expose /dec/i1c-0

More Words:

I used the debian squeeze image found here dated 19-4-2012.  Unfortunately there are no kernel drivers for SPI and I2C in the default image, which I find strange since the coolest part about the Raspberry Pi is the available GPIO.

Chris Boot has done an excellent job of collecting/writing SPI and I2C code and precompiling a kernel so you don’t have to.  One thing to note though is that his kernel puts the pins into I2C mode and SPI mode by default (at least at the time of this writing).  As mentioned on Chris Boot’s page, you need to update the “firmware” on your Debian image (not you cannot brick your RPi doing this, worst case is you reimage your SD card)

The easiest way to update the firmware is with hexxeh’s firmware updater.  For me this was not without issue though.  Chris Newland has a good description of the issues and how to get it working.  For me I needed a reboot between step 3 and 4, so if its not working, try a reboot.

Using SPI:

So far I’ve actually been able to get everything I’ve needed done though reading and writing /dev/spi0.0 and /dev/spi0.1, which chooses chip select 0 and 1 respectively.   Below is example python code to read from the MAX1113 ADC.

def readadc(channel):
	if channel == 0:
		cmd = chr(int('10001111',2))
	if channel == 1:
		cmd = chr(int('11001111',2))
	if channel == 2:
		cmd = chr(int('10101111',2))
	if channel == 3:
		cmd = chr(int('11101111',2))

 	####note this will actually bring CS high between write and read
	####which may not work for all devices but it works with this device
	#write to ADC to choose channel
	f = open('/dev/spidev0.0','w')
	f.write(cmd)
	f.close()
	#read from ADC
	f = open('/dev/spidev0.0','r')
	data = f.read(2)
	db = bytearray(data)
	#data format 0-0-msb-x-x-x-x-x-x-lsb-0-0-0-0-0-0
	value = (db[0]<<2) | (db[1]>>6)
	return value

Using I2C:

for I2C I’ve been using the i2c-tools package, which can be gotten with apt-get:

rpi:~# apt-get update
rpi:~# apt-get install i2c-tools

The important commands installed by 12c-tools are i2cdetect , i2cset, i2cget

Other (better) methods for SPI and I2C:

The other ways to get at spi and i2c are either directly from the kernel space, which if your reading this you probably don’t want to do, and through system calls.  I haven’t needed either method yet but if you want something to search for I believe you need to use the ioctl() system call.  I’ll post an update once I need more advanced control and have figured it out.  There is also an smbus (another name for i2c) library for python, which I haven’t tried yet and i’d be willing to be there is already an SPI library as well.

Leave a Reply

Your email address will not be published. Required fields are marked *