I2C bus interface

I2C is a bus invented by Philips to allow simple, robust and cost effective communication between integrated circuits. TWI and SMBus are the Atmel and Intel versions of these bus. This article is a practical guide to use the I2C bus with the Acme Systems Linux embedded boards

Kernel setup

Probably the Kernel used on your Acme Board is already configured to have the I2C bus enabled. To check it just type:

# ls /dev/i2c*
/dev/i2c-0  /dev/i2c-1

in this case two busses are already configured on your board. To know on which pins are available the I2C signals, read the pinout section of this page.

However if no device is present you have to check the Kernel drivers setup and the device tree contents.

Kernel setup

To know how to launch the Kernel config and how to compile it follow this tutorial.

Inside the make menuconfig enable the following items:

Device drivers --->
        I2C support  --->
            <*> I2C support
                [*]   Enable compatibility bits for old user-space
                <*>   I2C device interface
                <*>   I2C bus multiplexing support
                        Multiplexer I2C Chip support  --->
                [*]   Autoselect pertinent helper modules
                        I2C Hardware Bus support  --->
                            <*> Atmel AT91 I2C Two-Wire interface (TWI)
                            <*> GPIO-based bitbanging I2C

then compile the Kernel image, save it on the microsd and reboot.

Device tree setup

Once the I2C drivers are loaded into the Kernel the next thing to do is to set the MCU peripheral at Linux startup to be used with this driver.

Follow the pinout section of this page to know how to do it.

Using i2c-tools

The faster way to do the first experiments with this board is by installing and using the i2c-tools.

i2c-tools is a package contains a heterogeneous set of I2C tools for Linux such as:

  • a bus probing tool
  • a chip dumper
  • a register-level access helpers
  • an EEPROM decoding scripts
  • ...and more

To install i2c-tools on the FOX Board just type:

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

Using i2cdetect

i2cdetect is an userspace program to scan an I2C bus for devices. It outputs a table with the list of detected devices on the specified bus.

Example of use:

~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                             
00:          -- -- -- -- -- -- -- -- -- -- -- -- --                             
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
70: -- -- -- -- -- -- -- --                                                     

In this case a device has been detected on address 20 hex.

Using i2cset and i2cset

i2cset is a small helper program to set registers visible through the I2C bus.

The follow simple command writes the byte value 255 to the I2C device at address 20 hex on the i2c bus 0 (/dev/i2c-0).

~# i2cset -y 0 0x20 255

If for example you are using a DAISY-22 module with a PCF8574 I2C I/O expander this command will set all the GPIO lines to 1.

i2cget i2cget is a small helper program to read registers visible through the I2C bus.

The follow simple command read a byte from an I2C device at address 20 hex on the i2c bus 0 (/dev/i2c-0).

~# i2cget -y 0 0x20
0x01

Python code example

python-smbus is a Python module allows SMBus access through the I2C /dev interface on Linux hosts. The host kernel must have I2C support, I2C device interface support, and a bus adapter driver.

Write a register

The following example sends a sequence of values from 0 to 255 to the PCF8574 I2C I/O expander at address 0x20.

Run it by typing:

~# python write.py

Read a register

The following read the GPIO status of a PCF8574 I2C I/O expander at address 0x20. Note that we have to write 1 on the input line we want to read.

Run it by typing:

~# python read.py

C code example

Write a register

The following example sends a sequence of values from 0 to 255 to the PCF8574 I2C I/O expander at address 0x20 in C language.

Compile it by typing:

~# gcc write.c -o write

Then launch it:

~# ./write

Read a register

The following example get the state of the GPIO line from a PCF8574 I2C I/O expander at address 0x20.

Compile it by typing:

~# gcc read.c -o read

Then launch it:

~# ./read

Acqua A5

Up to three hardware I2C bus are available on Aria G25 (pinout page).

Pin # Signal Atmel name Description
J3.42 SDA0 (TWD0) PA30 Data line bus 0
J3.41 SCL0 (TWCK0) PA31 Clock line bus 0
J3.26 SDA1 (TWD1) PC26 Data line bus 1
J3.28 SCL1 (TWCK1) PC27 Clock line bus 1
J3.36 SDA2 (TWD2) PA18 Data line bus 2
J3.35 SCL2 (TWCK2) PA19 Clock line bus 2


No voltage higher than 3.3 Volt can be applied to the I2C lines.

To enable the I2C lines compile the DTS source following the Linux Kernel tutorial available here.

Device tree binding

    i2c0: i2c@f8010000 {
        status ="okay";
    };

    i2c1: i2c@f8014000 {
        status ="okay";
    };
    
    i2c2: i2c@f801c000 {
        status = "okay";
    };
    

Aria G25

Up to two hardware I2C bus are available on Aria G25 (pinout page).

Pin # Signal Atmel name Description
W17 SDA0 (TWD0) PA30 Data line bus 0
W18 SCL0 (TWCK0) PA31 Clock line bus 0
N2 SDA1 (TWD1) PC0 Data line bus 1
N3 SCL1 (TWCK0) PC1 Clock line bus 1


No voltage higher than 3.3 Volt can be applied to the I2C lines.

To enable the I2C lines compile the DTS source following the Linux Kernel tutorial available here.

Device tree binding

    i2c0: i2c@f8010000 {
        status ="okay";
    };

    i2c1: i2c@f8014000 {
        status ="okay";
    };

Arietta G25

Up to two hardware I2C bus are available on Arietta G25 (pinout page).

Pin # Signal Atmel name Description
J4.14 SDA0 (TWD0) PA30 Data line bus 0
J4.12 SCL0 (TWCK0) PA31 Clock line bus 0
J4.39 SDA1 (TWD1) PC0 Data line bus 1
J4.37 SCL1 (TWCK1) PC1 Clock line bus 1


No voltage higher than 3.3 Volt can be applied to the I2C lines.

To enable the I2C lines use the on-line Device Tree Blob generator or compile the DTS source following the Linux Kernel tutorial available here.

Device tree binding

    i2c0: i2c@f8010000 {
        status ="okay";
    };

    i2c1: i2c@f8014000 {
        status ="okay";
    };