5
\$\begingroup\$

Long version

Like some of you, I do electronics as a hobby and I'm relatively now to this, so I have a few questions regarding the communication between my Odroid XU4 and a nice I2C module from Olimex called MOD-IO. Let me give you some context.

For one of my projects I had a Raspberry Pi 3 connected to the MOD-IO as in the picture below:

Raspberry Pi 3 connected to MOD-IO

To detect the address I just used i2c-tools library i2cdetect -y 1 and would get:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

Recently I had acquired an Odroid XU4 to replace the Raspberry Pi 3 since more processing power was needed for my project. Since the logic of the Odroid is at 1.8V (as opposed to 3.3V for the Raspberry Pi) and MOD-IO is 3.3V I thought that a level shifter should do the trick. The connections are as in the picture:

Odriod XU4 connected to MOD-IO using a level shifter

I found that Odroid i2c_1 is mapped to i2c-4 in the software. Also confirmed this by running i2cdetect -y 4 while probing with an oscilloscope (I'm noob here, just saw that only on i2c-4 I get a reading on the oscilloscope on both SDA and SCL).

However when I run i2cdetect -y 4 I get mixed results in the console:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- 07 -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- 36 -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- 4b 4c -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

either random readings or none at all.

DEBUGGING or what I tried.

  1. Completely removed MOD-IO and used the oscilloscope for reference. When I run detect directly on the Odroid pins (SDA or SCL) I get a reading on the scope. Also when I run detect after the level shifter there is a reading on the scope. From here I deduced that the Shifter is OK.

  2. Secondly I connected another device that uses 3.3V and worked on the Raspberry Pi - a BMP180 sensor. This is connected similarly to the MOD-IO. When detect runs I get 0x77 as the address. I can even get a reading for the pressure. So I guess there is nothing terribly wrong with the shifter idea.

  3. I read on the Rpi forum that the Raspberry Pi has an internal pull-up resistor of 1.8k, but I could not find anything about Odroid I2C pull-up. I tried adding a pull-up resistor on the 3.3V side of the level shifter to 3.3V VCC and by using this TI document about I2C Bus Pull-up Resistor Calculation as a reference (E.g. 4) I chose 1k as the value, but to no avail.

Short version

I'm trying to connect an Olimex MOD-IO (3.3V logic) to an Odroid XU4 (1.8V logic) by I2C bus, via a bidirectional level converter and I can't get it to work.

Does anyone have any idea what I'm doing wrong? Can you point me in the right direction?

Edit 1:

First of all thank you guys fro all your input. Today I made what I think is a step forward.

Context: Tried adding various pull-ups to both the 1.8v line and the 3.3v one.

First setup 1k on the 1.8v (SDA & SCL) and 4k7 on the 3.3v. This is when I got my first reading of the I2C address. Got a reading for address 0x40 but when I tried a second reading I was back to square one.

So after resetting the MOD-IO I get one reading and the same random addressed on the second one. So I connected the oscilloscope and went on debugging.

What I tried further was changing the 1.8v resistors with a bigger 2k2 one, but this yielded no change in the result. Changing the 3.3v pull-ups to 2k2 made it even worse, so I stopped going down with the pull-ups. I tried changing the 3.3v with a 10k but the result changed little to none.

So the final version of the setup is now with a 2k2 on the 1.8v line (SDA & SCL) and a 10k on the 3.3v one (SDA & SCL).

Then I started taking pictures of the oscilloscope as I did i2cdetect(not an easy job :D).

First was the 1.8v line. This I did directly before the level shifter with the MOD-IO disconnected since I could not get any reading with both the oscilloscope and the MOD-IO. Here is what I got: imgur

Second was the 3.3v line. This was done with the MOD-IO connected. On the first detect I got the right address but on the second the process failed again with random addresses. imgur

What I noticed strange here is the noise on the SCL 3.3v and the SDA 3.3v going low on/after the second detect and remained that way until the MOD-IO is reset(doesn't work always, sometimes I need to reset it a few times for the detect to show the correct address).

Also note that the picture were taken sequential since the oscilloscope one has one channel.

So what do you guys think I should do next?

Edit 2:

So, having no success in borrowing a good scope I decided to save some cash and buy a decent scope. The delivery took some time so here are some images of what I managed to get (I'm still now to the scope thing so be gentle :D).

As a mention I kept the same setup with a pull-up of 2k2 on 1.8V and a 10k on 3.3v.

So what do I do next? What do you guys make of this?

\$\endgroup\$
  • \$\begingroup\$ Is your level shifter bi-directional? Also, I2C protocol assumes pull-ups on both SDA and SCK \$\endgroup\$ – Nazar Jan 2 '17 at 16:25
  • \$\begingroup\$ Yes, the shifter is bidirectional, at least according to the manufacturer's ebay. I tried adding 1k pull-up and had no success. \$\endgroup\$ – Vlad Iliescu Jan 2 '17 at 16:39
  • \$\begingroup\$ @VladIliescu - (a) From your debugging point "2", I guess you were using the level converter for that test. Is that correct? (b) If I had your equipment in my lab, I would be looking at the 'scope traces of the I2C bus, when you are using that I2C level converter - checking the voltage levels and rise/fall times, on both "sides" of the level converter. You have supplied lots of information in your question (great first question - I've already +1). One of the few things missing, are some 'scope traces. Can your 'scope save the waveforms as images? If not, can you take photos of its display? \$\endgroup\$ – SamGibson Jan 2 '17 at 18:29
  • \$\begingroup\$ @SamGibson thank you very much for your effort. Regarding your questions: a) yes, the only thing changed is BMP180 instead of MOD-IO. b) I will try tomorrow to get a clear shot at the scope traces however this will prove quite a challenge since my oscilloscope is a rudimentary DYI kit (DSO138). Just been using it to confirm that something is happening until now. But I will surely try. \$\endgroup\$ – Vlad Iliescu Jan 2 '17 at 19:51
  • \$\begingroup\$ @Vlad - Thanks. (a) Compare I2C waveforms on both sides of the converter: Odroid->converter->BMP180 (works) and Odroid->converter->MOD-IO (doesn't work). (b) Re: your point "3", I checked latest Odroid XU4 schematics and I don't see any built-in pull-ups on the h/w 1.8V I2C bus ("I2C#1"). But... (c) The photo of your BMP180 board does show I2C pull-ups. (d) I've run out of space here, but in short, I suspect lack of pull-ups on the 1.8V ODroid XU4 "side" of the I2C bus, when using your level converter, may be important (check with 'scope). \$\endgroup\$ – SamGibson Jan 2 '17 at 21:28
