I2C0 & 1

The I2C devices available have changed considerably across the various rPi boards. The ‘Available Functionality‘ page has the details. Generally speaking 26pin rPi’s have one (was I2C0 then became I2C1) and the 40pin rPi’s have both I2c0 and I2C1.

Note however that I2C0 is usually (purposefully) mislabeled as ‘EEPROM’ or ‘ID’ on the 40pin boards, e.g. here and here and here. This is because I2C0 is used to detect official foundation hardware (cameras, screens, hats and the like, you will notice I2C0 is also on the DSI & CSI interfaces).

When is it ok to use?

  • rPi A and B rev 1 boards only have I2C0 so they have no choice and must use it.
  • (IMHO) all 40pin boards that have both should only use I2C0 if no official foundation hardware or hats are being used and:
    • You need to run both 3.3v and 5v I2C devices
    • You need to run different speed busses, e.g. 100kHz and 400kHz
    • You have two devices with the same ID and they can’t be reconfigured
    • You need to run more than 125 I2C devices (yeh right)

I any case I’d be very careful about putting eeproms on I2C0 as it gets scanned for eeproms containing hardware information prior to linux booting. Boot issues are not unheard off with I2C0 devices (presumably answering the scan with misleading information).

Add-on board designers are advised not to connect the pins at all unless it is for hat identification via eeprom. Hobbyists can decide what is best for themselves.

The device supports the following linux i2c options:

  • I2C_FUNC_I2C
  • I2C_FUNC_SMBUS_EMUL – this includes a whole raft of stuff:
    • I2C_FUNC_SMBUS_PEC
    • I2C_FUNC_SMBUS_QUICK
    • I2C_FUNC_SMBUS_READ_BYTE
    • I2C_FUNC_SMBUS_WRITE_BYTE
    • I2C_FUNC_SMBUS_READ_BYTE_DATA
    • I2C_FUNC_SMBUS_WRITE_BYTE_DATA
    • I2C_FUNC_SMBUS_READ_WORD_DATA
    • I2C_FUNC_SMBUS_WRITE_WORD_DATA
    • I2C_FUNC_SMBUS_PROC_CALL
    • I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
    • I2C_FUNC_SMBUS_READ_I2C_BLOCK
    • I2C_FUNC_SMBUS_WRITE_I2C_BLOCK

Note that 10bit client address mode isn’t supported although the hardware is capable of it.

I2C0 uses GPIO0-1 and I2C1 uses GPIO2-3

Prerequisite Configuration

/boot/config.txt

Add the following to enable I2C1

dtparam=i2c_arm=on

Add the following to enable I2C0

dtparam=i2c_vc=on

(Note: that you can enable i2c_arm with  rasp-config: option 8) advanced → 3) enable I2C. However note you will still need to enable the i2c-dev kernel module below too)

Kernel Module

Two modules need to load for the I2C devices to work. The i2c_dev module needs to be manually configured to load by adding it into the /etc/modules file like this:

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-dev

Once done reboot and you should find these two i2c modules loaded

$ lsmod | grep i2c
i2c_bcm2708             5014  0 
i2c_dev                 6040  0

Finally check /dev for the device node(s). They should be read/write the i2c group.

$ ls -l /dev/i2c*
crw-rw---- 1 root i2c 89, 0 Jan 25 17:41 /dev/i2c-0
crw-rw---- 1 root i2c 89, 1 Jan 25 17:41 /dev/i2c-1

System Config

Add yourself into the i2c group if you haven’t already done so. Add any other users at the same time

sudo usermod -a -G i2c <acccount>

Issues

Although it is possible to set the i2c clock speed as a kernel option, it doesn’t always work (it gets overridden with some versions of Raspbian) . So it is probably better to do it in the /boot/config.txt like this:

dtparam=i2c_arm_baudrate=400000