Aria technical documentation

How to use the I2C ports on Aria SOM

This article illustrates how to use the I2C on Aria SOM

Pinout of I2C ports

This is the list of I2C ports implemented in hardware way. In bitbanging mode any GPIO can be used.

Signal Dir Description Aria pins MPU lines
TWD0 I/O Serial data W17 PA30
TWCK0 O Clock W18 PA31
TWD1 I/O Serial data N2 PC0
TWCK1 O Clock N3 PC1

Linux Kernel drivers

Check if your Kernel has the I2C drivers already active by typing:

ls /dev/i2c*

if the files do not exist or if there are not the device you need, follow this tutorial:

to know how to cross compile the Linux Kernel and how to configure the drivers using the device tree to enable the lines you need.

Using the make ARCH=arm menuconfig comand 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 configure the device tree (arch/arm/boot/dts/acme-aria.dts) with this definition inside the section ahb and apb:

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

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

Copy the zImage and acme-aria.dtb file inside the first microSD partition, boot and check if any /dev/i2c exists.

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

Using I2C from user space

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.

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.

This example will be available as soon as possible

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.

import smbus

I2C_ADDRESS = 0x20 

bus = smbus.SMBus(0)

#Set all ports in input mode
bus.write_byte(I2C_ADDRESS,0xFF)

#Read all the unput lines
value=bus.read_byte(I2C_ADDRESS)
print "%02X" % value

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.

#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>

#define I2C_ADDR 0x20

int main (void) {
    int value;
    int fd;

    fd = open("/dev/i2c-0", O_RDWR);

    if (fd < 0) {
        printf("Error opening file: %s\n", strerror(errno));
        return 1;
    }

    if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0) {
        printf("ioctl error: %s\n", strerror(errno));
        return 1;
    }

    for (value=0; value<=255; value++) {
        if (write(fd, &value, 1) != 1) {
            printf("Error writing file: %s\n", strerror(errno));
        }
        usleep(100000);
    }
    return 0;
}

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.

#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>

#define I2C_ADDR 0x20

int main (void) {
    char buffer[1];
    int fd;

    fd = open("/dev/i2c-0", O_RDWR);

    if (fd < 0) {
        printf("Error opening file: %s\n", strerror(errno));
        return 1;
    }

    if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0) {
        printf("ioctl error: %s\n", strerror(errno));
        return 1;
    }

    buffer[0]=0xFF;
    write(fd, buffer, 1);

    read(fd, buffer, 1);
    printf("0x%02X\n", buffer[0]);
    return 0;
}

Compile it by typing:

gcc read.c -o read

Then launch it:

./read

Links

Sergio Tanzilli
System designer, webmaster and Acme Systems co-founder

Personal email: tanzilli@acmesystems.it
Webpage: https://www.acmesystems.it
Github repositories: https://github.com/tanzilli and https://github.com/acmesystems
Telegram group dedicated to the Acme Systems boards: https://t.me/acmesystemssrl

Aria technical documentation