Difference between revisions of "Category:How to - i2c"
(Added a Sample code section and one link) |
m (Remove the Further Information section since the link dest has no content) |
||
(6 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
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. | 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 | + | 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 == | == I2C with Gumstix Overo == | ||
− | There are several i2c | + | There are several i2c buses available on the overo board. |
− | The | + | The bus accessible from most of the 40 pin expansion board headers is i2c-3. |
− | + | Refer to the board [http://pubs.gumstix.com/boards/ schematics] to find whether the board you are using exposes the i2c lines. | |
− | The voltage levels are 1.8v, so a voltage level shifter is required to connect to 3.3 or 5 volt slave devices. | + | 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 [http://www.nxp.com/documents/application_note/AN10441.pdf here.] | ||
The overo main board already has pullup resistors for SCL and SDA. | The overo main board already has pullup resistors for SCL and SDA. | ||
Line 21: | Line 26: | ||
The default gumstix kernels set the i2c-3 bus speed to 400 kHz. | 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 | + | This can be changed to 100 kHz with a kernel command line parameter in u-boot. |
i2c_bus=3,100 | i2c_bus=3,100 | ||
− | |||
− | |||
The i2c-3 bus appears as a character device under /dev | The i2c-3 bus appears as a character device under /dev | ||
Line 46: | Line 49: | ||
#include <sys/stat.h> | #include <sys/stat.h> | ||
#include <fcntl.h> | #include <fcntl.h> | ||
− | #include <linux/i2c.h> /* for I2C_SLAVE */ | + | #include <linux/i2c-dev.h> /* for I2C_SLAVE */ |
− | + | ... | |
− | + | ||
int fh; | int fh; | ||
uint8_t data[4]; | uint8_t data[4]; | ||
− | + | ||
fh = open("/dev/i2c-3", O_RDWR); | fh = open("/dev/i2c-3", O_RDWR); | ||
− | + | ||
− | /* tell the driver we want the device | + | /* tell the driver we want the device with address 0x20 on the I2C bus */ |
ioctl(fh, I2C_SLAVE, 0x20); | ioctl(fh, I2C_SLAVE, 0x20); | ||
− | + | ||
/* write two bytes */ | /* write two bytes */ | ||
data[0] = 0x05; | data[0] = 0x05; | ||
data[1] = 0x08; | data[1] = 0x08; | ||
write(fh, data, 2); | write(fh, data, 2); | ||
− | + | ||
/* read 4 bytes */ | /* read 4 bytes */ | ||
read(fh, data, 4); | read(fh, data, 4); | ||
− | + | ||
close(fh); | close(fh); | ||
− | == | + | ==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. | |
− | + | ||
− | + | ||
− | [http://github.com/scottellis/overo- | + | [http://github.com/scottellis/overo-mcp23017 overo-mcp23017] |
[[Category:How_to_-_general]] | [[Category:How_to_-_general]] |
Latest revision as of 12:52, 12 August 2010
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 with address 0x20 on the I2C bus */ 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);
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.