Difference between revisions of "EMAC I²C Programming"

From wiki.emacinc.com
Jump to: navigation, search
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{todo|Complete; (12.4.13-15:35->MD+);(12.26.13-14:05->MW+);(12.26.13-14:50->MG+)|Michael Welling|project=oe 4,oe 5,mw,md,mg,Complete}}
+
{{todo|SEOKWREV; (12.4.13-15:35->MD+);(12.26.13-14:05->MW+);(12.26.13-14:50->MG+);(03.04.14-16:25->BS-);(03.26.14-16:55->BS+);(04.14.14-14:55->BS+)|Michael Welling|project=oe 4,oe 5,mw,md,mg,bs,SEOKWREV}}
 +
 
 +
{{#seo:
 +
|title=EMAC I²C Programming
 +
|titlemode=append
 +
|keywords=I²C Programming,i2c-dev Interface
 +
|description=Programming I²C device.
 +
}}
 
=== Background Information ===
 
=== Background Information ===
 
I²C is a low-speed (400 kHz max.) two wire serial interface used to connect to a variety of sensor and I/O devices. The interface uses two bi-directional open-drain I/Os, SDA and SCL, to communicate to devices based on an address encoded within the data transmission. SDA is a data signal which sends and receives serially transmitted data. SCL is a clock signal which is used to determine when to latch data from the SDA line.
 
I²C is a low-speed (400 kHz max.) two wire serial interface used to connect to a variety of sensor and I/O devices. The interface uses two bi-directional open-drain I/Os, SDA and SCL, to communicate to devices based on an address encoded within the data transmission. SDA is a data signal which sends and receives serially transmitted data. SCL is a clock signal which is used to determine when to latch data from the SDA line.
Line 12: Line 19:
  
 
=== Accessing the i2c-dev Interface ===
 
=== Accessing the i2c-dev Interface ===
When the i2c-dev driver is properly loaded it exposes a device interface for each available I²C interface. Each interface will have an associated character device node at /dev/i2c-X, where X is replaced by a number representing the interface. This device node allows the user to access the I²C interface directly from a C program.
+
When the i2c-dev driver is properly loaded it exposes a device interface for each available I²C interface. Each interface will have an associated character device node at <code>/dev/i2c-X</code>, where X is replaced by a number representing the interface. This device node allows the user to access the I²C interface directly from a C program.
  
To open a I²C device node from a C program, use the standard <code>open</code> command as follows:
+
To open an I²C device node from a C program, use the standard <code>open</code> command as follows:
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
int fd;
 
int fd;
Line 23: Line 30:
  
  
Once the device is open, the I2C_SLAVE ioctl command is used to set the address of the slave I²C device:
+
Once the device is open, the <code>I2C_SLAVE ioctl</code> command is used to set the address of the slave I²C device:
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 +
#include "i2c-dev.h"
 +
    ⋮
 
int ret;
 
int ret;
 
int addr = 0x0e;
 
int addr = 0x0e;

Latest revision as of 13:55, 14 April 2014

TODO: {{#todo:SEOKWREV; (12.4.13-15:35->MD+);(12.26.13-14:05->MW+);(12.26.13-14:50->MG+);(03.04.14-16:25->BS-);(03.26.14-16:55->BS+);(04.14.14-14:55->BS+)|Michael Welling|oe 4,oe 5,mw,md,mg,bs,SEOKWREV}}

Background Information

I²C is a low-speed (400 kHz max.) two wire serial interface used to connect to a variety of sensor and I/O devices. The interface uses two bi-directional open-drain I/Os, SDA and SCL, to communicate to devices based on an address encoded within the data transmission. SDA is a data signal which sends and receives serially transmitted data. SCL is a clock signal which is used to determine when to latch data from the SDA line.

For more information about the protocol see the following page: http://en.wikipedia.org/wiki/I²C

This page specifically covers the usage of the Linux I²C i2c-dev driver.

For more information about the Linux I²C subsystem: https://i2c.wiki.kernel.org/index.php/Main_Page

Accessing the i2c-dev Interface

When the i2c-dev driver is properly loaded it exposes a device interface for each available I²C interface. Each interface will have an associated character device node at /dev/i2c-X, where X is replaced by a number representing the interface. This device node allows the user to access the I²C interface directly from a C program.

To open an I²C device node from a C program, use the standard open command as follows:

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


Once the device is open, the I2C_SLAVE ioctl command is used to set the address of the slave I²C device:

#include "i2c-dev.h"
    
int ret;
int addr = 0x0e;
    
ret = ioctl(fd, I2C_SLAVE, addr);


After the device address is set, the device can be accessed with the standard read and write commands:

int data = 0xaa;
    
ret = write(fd, &data, 1);
    
ret = read(fd, &data, 1);

Below is a functional code listing that puts all of the commands together, showing the required include files and error checking. For a more complete example refer to the I²C demo in the EMAC SDK.

Simple C Code Example

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "i2c-dev.h"

int main(int argc, char * argv[])
{
    int fd;
    int ret;
    int addr = 0x0e;
    int data = 0xaa;

    fd = open("/dev/i2c-0", O_RDWR);
    
    if(fd < 0) {
        fprintf(stderr, "Cannot open i2c device\n");
        exit(-1);
    }

    ret = ioctl(fd, I2C_SLAVE, addr);

    if(ret < 0) {
        fprintf(stderr, "Cannot set slave address\n");
        exit(-1);
    }

    ret = write(fd, &data, 1);

    if(ret != 1)
        fprintf(stderr, "Cannot write i2c device\n");

    ret = read(fd, &data, 1);

    if(ret != 1)
        fprintf(stderr, "Cannot read i2c device\n");
    else
        printf("Byte read from i2c was %x\n", data);

    exit(0);
}