I2C

The Inter-Integrated Circuit (I2C) interface is a two-wire, bidirectional serial bus that provides a simple and efficient method for data exchange among devices. The phyCORE-AM62x SOM provides six independent multimaster fast-mode I2C modules. Aside from I2C0, which has pullups on the SOM, all the I2C signals require pullups in your custom carrier board design. This guide will show you how to test the I2C interface on the phyCORE-AM62x development kit. To learn more information about the phyCORE-AM62x Inter-Integrated Circuit (I2C) interface, please see section 7.3 in the Hardware Manual.

Note

The AM62x processor supports up to 6x I2C interfaces. Only two of these are supported on the phyCORE-AM62x development kit by default but others can be enabled via pin multiplexing.

I2C Settings

Hardware Interface

sysfs Path

I2C0

/dev/i2c-0

I2C1

/dev/i2c-1

Requirements

  • M/M Jumper Wire

    Note

    The expansion header was designed for 2mm pins. It is acceptable to use 2.54mm jumper pins during the development and verification of interfaces. The only issue arises when you switch back to plugging in a 2mm male header for an expansion board you created.

  • I2C device ( Accelerometer )

Using I2C0

  • Power on the development kit and boot into Linux.

  • List the available I2C devices. There will be a few devices that appear in /dev/ and each is a different I2C interface.

Target (Linux)
ls /dev/i2c*
Expected Output
root@phyboard-lyra-am62xx-2:~# ls /dev/i2c*
/dev/i2c-0  /dev/i2c-1  /dev/i2c-2

Note

The Linux Kernel is currently enumerating an extra I2C interfaces available at the hardware level even though only two are setup. Attempting to work with the I2C interfaces other than I2C0 and I2C1, using the default software, will give you errors.

  • List all the I2C busses in the system.

    The i2c-tools package contains a heterogeneous set of I2C tools to interact with I2C slave devices from userspace. BSP images have i2c-tools packaged by default

Target (Linux)
i2cdetect -l
Expected Output
root@phyboard-lyra-am62xx-2:~# i2cdetect -l
i2c-0   i2c             OMAP I2C adapter                        I2C adapter
i2c-1   i2c             OMAP I2C adapter                        I2C adapter
i2c-2   i2c             i2c-1-mux (chan_id 0)                   I2C adapter
  • Use the “i2cdetect” command to scan the I2C0 bus for devices. This command outputs the address of all devices on the I2C0 bus.

Target (Linux)
i2cdetect -y -r 0
Expected Output
root@phyboard-lyra-am62xx-2:~# i2cdetect -y -r 0
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: UU -- UU -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Note

UU indicates that the device with that particular address is tied to a kernel driver and you will be unable to communicate with the device via i2c commands (i2cset and i2cget).

The detected interfaces should match with the devices connected to I2C0 on the development kit.

I2C0 addresses

Interface

Address (7-bit)

PMIC

0x30

EEPROM

0x50

EEPROM identification page

0x58

RTC

0x52

Connecting the Accelerometer

  • Now ‘poweroff’ the development kit and connect up the accelerometer before booting the kit back into Linux.

Target (Linux)
poweroff
I2C0 Device Pins

I2C Device Pin

Carrier Board Signal

Carrier Board Connector - Pin

VCC

VCC_5V0_SW

X17 - Pin 2

GND

GND

X17 - Pin 7

SCL

X_I2C0_SCL

X17 - Pin 41

SDA

X_I2C0_SDA

X17 - Pin 43

phyCORE-AM62x I2C
  • If you run the same i2cdetect command you should be able to confirm that a new device has appeared on the I2C0 bus:

Target (Linux)
i2cdetect -y -r 0
Expected Output
root@phyboard-lyra-am62xx-2:~# i2cdetect -y -r 0
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: UU -- UU -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Since the accelerometer was simply attached to the BUS without any knowledge of it having been provisioned into the Linux device tree the device address comes up as its true address 0x1d as opposed to ‘UU’. This means we can interact with it directly in userspace using the i2cget and i2cset utilities, check out the following userspace driver for bump detection!

Bump Detect Userspace Driver

  • Open a text editor to write a script:

Target (Linux)
cd ~
vi ./bumpDetect.sh

Note

The vi text editor begins in “Command Mode” and you must first hit the ‘i’ key in order to enter “Insert Mode”. Using the arrow keys to navigate, make the necessary changes and then hit ESC to go back to “Command mode”. Now enter “:wq” to write the file and quit.

Pro Tip: Use the right click on your mouse to paste! This will only work if you are in “Insert Mode” first.

  • Enter the following into the text editor and save the file:

bumpDetect.sh
#!/bin/bash

echo Input Sparkfun RedBot-Accelerometer bus:
read -r bus
echo Input Sparkfun RedBot-Accelerometer address:
read -r addy

                                        #This stuff all comes from the MMA8452Q accelerometer datasheet
i2cset -y "$bus" "$addy" 0x2B 0x40      #Reset the accelerometer
i2cset -y "$bus" "$addy" 0x0E 0x02      #Set dynamic range to 8g from default 2g
i2cset -y "$bus" "$addy" 0x2A 0x05      #Enable the device

#Constantly check if there is any change in acceleration in the Z axis
state=$(i2cget -y "$bus" "$addy" 0x05)

while true; do
        temp=$(i2cget -y "$bus" "$addy" 0x05)
        if [ "$state" != "$temp" ];
        then
                echo Bump!
                usleep 200000
                state=$(i2cget -y "$bus" "$addy" 0x05)
        fi
done
  • Change the permissions such that you can execute the script:

Target (Linux)
chmod +x ./bumpDetect.sh
  • Now run the script:

Target (Linux)
./bumpDetect.sh
  • When prompted, enter the bus you connected the device to (which was I2C0) and the address found earlier (the kernel representd this bus as /dev/i2c-0) Both must be given in hexidecimal form!

Target (Linux)
root@phyboard-lyra-am62xx-2:~# ./bumpDetect.sh
Input Sparkfun RedBot-Accelerometer bus:
0x00
Input Sparkfun RedBot-Accelerometer address:
0x1D
  • With the accelerometer resting on the table surface, try tapping the table surface!

    The accelerometer is pretty sensitive so you should be able to tap the table anywhere, and very lightly, to get a bump to register (Note that the example is only polling the Z axis, so tapping the sides of the table will probably not register a bump).

Expected Output
root@phyboard-lyra-am62xx-2:~# ./bumpDetect.sh
Input Sparkfun RedBot-Accelerometer bus:
0x00
Input Sparkfun RedBot-Accelerometer address:
0x1D
Bump!
Bump!
Bump!
Bump!
Bump!