Jetson Nano I2C problem with access to the IR camera

Hi all,
I need an advise for the following case with unusual behaviour for I2C buses.

Used HW. Jetson Nano with SparkFun Pi Wedge (40pin breakout board), RPi3 for verification.
Used SW: Ubuntu 18.04 LTS, Melexis library for MLX90640 IR camera.
Test: read from IR camera (MLX90640) control register with address 0x800D. Expected value is default value, 0x1901. IR camera I2C device address 0x33.

Verification test: RPi3 with Pi Wedge and IR camera, test passed, the logic analyzer and scope screenshots for the same I2C transaction is first two parts in image (sorry, I have permission for upload only one image).

IR camera is functional.

Test with Jetson Nano and DS1307 I2C RTC (read register 0x00), passed, I2C bus, wiring is OK.

Test with Jetson Nano, I2C-1 (100kHz bus): test fail, I2C transaction not finished. The logic analyzer and scope screenshot for the same transaction is a 3rd and forth parts on image.

The scope shows a lot of noise on the bus.
This result is identical with different values for the I2C pull up resistors.

Test with Jetson Nano, I2C-0 (400kHz bus): test fail, I2C transaction not finished
The logic analyzer and scope screenshot for the same transaction is last two parts on image.

The code snippet for run this transaction (the same for RPi3 and Jetson Nano):

char buf[1664];
struct i2c_msg i2c_messages[2];
struct i2c_rdwr_ioctl_data i2c_messageset[1];

i2c_messages[0].addr = slaveAddr;
i2c_messages[0].flags = 0;
i2c_messages[0].len = 2;
i2c_messages[0].buf = (I2C_MSG_FMT*)cmd;

i2c_messages[1].addr = slaveAddr;
i2c_messages[1].flags = I2C_M_RD | I2C_M_NOSTART;
i2c_messages[1].len =  2;
i2c_messages[1].buf = (I2C_MSG_FMT*)buf;

i2c_messageset[0].msgs = i2c_messages;
i2c_messageset[0].nmsgs = 2;

   if (ioctl(i2c_fd, I2C_RDWR, &i2c_messageset) < 0) {
    printf("I2C Read Error!\n");
    return -1;
}

Thanks for yours attention!

1 Like

Have a check with i2cget/i2cset get the same result?

Hi, what’s the waveform without device attached? Is the rated voltage level of device is 3.3V?

Hi Shane,
The i2cget/i2cset allow use only one byte register address: i2cget help

The MLX IR camera have address space with two bytes addresses, so it not possible to use i2cget/i2cset for this device.
I try access to a I2C device with one byte registers address (DC1307) - it works with i2cget.

Thanks,
Dmitriy Antonets

Hi Trumany,

Well, the signal quality on the I2C bus was a one of first question. Please, find my notes about that below.
In the very first, I need note that I’m not a EE, just a programmer. So, all my test in this area can be not complete, or even correct. If you will have any other questions/suggestion, please ask me …

  1. I attach the screenshot from the scope for I2C bus without devices, the MLX camera is not powered but all other lines connected. The IR camera itself is 3.3V device, the PCB for camera powered from 5V. The SDA line on the screenshot (C1, yellow) is not goes high (no devices), and, seems, I2C controller even not try send a clock to the bus.

  2. You can find a screenshot from the scope for I2C transaction with use RaspberryPi 3. in my post (I can send it separately). It looks better from the signal quality point view. I use exactly the same MLX camera, Pi Wedge for breakout 40pins cable on the breadboard, and all other wiring for test with Jetson Nano and Raspberry Pi. I attach a picture for my test bench just for illustration that.

  3. I use three different types of logic analyzers: (a) LogicPort from pctestinstruments.com (2) analog discovery 2 from Digilent (it a scope but can works as a LA), (3) Seleae. The first one is chip but works OK with different projects last 5-8 years. But for this project is not works on I2C bus - the bus protocol interpreter can’t decode I2C transaction. It happen first time in my practice. Analog Discovery and Seleae works OK. (you can see that in my post). So, it look alike something not good with signals on the I2C bus.

Thanks,
Dmitriy Antonets

