Category:How to - i2c

From Gumstix User Wiki
Revision as of 06:07, 4 February 2010 by Sellis (Talk | contribs) (Not supposed to include linux/i2c.h in userspace progs, I2C_SLAVE is also in linux/i2c-dev.h)

Jump to: navigation, search

Background

I2c is a 2-wire serial 8 bit communications protocol from the old days. It is mainly used to communicate between on-board components when the design does not allow for a data and address bus. Typical components are elapsed timer chips, ee-proms, FRAM's, A/D and D/A chips. Some cpu's have the I2c hardware shift registers built in.

The 2 wires are the SCL or clock wire and the SDL or data wire. The clock high to low transition is used to signal that the data wire has a stable 1/0 data value and that the receiver should shift this into the data results register. The clock line is high when the bus is idle. A special high to low transition on the clock line followed by a high to low transition on the data line signals the start of a message sequence. the end of a message sequence is a low to high transition in the data line followed by a low to high transition in the SCL line. An important aspect of this communication standard is that each device is assigned a unique 7 bit address, (oh yea the 8th bit is the Read/write indicator to complete the byte). The device address is the first byte sent in any communication. Subsequent bytes of a message depend on the device you are talking to.

Because of patents that have since expired, other companies had to use slightly different ways to do the same thing so a very similar serial communications method called SPI uses 4 wires and another called TWI uses the same 2 wires.

I2C with Gumstix Overo

There are several i2c buses available on the overo board.

The bus accessible from most of the 40 pin expansion board headers is i2c-3.

Refer to the board schematics to find whether the board you are using exposes the i2c lines.

You are looking for GPIO184_SCL3 and GPIO185_SDA3.

For many of the boards, pin 23 is SCL and pin 24 is SDA.

The voltage levels are 1.8v, so a voltage level shifter is required to connect to 3.3 or 5 volt slave devices. A good explanation can be found here.

The overo main board already has pullup resistors for SCL and SDA.

The default gumstix kernels set the i2c-3 bus speed to 400 kHz.

This can be changed to 100 kHz with a kernel command line parameter in u-boot.

i2c_bus=3,100

The i2c-3 bus appears as a character device under /dev

root@overo:/dev# ls -all i2c*
crw-rw---- 1 root root 89, 1 Jan  1  2000 i2c-1
crw-rw---- 1 root root 89, 3 Jan  1  2000 i2c-3

Programmers can access devices on the bus using standard unix file i/o.

You must set the slave address with an ioctl() call prior to communicating with a slave device.

The driver takes care of shifting the slave address one bit and appending the R/W bit in the first byte of the transfer.

Here's a C example minus any error checking.

...
#include <stdint.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c-dev.h> /* for I2C_SLAVE */
  ...

int fh;
uint8_t data[4];

fh = open("/dev/i2c-3", O_RDWR);

/* tell the driver we want the device at address 0x20 */
ioctl(fh, I2C_SLAVE, 0x20);

/* write two bytes */
data[0] = 0x05;
data[1] = 0x08;
write(fh, data, 2);

/* read 4 bytes */
read(fh, data, 4);

close(fh);

Further information

Another source of I2C information can be found here.

Sample code

Here is a small project showing how to write Overo I2C userland code to communicate with an I/O expander as the slave device. It includes a schematic for the voltage level conversion of the I2C lines that's required.

overo-mcp23017

Pages in category "How to - i2c"

This category contains only the following page.