Difference between revisions of "I2C"

From ArmadeusWiki
Jump to: navigation, search
(Linux user space C code)
m (On OPOS6UL)
 
(27 intermediate revisions by 5 users not shown)
Line 3: Line 3:
 
==Overview==
 
==Overview==
 
The I2C bus is a simple & widely used two wires synchronous bus. It has been developped by [http://www.nxp.com Philips (now NXP)].<br>
 
The I2C bus is a simple & widely used two wires synchronous bus. It has been developped by [http://www.nxp.com Philips (now NXP)].<br>
The standard frequency is 100kHz but 400kHz devices can be found (for example the i.MX).
+
The standard frequency is 100kHz but 400kHz devices can be found (for example on the i.MX).
 
Single and multi masters are supported. Only the single master configuration will be discussed here.
 
Single and multi masters are supported. Only the single master configuration will be discussed here.
  
Line 14: Line 14:
 
==Linux configuration==
 
==Linux configuration==
 
By default the I2C bus is activated in the Armadeus distrib.
 
By default the I2C bus is activated in the Armadeus distrib.
If you need to deactivate it, take a look at the linux menuconfig (make linux-menuconfig)
+
If you need to deactivate it, take a look at the linux menuconfig:
 +
<pre class="host">
 +
$ make linux-menuconfig
 +
</pre>
  
 
==Linux user space C code==
 
==Linux user space C code==
Line 22: Line 25:
 
You can find a sample code under ''target/packages/ch7024ctrl/'' of the Armadeus distribution ( [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/packages/ch7024ctrl/ or here through SF's SVN browsing] )
 
You can find a sample code under ''target/packages/ch7024ctrl/'' of the Armadeus distribution ( [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/packages/ch7024ctrl/ or here through SF's SVN browsing] )
  
==Tested I2C chips==
+
== On OPOS6UL ==
 +
 
 +
By default, OPOS6UL kernel and rootfs are compiled with [https://github.com/groeck/lm-sensors lm-sensors] tools. There are 2 i2c busses on the opos6ul numeroted 1 and 2 on schematics and 0,1 under Linux. The i2c busses can be listed with command i2cdetect:
 +
<pre class="apf">
 +
# i2cdetect -l
 +
i2c-1 i2c      21a4000.i2c                    I2C adapter
 +
i2c-0 i2c      21a0000.i2c                    I2C adapter
 +
</pre>
 +
 
 +
The second bus (I2C2) is available on the [[OPOS6ULDev#Connectors | RaspberryPi connector]].
 +
 
 +
=== Detect ===
 +
 
 +
To see devices connected on one of the i2c master, use the command i2cdetect with the bus number:
 +
<pre class="apf">
 +
# i2cdetect -y 1
 +
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 +
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
 +
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 +
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 +
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 +
40: 40 -- 42 43 -- -- -- -- -- -- -- -- -- -- -- --
 +
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 +
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 +
70: -- -- -- -- -- -- -- -- 
 +
</pre>
 +
{{Note| On some x86 computer, the DDR timing is configured through a little i2c device, if wrong values are written in this component it can brick the computer. It's the reason why i2cdetect add a big warning when we try to detect device on a i2c bus :<pre class="apf"> WARNING! This program can confuse your I2C bus, cause data loss and worse!
 +
I will read from device file /dev/i2c-1, chip address 0x3c, data address
 +
0x00, using read byte data.
 +
Continue? [Y/n] </pre> But it's not a problem on APF/OPOS and we can ignore this warnings with option '-y'}}
 +
In this bus we can see 4 devices in addresses 0x40, 0x42, 0x43 and 0x60.
 +
 
 +
=== Read Write values ===
 +
 
 +
Depending on the device plugged on the bus, it's possible to read/write registers with command i2cget and i2cwrite.
 +
For example, here we have a ioexpander like device plugged at address 0x42.
 +
 
 +
* We can read the switch input with command :
 +
<pre class="apf">
 +
# i2cget -y 1 0x42 1
 +
0x0e
 +
# i2cget -y 1 0x42 1
 +
0x02
 +
</pre>
 +
 
 +
* And we can write the leds output with command :
 +
<pre class="apf">
 +
# i2cset -y 1 0x42 2 0
 +
# i2cset -y 1 0x42 2 0x55
 +
# i2cset -y 1 0x42 2 0xaa
 +
</pre>
 +
 
 +
* It's also possible to dump all registers of a device (be careful) :
 +
<pre class="apf">
 +
# i2cdump -y 1 0x60
 +
No size specified (using byte-data access)
 +
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
 +
00: 00 01 88 64 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f    .??d????????????
 +
10: 10 11 12 13 14 e0 16 17 18 19 1a 1b 1c 1d 1e 1f    ????????????????
 +
20: 20 21 22 23 24 00 26 27 00 29 2a 2b 2c 2d 2e 2f    !"#$.&'.)*+,-./
 +
30: 30 31 32 00 00 35 00 ff 38 39 3a 3b 3c 3d 3e 3f    012..5..89:;<=>?
 +
40: 40 00 00 00 00 00 00 00 00 49 4a 4b 4c 4d 4e 4f    @........IJKLMNO
 +
50: 50 51 00 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f    PQ.STUVWXYZ[\]^_
 +
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f    `abcdefghijklmno
 +
70: 70 71 72 73 30 75 76 77 78 79 7a 7b 7c 7d 7e 7f    pqrs0uvwxyz{|}~?
 +
80: 80 81 82 83 00 00 86 87 88 89 8a 8b 8c 8d 8e 8f    ????..??????????
 +
90: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f    ????????????????
 +
a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af    ????????????????
 +
b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf    ????????????????
 +
c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf    ????????????????
 +
d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df    ????????????????
 +
e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef    ????????????????
 +
f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff    ???????????????.
 +
</pre>
 +
 
 +
== On APF27 ==
 +
 
 +
===Tested I2C chips===
 
* RTC: DS1327
 
* RTC: DS1327
 
* DAC: [[Max5821]]
 
* DAC: [[Max5821]]
* Misc: [[TV_Output | CH7024]]
+
* Video: [[TV_Output | CH7024]] [[DVI_/_HDMI|AD9889 & TFP410]]
 +
* Misc: [[APF51 PMIC|WM8311]]
 
* EEPROM:
 
* EEPROM:
  
==APF9328 I2C bus logic 5v level adaptation (if necessary)==
+
===APF27 I2C chips===
On the APF9328 the I2C bus has a 3,3V logic level so '''if you want to use 5V I2C devices you have to add a level converter''', for example a PCA9306 from NXP:
+
 
 +
List of all hardware devices on APF27 I2C busses
 +
:"I2C" and "I2C2" are the busses names from the iMX27 datasheet
 +
:"I2C-0" and "I2C-1" are the corresponding linux device names
 +
 
 +
* I2C  (I2C-0):
 +
                  none
 +
 
 +
* I2C2 (I2C-1):
 +
                  24AA02 Microchip Technology
 +
                  256X8 EEPROM
 +
                  I2C ADDRESS 0x50 to 0x57 (bits 0-2 are don't care)
 +
 
 +
===APF27_DEV I2C chips===
 +
 
 +
List of all hardware devices on APF27_DEV I2C busses
 +
:"I2C" and "I2C2" are the busses names from the iMX27 datasheet
 +
:"I2C-0" and "I2C-1" are the corresponding linux device names
 +
 
 +
 
 +
* I2C  (I2C-0):
 +
                  DS1374 Dallas Semiconductors
 +
                  32 bits time of day counter (1s increment)
 +
                  I2C ADDRESS 0x68                 
 +
 
 +
                  MAX5821L MAXIM
 +
                  Dual 10bits DAC
 +
                  I2C ADDRESS 0x38                 
 +
 
 +
 
 +
* I2C2 (I2C-1):
 +
                  AD9889 Analog Devices
 +
                  HDMI I/F
 +
                  I2C ADDRESSES
 +
                  * Main ctrl register 0x39
 +
                  * Spare packet memory (31 bytes) 0x38 (default)
 +
                  * EDID memory area (256 bytes) 0x3F (default)
 +
 
 +
===I2C bus logic 5v level adaptation (if necessary)===
 +
if you want to use I2C devices which can not work with the I2C voltage of the APF board, a level translator has to be used, for example a PCA9306 from NXP:
 
* Connect pin 1 to the local GND
 
* Connect pin 1 to the local GND
* Connect pin 2 to the local 3.3V
+
* Connect pin 2 to the local I2C iMX supply voltage
 
* Connect pin 3 to the SCL output of the APF
 
* Connect pin 3 to the SCL output of the APF
 
* Connect pin 4 to the SDA input/ouput of the APF
 
* Connect pin 4 to the SDA input/ouput of the APF
 
* Connect pin 7 and 8 together and the add a 200K resistor in parallel to a 100nF capacitor to GND
 
* Connect pin 7 and 8 together and the add a 200K resistor in parallel to a 100nF capacitor to GND
* Connect a pullup of 1.7K to the 5V SCL line (pin 6)
+
* Connect a pullup of 1.7K between your I2C device supply and the SCL line (pin 6)
* Connect a pullup of 1.7K to the 5V SDA line (pin 5)
+
* Connect a pullup of 1.7K between your I2C device supply and and the SDA line (pin 5)
  
 
For more details, take a look at the [http://www.nxp.com/acrobat_download/datasheets/PCA9306_2.pdf PCA9306 datasheet].
 
For more details, take a look at the [http://www.nxp.com/acrobat_download/datasheets/PCA9306_2.pdf PCA9306 datasheet].
This chip is the one that can be mounted by users on the DevFull board.
+
This chip is the one that can be mounted by users on the APF9328DevFull board.
  
 
As a low-cost alternative, a level shifter can be built with a pair of N-channel mosfets (such as a BS170). See the [http://www.nxp.com/acrobat_download/applicationnotes/AN97055.pdf Application Note 97055].
 
As a low-cost alternative, a level shifter can be built with a pair of N-channel mosfets (such as a BS170). See the [http://www.nxp.com/acrobat_download/applicationnotes/AN97055.pdf Application Note 97055].
Line 47: Line 167:
 
* [http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf I2C specification]
 
* [http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf I2C specification]
 
* [http://www.lm-sensors.org/wiki/man/i2cset I2C Linux test tools of Lm-Sensors]
 
* [http://www.lm-sensors.org/wiki/man/i2cset I2C Linux test tools of Lm-Sensors]
* [http://codesink.org/eeprog.html eeprog, a tool to program I2C EEPROMs]
+
* [http://www.codesink.org/eeprog.html eeprog, a tool to program I2C EEPROMs]
 
* http://www.stlinux.com/docs/manual/distribution/distribution_guide6.php
 
* http://www.stlinux.com/docs/manual/distribution/distribution_guide6.php
 +
 +
[[Category:I2C]]

Latest revision as of 07:55, 26 July 2018

This page will summarize the informations to use the I2C bus on our boards.

Overview

The I2C bus is a simple & widely used two wires synchronous bus. It has been developped by Philips (now NXP).
The standard frequency is 100kHz but 400kHz devices can be found (for example on the i.MX). Single and multi masters are supported. Only the single master configuration will be discussed here.

The bus is based on two signals: SDA and SCL.

  • SDA: bidirectional line for data
  • SCL: unidirectional line for the clock (provided by the master)

Details can be found in the specification here.

Linux configuration

By default the I2C bus is activated in the Armadeus distrib. If you need to deactivate it, take a look at the linux menuconfig:

$ make linux-menuconfig

Linux user space C code

Kernel source has a good documentation on using i2c bus through /dev with C program, it can be found in kernel source directory Documentation/i2c/dev-interface.

You can find a sample code under target/packages/ch7024ctrl/ of the Armadeus distribution ( or here through SF's SVN browsing )

On OPOS6UL

By default, OPOS6UL kernel and rootfs are compiled with lm-sensors tools. There are 2 i2c busses on the opos6ul numeroted 1 and 2 on schematics and 0,1 under Linux. The i2c busses can be listed with command i2cdetect:

# i2cdetect -l
i2c-1	i2c       	21a4000.i2c                     	I2C adapter
i2c-0	i2c       	21a0000.i2c                     	I2C adapter

The second bus (I2C2) is available on the RaspberryPi connector.

Detect

To see devices connected on one of the i2c master, use the command i2cdetect with the bus number:

# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- 42 43 -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --   
Note Note: On some x86 computer, the DDR timing is configured through a little i2c device, if wrong values are written in this component it can brick the computer. It's the reason why i2cdetect add a big warning when we try to detect device on a i2c bus :
 WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-1, chip address 0x3c, data address
0x00, using read byte data.
Continue? [Y/n] 
But it's not a problem on APF/OPOS and we can ignore this warnings with option '-y'

In this bus we can see 4 devices in addresses 0x40, 0x42, 0x43 and 0x60.

Read Write values

Depending on the device plugged on the bus, it's possible to read/write registers with command i2cget and i2cwrite. For example, here we have a ioexpander like device plugged at address 0x42.

  • We can read the switch input with command :
# i2cget -y 1 0x42 1
0x0e
# i2cget -y 1 0x42 1
0x02
  • And we can write the leds output with command :
# i2cset -y 1 0x42 2 0
# i2cset -y 1 0x42 2 0x55
# i2cset -y 1 0x42 2 0xaa
  • It's also possible to dump all registers of a device (be careful) :
# i2cdump -y 1 0x60
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 01 88 64 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f    .??d????????????
10: 10 11 12 13 14 e0 16 17 18 19 1a 1b 1c 1d 1e 1f    ????????????????
20: 20 21 22 23 24 00 26 27 00 29 2a 2b 2c 2d 2e 2f     !"#$.&'.)*+,-./
30: 30 31 32 00 00 35 00 ff 38 39 3a 3b 3c 3d 3e 3f    012..5..89:;<=>?
40: 40 00 00 00 00 00 00 00 00 49 4a 4b 4c 4d 4e 4f    @........IJKLMNO
50: 50 51 00 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f    PQ.STUVWXYZ[\]^_
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f    `abcdefghijklmno
70: 70 71 72 73 30 75 76 77 78 79 7a 7b 7c 7d 7e 7f    pqrs0uvwxyz{|}~?
80: 80 81 82 83 00 00 86 87 88 89 8a 8b 8c 8d 8e 8f    ????..??????????
90: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f    ????????????????
a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af    ????????????????
b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf    ????????????????
c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf    ????????????????
d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df    ????????????????
e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef    ????????????????
f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff    ???????????????.

On APF27

Tested I2C chips

APF27 I2C chips

List of all hardware devices on APF27 I2C busses

"I2C" and "I2C2" are the busses names from the iMX27 datasheet
"I2C-0" and "I2C-1" are the corresponding linux device names
  • I2C (I2C-0):
                 none
  • I2C2 (I2C-1):
                 24AA02 Microchip Technology
                 256X8 EEPROM
                 I2C ADDRESS 0x50 to 0x57 (bits 0-2 are don't care)

APF27_DEV I2C chips

List of all hardware devices on APF27_DEV I2C busses

"I2C" and "I2C2" are the busses names from the iMX27 datasheet
"I2C-0" and "I2C-1" are the corresponding linux device names


  • I2C (I2C-0):
                 DS1374 Dallas Semiconductors
                 32 bits time of day counter (1s increment)
                 I2C ADDRESS 0x68                  
                 MAX5821L MAXIM
                 Dual 10bits DAC
                 I2C ADDRESS 0x38                  


  • I2C2 (I2C-1):
                 AD9889 Analog Devices
                 HDMI I/F
                 I2C ADDRESSES
                 * Main ctrl register 0x39
                 * Spare packet memory (31 bytes) 0x38 (default)
                 * EDID memory area (256 bytes) 0x3F (default)

I2C bus logic 5v level adaptation (if necessary)

if you want to use I2C devices which can not work with the I2C voltage of the APF board, a level translator has to be used, for example a PCA9306 from NXP:

  • Connect pin 1 to the local GND
  • Connect pin 2 to the local I2C iMX supply voltage
  • Connect pin 3 to the SCL output of the APF
  • Connect pin 4 to the SDA input/ouput of the APF
  • Connect pin 7 and 8 together and the add a 200K resistor in parallel to a 100nF capacitor to GND
  • Connect a pullup of 1.7K between your I2C device supply and the SCL line (pin 6)
  • Connect a pullup of 1.7K between your I2C device supply and and the SDA line (pin 5)

For more details, take a look at the PCA9306 datasheet. This chip is the one that can be mounted by users on the APF9328DevFull board.

As a low-cost alternative, a level shifter can be built with a pair of N-channel mosfets (such as a BS170). See the Application Note 97055.

Links