Monday 1 July 2013

Using i2c-tools with Angstrom Linux on the BeagleBone Black

Today I'm going to take a slight detour from my usual Minix posts and post about Linux. I was doing some debugging of my Minix i2c driver and wanted to make sure that my hardware setup was good because I wasn't able to access an EEPROM on the 3rd i2c bus from Minix. I booted into Angstrom Linux to see if the third bus was working at all.

Finding what Linux calls the 3rd i2c bus is a bit of a pain because they are numbered in the order that they are initialized in, and one of the buses is disabled by default. To really know for sure you have to check sysfs. That will give you the memory address of the device on the SoC which you can use to determine the hardware bus number. Here's an example:

root@beaglebone:~# ls -l /sys/bus/i2c/devices/i2c-1
lrwxrwxrwx 1 root root 0 Jan  1 00:00 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/ocp.2/4819c000.i2c/i2c-1


Then I ran i2cdetect from i2c-tools to discover devices on the bus. You need the '-r' option because the am335x doesn't support something called quick writes (0 byte writes). The '-y' option is to acknowledge that you know it could hang or otherwise mess up your i2c bus. Finally, the '1' is the number of the bus according to Linux which we found above. As you can see, my device with slave address 0x50 was detected. The 'UU' means busy. The addresses marked busy were probably reserved by a driver as the cape EEPROMs have address 0x54-0x57.

root@beaglebone:~# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --   
          
           

Finally, I wanted to look at the data I had previously written. Both to verify that it was there after the chip was powered off and to verify that bus 3 and my circuit were functional. I did this with the i2cdump command. This too needs a '-y' argument to let it know that you know what you're doing. The '1' is the bus number, the 0x50 is the slave address, and the 'c' is the mode (consecutive byte). As you can see, the characters I wrote previously are still there and the i2c bus is functional.

root@beaglebone:~# i2cdump -y 1 0x50 c
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 6d 69 6e 69 78 33 ff ff ff ff ff ff ff ff ff ff    minix3..........
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................


I found it a bit confusing when I first needed to use these tools, so I hope this post helps someone else debug their i2c issues.

11 comments:

  1. This indeed saved me a ton of time my I started working on the I2C libraries for Userspace-Arduino.

    ReplyDelete
  2. Hello...for my BBB...I connected some slave ICs and when i executed 'i2cdetect -y -r 1'..it is not detecting anything.......Y is it happpening..???

    ReplyDelete
    Replies
    1. There are a lot of reasons why it might not be working. The first step in troubleshooting is to eliminate a hardware problem. Use known working chips, and check the datasheet to make sure they support 3.3V and support the bus speeds used on the BBB. Double check the wiring to ensure everything is connected correctly. Use a multi-meter to check the voltages. Use an oscilloscope to view the output of the SCL pin when you run i2cdetect. If everything looks good, move on to software. Check that the chip is supported in Linux, and check that a driver for the chip hasn't already been started.

      It should also be noted that not all chips respond to probes from i2cdetect, especially on the BBB where the i2c controller doesn't support quick writes (0 byte writes). If you are wiring in a chip, you should already know the slave address (and hence shouldn't need i2cdetect), just try using the chip.

      Delete
  3. I connected slave ICs by putting pull up resistance of 5.5K ohm and a voltage of 3.3v(from PIN 3 and 4 of BBB)....But not detecting anything....

    ReplyDelete
  4. Thomas Cort ...Thank you very much for replying.....When i checked with the Oscilloscope, the SCL (pin 19) is giving clk with i2cdetect....and it is now working fine with the slave(address 0x20)......But with the same slave and circuit(everything)..it is not working for PIN 17(I2C1_SCL) .....it is not providing clock in oscilloscope....even without connecting slave also it is not providing clock......should we do something in kernel to get this......

    ReplyDelete
  5. like I2C2( PIN 20 and PIN 19 of P9 ), I2C1 (PIN 17 and 18) also will be enabled by default...right...??

    ReplyDelete
    Replies
    1. Nope. i2c1 is not enabled by default on most distros.

      Delete
    2. I've never done it, but here are a couple of links from a Google search I did:
      http://wind.cs.purdue.edu/doc/beaglebone_ubuntu.html#sec4
      https://groups.google.com/d/msg/beagleboard/qURjsQkzb1Q/j4iZ3fj38pEJ

      Delete
  6. Thomas, Thank you for your article. I have been working with a melexis IR I2C sensor that I think has multiple slave addresses. I used to have it connect to an Rpi, but later found it would not work with that boadr and switched to the bbb. the pi showed a response from addresses 0x50-0x57 and 0x60 and 0x61. I think I can read data from the sensors slave address 0x50, but the bbb stops at 0x53, and i2cdetect doesnt "see" anything on 0x60, even though I am fairly certain it is there according to the data sheet. is there a way in linux to force a slave address to come to life, somewhere in the driver file or kernel?

    ReplyDelete
  7. Thanks for the intro, Tom. I'm here to report that I followed the tutorial above, and like other users before me, cannot detect the EEPROM at 0x50.

    I'm using the exact same chip present on the BBB Rev B ( CAT24C256WI ) Tried with 2 different chips, triple checked wiring, datasheet & voltages. Probed SCL & SDA with oscilloscope: i2cdetect indeed sends out all combinations of START condition followed by all 7-bit addresses possible on the bus and then a READ (1) after each address. However, an ACK is never sent back by the EEPROM on 0x50. Also tried other addresses without success.

    If anyone here wants to work on this, you can contact me at your leisure. I'm sure we'll figure it out eventually.

    ReplyDelete