0
\$\begingroup\$

It seems your level-shifter is not able to work with I2C devices which use clock stretching. Consequently, the device ends up in a state where SCK/SDA are latched to GND.

Clock stretching allows an I2C slave device to suspend communication by holding the clock down to GND while processing data (after the addressing phase). This means that the slave and the master both activate their open collector output at the same time.

In a normal setup, without level-shifter, the master would release the clock and then detect, that the slave still holds the clock down. As soon as the slave releases the clock (which becomes high again), the communication can continue.

With the level-shifter inbetween this logic does not work anymore. When the master holds CLK down, the level shifter has to drive CLK down on the slave side as well. When the slave holds down CLK, then either this information is not forwarded by the level shifter to the master (uni-directional shifter) or the shifter latches the state. This is, because it cannot determine if the master has released the clock, yet.

Not all I2C devices use clock stretching. I suspect that the BMP180 sensor, you are using as a reference, works, because it does not use clock stretching. On the other side, the MOD-IO is based on an ATmega16L, which will (very likely) perform clock stretching until the software has handled the I2C interrupt.

When you look at a proper I2C level shifter like the TCA9800 and P82B96, they use more advanced techniques to resolve the lockup situation.

The P82B96 uses two different ground levels (0V and ~0.6V) to distinguish the current dominant part on the bus.

The TCA9800 measures the direction of the current flow to solve the same issue.

So the answer comes down to: Get a proper I2C level-shifter! (and keep the scope you bought :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.