Raspberry Pi and I2C

Update: 2014; all current ByVac I2C products work with the Raspberry Pi and the Pichips range have been designed for that purpose. This text has been kept for archive reasons.

There are several methods of using I2C on this device, however at the time of writing, September 2012, the Broadcom IC does not support clock stretching and this has implications for I2C devices that rely on it. Most BV devices require either the clock stretching to work or a bit slower bus frequency, in practice this is just under the normal 100KHz.

Some BV devices work without the need for clock stretching so try it first, probably using i2cdetect. If it does not work then use one of the two options below. I am assuming that these options are only a temporary measure and that a future release of the firmware will have addressed the problem. In particular it needs some Linux guru to implement a kernel version of option 2 and update option 1 so that the Broadcom registers can be accessed by ioctl.

See also the individual products in the product section as there may be more information there. This text has been written for Rpi revision 1 there are some changes to the GPIO on revision 2 so check which revision you have when consulting the hardware diagrams.

Not smBUS

You may also want to look into using an alternative to smBUS as this is designed for a specific chip set and only offers high level access to I2C. I have written 'notsmb' that will give access to I2C with just one Python function. The details are on the pichips website.

Preparation

If you have not used I2C before then follow the instruction on this site. STOP at i2cdetect -y 0 DON'T do this yet.
Now follow the instructions for Option 1

Devices requiring Option1 or 2

  • BV4205 - replaced with P0 range of IC's
  • BV4206 - replaced with P0 range of IC's
  • BV4208 - replaced with P0 range of IC's
  • BV4218 (This has now been replaced with BV4618 that works without any modifications)

Option 1

This option uses a reduced clock frequency to compensate for the lack of clock stretching. The advantage is that all of the normal Linux tools can be used. The disadvantage is that it has not been tested fully and may not work in all circumstances. The steps for using this are:

wget http://www.byvac.com/downloads/Pi/i2c_stretch/bcmdel
sudo ./bcmdel

The above is a one time operation, sudo ./bcmdel will be required for each reset. It will modify the contents of the Broadcom's I2C DEL register. This register has default values in at reset and so this needs modifying at start up.

If you want the source code and some notes download this zip file and unzip to a working directory.

The I2C device will now work with I2C tools. e.g. i2cdetect -y 0
The above will also allow you to use all of the built in tools for example if you have a BV4205 device connected try

i2cget -y 0 0x31 0xa0 w

This will return the firmware version as a 16 bit value.

Clearing the LCD display using a BV4218 would be.

i2cset 0 0x21 1 1

Option 2

This is more complex but provides a 'proper' I2C driver that can take care of slave devices properly. The advantage is that it provides a method of driving the I2C bus according to the standard specifications and so all devices will work with it. The disadvantage is that it requires C to work and is not part of the standard library and so more effort is required to use it. Another problem is that it is written entirely in user space and so the maximum clock frequency is just about 100KHz.

The zip file containing all of the information and instructions on use is downloaded from here.

Update Nov 2012

Thanks to Adrian for this information.

  1. On the revision B RPi 11&13 are GPIO 17 and 27 not 17 and 21 as coded in bcm2835_i2cbb.c
  2. bcm2835.c is missing a free that causes the program to exhaust memory, add to line 686:
 if (pads != MAP_FAILED) {
   munmap((void*)pads, BCM2835_BLOCK_SIZE);
   pads = MAP_FAILED;
 }
 if (padsMem) {
   free(padsMem);
   padsMem = NULL;
 }

Hardware

Option 1 uses the standard I2C interface on the RPi GPIO pins. Option 2 can use any GPIO pins, you specify which pins to use in the software. The voltage can be an issue and there is much noise and nonsense about bus translators and the like. So How do you operate a 5V logic device on a 3.3V logic system using I2C?</br> The thing to remember about I2C is that the bus only drives the voltage to ground, it does not supply any current. The high voltage level (the one we are worried about) is provided by two pull up resistors. Now, what must not happen is that any voltage on any RPi pin should exceed 3.3V so the solution is simple, connect the pull up resistors to the 3.3V supply.

Image3.gif
The diagram show the arrangement for connecting 3.3V I2C to 5V logic. When using the RPi there are already pull up resistors connected to the 3.3V supply so the ones in the diagram are not needed. There is a small issue about driving 5V logic with a 3.3V supply and that is for the 5V logic to be full on (logic 1) it needs to be 2.5V or greater, this is fine for when the supply is a good 3.3V.
When talking about 3.3V logic we are specifying the maxim voltage, the nominal voltage is around 2.8V and so the power supply of 3.3V logic may not actually provide 3.3V and 2.8V is very close to being a logic 0 rather then a logic 1 on 5V logic. In practice provided the supply is 3V or above 5V will work just fine, for the likely use that this kind of device is going to get.

Example Code

To see how to use the Pi with I2C there is some example code for this BV4618 device that can be downloaded with wget or simply click on the code to look at it.