Interfacing I2C the easy way

Here is the schematic, the story follows.

Vga to I2C interface

Sidenote: To see if you have a chance to get it to work try this: Connect a monitor to the VGA port you want to use. Then do (Linux, of course): modprobe i2c-dev, and then try i2cdetect {0,1,2,…} basically the number you found with ‘ls /dev/i2c-*’. If you will see that the address 0×50 responds, then disconnect the monitor, and try again (possibly from a remote host, or with a laptop — by disconnecting an external monitor). If 0×50 disappeared, that’s it. If it didn’t, see disclaimer at the end of the post – you might be playing with the wrong bus. You can also try i2cdump -y <busid> 0×50 to see if the device there contains something that relates in any way to your monitor. If you do then you should be able to use this bus to access any kind of I2C device using the schematic above. But remember, you are doing this on your own responsibility, you can kill your cat, burn up your house, and I take no credit for that. Also, the +5V that comes from VGA port is supposed to power the EEPROM kind of device, so if you pull more than say 20mA from it – you’re on your own.

The story: I was looking for quick way to read/write an I2C EEPROM using my laptop. One interface that I had was on a motherboard of a server I run. Every modern RAM memory comes with an I2C EEPROM containing it’s capabilities (for more info see Serial presence detect article on Wikipedia) and you can basically solder two wires under the motherboard’s RAM socket to get an I2C interface. This has worked fine for me, but after a memory upgrade, the new memory chip’s EEPROM occupies address 0×50 that I needed for my EEPROM chip. I had to find another I2C bus controller.

At first I soldered a parport-i2c interface (found here: http://distro.ibiblio.org/eloop/6/setup/docs/knldoc/i2c/busses/i2c-parport), which I connected to the aforementioned server’s parallel port. It’s basically a 7405 hex inverter and some resistors. i2cget was not working as intended. On the oscilloscope I could see some miserable attempts to drive the SCL and SDA lines, but the clocks were very inconsistent, and it was eating 100% cpu time in kernel mode. The server was locked out for the few seconds when it was trying to read the EEPROM, and failing, so I dropped it.

In my post on DDC2 interface tests I wrote that it’s basically an I2C interface sitting on a VGA port. Back then, on the server I wasn’t able to get the i2cdetect to detect my monitor’s eeprom, but I decided to try again, this time on the laptop. After doing a modprobe i2c-dev I had /dev/i2c-{0,1,2}. I installed the i2c-tools package, and the i2cdetect showed the 0×50 part all-right. On one of the buses it was my built-in LCD, and on the other the externam monitor’s EEPROM:

root@spartan:~# i2cdump -r 0x60-0x68 -y 0 0x50 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
60: 44 45 4c 4c 20 31 39 30 37                         DELL 1907

I plugged my trusted VGA RGB to TTL board with my own EEPROM chip attached, and I was able to read and write contents to it, for example change the name of the “monitor” (I duplicated the entries for the Dell monitor to it, as described in the article on DDC2) to something else:

root@ludolphine:~# i2cset -y 0 0x50 0x60 0x48
root@ludolphine:~# i2cdump -r 0x60-0x68 -y 0 0x50 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
60: 48 45 4c 4c 20 31 39 30 37                         HELL 1907

Now I should probably warn you about something. If you will get over-anxious and write to address 0×50 on the wrong I2C bus, you risk overwriting your RAM’s SPD timings. This will very likely result in a non-bootable system, so make sure you know what you are doing.