I2c issue (timeout + error messages)

Hi,
I drove a lot of I2C tests and having issues between Jetson nano and STM32 blackpill as slave
I am using the command ‘i2cdetect -r -y 1’ with pins 3 & 5 (also tried bus 0 with pins 27 28 with exactly the same results)
my I2C lines have 4.7K pull up resistors.

A/ Jetson Nano & Servo controller as slave : detected
B/ STM32 black pill as master & STM32 black pill as slave: detected
C/ Jetson Nano & ESP32 as slave : detected
D/ ESP 32 as master & STM32 as slave : detected
E/ ESP 32 or STM32 black pill as master & servo controller : detected
F/ Jetson Nano & STM32 black pill as slave : not detected + freeze issue + errors:

[ 1814.353314] tegra-i2c 7000c400.i2c: pio timed out addr: 0x4 tlen:12 rlen:4
[ 1814.361039] tegra-i2c 7000c400.i2c: — register dump for debugging ----
[ 1814.369008] tegra-i2c 7000c400.i2c: I2C_CNFG - 0x22c00
[ 1814.374261] tegra-i2c 7000c400.i2c: I2C_PACKET_TRANSFER_STATUS - 0x10001
[ 1814.381029] tegra-i2c 7000c400.i2c: I2C_FIFO_CONTROL - 0xe0
[ 1814.387048] tegra-i2c 7000c400.i2c: I2C_FIFO_STATUS - 0x800080
[ 1814.392970] tegra-i2c 7000c400.i2c: I2C_INT_MASK - 0x7d
[ 1814.398288] tegra-i2c 7000c400.i2c: I2C_INT_STATUS - 0x2
[ 1814.403643] tegra-i2c 7000c400.i2c: i2c transfer timed out addr: 0x4

I also tried 2 different black pill clones & for each model 2 units.

Any help is welcomed.

Here are the Arduino programs used as slave and master:

Slave:

#include <Wire.h>

#define SLAVE_ADR 0x4

void receiveEvent (int) ;

void setup() {
  Serial.begin(9600) ;
  Wire.begin(SLAVE_ADR) ;
  Wire.onReceive(receiveEvent) ;
}

void loop() {
}

void receiveEvent (int howMany) {
  (void)howMany;
  while (Wire.available()){
    Serial.println((char)Wire.read());
  }
}


Master:
#include <Wire.h> //include Wire.h library

void setup()
{
Wire.begin(); // Wire communication begin
Serial.begin(9600); // The baudrate of Serial monitor is set in 9600
while (!Serial); // Waiting for Serial Monitor
Serial.println("\nI2C Scanner");
}

void loop()
{
byte error, address; //variable for error and I2C address
int nDevices;

Serial.println("Scanning...");

nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();

if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
}
else if (error == 4)
{
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");

delay(5000); // wait 5 seconds for the next I2C scan
}

Does i2cdetest can detect it?
How about the i2cget/i2cset for read/write?

Hi Shane, many thanks for your answer,
i2cdetect can not detect it. The error message I have come from ‘dmesg’ command actually is after a i2cdetect command. the Jetson Nano start to scan the devices, but as it comes to the ID 004 (the slave ID I set to my board) it becomes really slow and it looks like frozen, with timeout error found in dmesg command. If I remove the slave board it works normally (but of course my slave board is not detected).

Hi, better to check the I2C signals to make sure the output is correct.

So here are my results:
D0 is SDA
D2 is SCL

First graphic is about Jetson Nano and a servo controller as slave and launch the i2cdetect command

Second graphic is when I add the STM32 board as slave and launch the i2cdetect command:

as you can see the SCL signal becomes low and stay low

Well… I found that disabling the stretching clock mode on slave make the i2cdetect command working.
Is Jetson Nano support Stretching clock?

In HS mode, only byte level clock stretching is allowed, not bit level. The reason is, in HS mode, I2C Master devices enable the current-source pull-up circuit to speed up signals rise time. During this time, no clock stretching is allowed. This current-source pull-up circuit will be disabled only after Ack bit to allow other devices to delay the serial transfer by stretching the LOW period of the SCL signal. That means, clock stretching is allowed only during the period between Ack bit (after 9th bit of current) and 1st bit of next byte transfer.

When this could happen:

  1. When RX-FIFO is full and SW is not reading the data from the FIFO, Slave controller stretches the SCL line low period until it finds free room in the RX-FIFO
  2. When I2C controllers clocks run at less than 130MHz frequency

I2C controllers support clock stretching. However, we have added a timeout logic in our Tegra driver to avoid the system hang if the transaction fails. The timeout logic in the release code is as follows.
File - $TOP/kernel/kernel-4.9/drivers/i2c/busses/i2c-tegra.c

static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, u8 *buffer,
                u32 tx_len, u32 rx_len)
{
...
        if ((tx_len > I2C_PIO_MODE_MAX_LEN || rx_len > I2C_PIO_MODE_MAX_LEN) &&
                        i2c_dev->tx_dma_chan && i2c_dev->rx_dma_chan) {
                if (i2c_dev->curr_direction & DATA_DMA_DIR_TX) {
                        time_left = wait_for_completion_timeout(
                                        &i2c_dev->tx_dma_complete,
                                        TEGRA_I2C_TIMEOUT);
...
}

The above example is for DMA transfer from master to slave but the same API has the other wait_for_completion calls for DMA receive from slave to master and PIO mode.
The TEGRA_I2C_TIMEOUT is a compile-time macro. This can be tuned to get the desired response. The default value supported is 10s or 10000ms.
In the case of a timeout scenario, the i2c controller is reinitialized to bring the i2c lanes and the controller to a sane state.

Please let me know if the customer wants more details.