I2C Bus - Overview

History

  • Inter-Integrated Circuit (I2C) is a low speed serial bus.
  • Developed by Philips for a TV set.
  • It connects peripheral devices to Microcontroller Unit.
  • No. of wires reduced to two (clock and data) for connecting devices.

Features

  • It operates at one of the bus speed,
    • 100kHz - Standard mode.
    • 400kHz - Fast mode.
    • 1 MHz - Fast+ mode.
    • 3.4MHz - High Speed mode.
  • The CPU is the master on the bus, and the peripherals are slaves. Only the master can initiate a transaction.
  • Each slave will have 7-bit address.

Features

figures/i2c-drop.png

Features

figures/master-slave.png
  • Master provides clock and starts transaction.
  • The master can address a peripheral and send data to it, or receive data from it.
  • If 7-bit address is used, maximum of 127 devices can be connected.

Features

figures/soc-cntlr.png
  • SoC’s CPU is memory mapped to I2C controller.
  • Each I2C controller owns a bus.
  • Example: If 2x I2C controller in Soc, 2x I2C Bus.

I2C Protocol

Bus transactions

For accessing the slave registers, master has to

  • Write the register address to be accessed.
  • Then read or write data to the device.

REST transactions

figures/rest.png

I2C transactions

figures/i2c.png

Applications

Communication Interface

  • To interface IO expanders.
  • To interface with ADC and DAC.
  • To interface touch screen.
  • Used in many sound cards in configuration.
  • and so on…

I2C in Target Board

Target

figures/i2c-target.png

The following devices are connected on board,

  • RTC
  • Accelerometer
  • 4-way key.

I2C in Linux

File interface

  • In Linux, I2C Bus can be accessed like a file.
  • It can be accessed using a dev interface, /dev/i2c-<bus no.>.
  • Doing fileio operations on this device file, will be reflected as send and receive transactions in the bus.

i2ctools

  • A set of tools to access I2C in linux.
  • i2cdetect provides the list of device addresses, connected in the bus.

Interpreting i2cdetect output

  • An address number in hexadecimal, e.g. "2d" or "4e". A chip was found at this address.
  • "--". The address was probed but no chip answered.
  • "UU". Probing was skipped, because this address is currently in use by a driver. This strongly suggests that there is a chip at this address.
# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: UU -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Accessing I2C Device

SMBus

  • Normal and register transaction methods.
  • FileIO operations are not sufficient to select and register access I2C devices.
  • For operations more than fileIO, we need to use ioctl.
  • Extra ioctl operations while accessing the i2c devices can be done using SMBus.
  • SMBus provides apis for selecting the I2C slave.

SMBus

  • Opening and reading the device requires the following steps.
import smbus

BUSNO = 0
SLAVE = 0x20 # Slave address depends on the device.
REG = 0x00   # Register address depends on the device.

i2c = smbus.SMBus(BUSNO)
i2c.open(BUSNO)

data = i2c.read_byte_data(SLAVE, REG)

Accelerometer

figures/accelerometer.png

Tilt Sensing Using Accelerometer

figures/structural-accelerometer.png

Demo

4-way Key Functional Diagram

figures/4-way-key-func.png

4-way Key Datasheet

figures/4-way-key-datasheet.png

Try Out

  • Try to access 4-way key.
  • Detect the device is connected in the bus.
  • Read the status register and data register.
  • Use smbus apis to read current key value.