============= Update for this reply ===========
I try the same test with I2C read (I2C-1 bus) on Jetson TX2. It fails exactly the same way.
The post PM_I2C Issue seems can be close to this case: the I2C bus stall, and I2C controller reset it after some time… Just in case …
Thanks,
Dmitriy Antonets

1 Like

Hi, checking the signal quality without device is to confirm no hw issue on nano side, you can send I2C command over the line without device and compare the waveform to that with device powered on. If the signal quality and frequency are good and correct without device, then it might be the matching problem between nano and device.

In general, adding a strong pull-up and decreasing load capacitance are methods to improve signal quality, i.e. to add a 1k pull-up on carrier board, to use a shorter cable to connect nano with device and to remove the components which possible have much capacitance.

Hi, Yes, the pull up 1K make signals clear but the result is the same - I2C read still fails.
I attach screenshots for LA and scope for I2C-0 with 1K pull up.


So, problem is not with a I2C HW.
Thanks.

So the value read from logic analyzer is correct, right? If so, it is not hw problem then.

No, Trumany. The I2C transaction still not done, and it no read from the device at all. The screenshot with “full” transaction (but for RPi3) showed in my post. And I expect something like that for Nano and TX2.

I mean this is the output waveform from TX2, right? It is what you want to send out even though not get answer from device, right? If so, can you try capturing waveform without device attached? That can show if the output signal quality is good or not. If the signal quality is good, it means the problem might be the load capacitance or other things of device.

Hmm, the waveform for the I2C bus without devices is not good as with a device. But looks for me, the signal is acceptable :

Is it a proof that problem (I2C transactions not finished) not with a signal quality but with something else?

This waveform without device is bad, I don’t know why. Never meet such problem on devkit without device attached. Can you show a picture of the entire test environment setting?

  1. You right, I remove my mess and hook probes to the I2C pins:


    The result on scope is better:

  2. Use the I2C FRAM part (adafru.it/1895) instead IR camera for testing. It have the 16bit address space as IR camera:


    Try i2cdetect, device is here, on the scope can see:

It looks the same, as without a device.

Run test - it fails exactly as with camera, on scope:

At the end of write phase of I2C read: SDA line high, but SCL line is low and stay low a long time, and I2C transaction not finished, that is a problem.

  1. Use pins on J21: 37 (gpio388) as SDA, and 31 (gpio298) as SCL. Port functions (almost all) from the kernel driver drivers/i2c/algos/i2c-algo-bit.c to the user space test application. It a bitbang I2C. Start this test app with I2C FRAM, it works OK:

I got from FRAM (all F’s, FRAM is empty) what expected but it slow, of course, and useless for a real work.
It mean, IMHO, the problem with I2C kernel driver.

Yes, it looks like a sw problem, the hw signal is good enough.

Any kernel error message?

Yes, I got this problem for Xavier as well (kernel 4.9.140-tegra, build at 04/08/2020):

It in the last line for dmesg output.

I find the source for this problem for Xavier kernel (4.9.140) - it seems the I2C driver from the public sources ( drivers/i2c/buses/i2c-tegra.c, function tegra_i2c_calc_end_bit() ) not correctly handle flag I2C_M_NOSTART. I change sources for the MLX IR camera for adjust this uncorrect handling, and the I2C transactions seems works OK.

hi dmitriy.antonets.
can you tell me what version of sdk did you tried. and how did you change source for mlx ir camera?

Hi Nguen,
To be honest - I don’t remember. However, it was one of the first versions of SDK. As you can see from the texts above, this problem was due to the fact that the I2C driver did not handle the flag I2C_M_NOSTART correctly. I had to make changes in the software for the IR camera on user space side for work around. And I’m not sure if this is fixed in later versions for kernel. The thing is that I updated the SDK regularly but the problem didn’t appear anymore although I expected it to appear again when the driver is fixed by the NVIDIA developers.

Sorry, I forgot answer for yours second question. So, the fix is easy - do not use flag I2C_M_NOSTART in the I2C transactions to/from MLX IR camera. It not correct (!) but driver works not correct.

// 06/10/2020 Workaround for I2C driver problem for kernel 4.9.140-tegra
i2c_messages[1].flags = I2C_M_RD /*| I2C_M_NOSTART */;

Thanks,
Dmitriy Antonets