cancel
Showing results for 
Search instead for 
Did you mean: 

I2C-2 and I2C-6 bus is busy when accessing from user space.

Led
Senior

I want to use i2c-2 and i2c-6 from the user space to access different external devices. With 'i2cdetect -l' I can see the interfaces, But executing 'i2cdetect 3' sais 'Bus busy'.

Used HW: Phytec Sabre Board (phyBOARD-Sargas)

Linux: Yocto-OpenSTLinux PD20.2.0

Executed command that results in error:

root@phycore-stm32mp1-3:~# i2cdetect -l
i2c-3   i2c             STM32F7 I2C(0x5c009000)                 I2C adapter
i2c-1   i2c             STM32F7 I2C(0x40013000)                 I2C adapter
i2c-2   i2c             STM32F7 I2C(0x5c002000)                 I2C adapter
i2c-0   i2c             STM32F7 I2C(0x40012000)                 I2C adapter
 
root@phycore-stm32mp1-3:~# i2cdetect 3
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-3.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- [  217.031102] stm32f7-i2c 5c009000.i2c: bus busy
[  217.034098] stm32f7-i2c 5c009000.i2c: Trying to recover bus

For /dev/i2c-0 and /dev/i2c-2 the command i2cdetect works as expected. But not for the newly added /dev/i2c-1 and /dev/i2c-3.

Remark: surprising is that the error contains 'stm32f7' on the 'stm32mp' board.

DTS Configuration:

&pinctrl {
      i2c2_pins_a: i2c2-0 {
        pins {
          pinmux = <STM32_PINMUX('F', 0, AF4)>, /* I2C2_SDA */
                  <STM32_PINMUX('F', 1, AF4)>; /* I2C2_SCL */
          bias-disable;
          drive-open-drain;
          slew-rate = <0>;
        };
      };
}
&pinctrl_z {
  i2c6_pins_a: i2c6-0 {
    pins {
      pinmux = <STM32_PINMUX('Z', 0, AF2)>, /* I2C6_SCL */
              <STM32_PINMUX('Z', 1, AF2)>; /* I2C6_SDA */
      bias-disable;
      drive-open-drain;
      slew-rate = <0>;
    };
  };
  i2c6_pins_sleep_a: i2c6-1 {
    pins {
      pinmux = <STM32_PINMUX('Z', 0, ANALOG)>, /* I2C6_SCL */
              <STM32_PINMUX('Z', 1, ANALOG)>; /* I2C6_SDA */
    };
  };
};
 
&i2c2{
      pinctrl-names = "default", "sleep";
      pinctrl-0 = <&i2c2_pins_a>;
      pinctrl-1 = <&i2c2_pins_sleep_a>;
      i2c-scl-rising-time-ns = <185>;
      i2c-scl-falling-time-ns = <20>;
      status = "okay";
      /delete-property/dmas;
      /delete-property/dma-names;
};
&i2c6{
      pinctrl-names = "default", "sleep";
      pinctrl-0 = <&i2c6_pins_a>;
      pinctrl-1 = <&i2c6_pins_sleep_a>;
      i2c-scl-rising-time-ns = <185>;
      i2c-scl-falling-time-ns = <20>;
      status = "okay";
      /delete-property/dmas;
      /delete-property/dma-names;
};

1 ACCEPTED SOLUTION

Accepted Solutions
Danish1
Lead II

You say it is busy from user-space. That suggests that it might not be busy from "superuser" space. Have you done anything that might check this either way?

One thing that I2C lines need is pull-up resistors (2.2 - 4.7 kOhm typical). Are they already present on the board or have you added them yourself?

If you have access to a voltmeter, do these pins measure high, over 2.0 V?

"Trying to recover Bus" could be an I2C "trick" that sends 9 pulses on SCL while allowing SDA to float high before issuing a stop-condition, in order to end communication which might have stopped part-way-through a transfer e.g. due to a reset.

Hope this helps,

Danish

View solution in original post

4 REPLIES 4
Danish1
Lead II

You say it is busy from user-space. That suggests that it might not be busy from "superuser" space. Have you done anything that might check this either way?

One thing that I2C lines need is pull-up resistors (2.2 - 4.7 kOhm typical). Are they already present on the board or have you added them yourself?

If you have access to a voltmeter, do these pins measure high, over 2.0 V?

"Trying to recover Bus" could be an I2C "trick" that sends 9 pulses on SCL while allowing SDA to float high before issuing a stop-condition, in order to end communication which might have stopped part-way-through a transfer e.g. due to a reset.

Hope this helps,

Danish

Led
Senior

Hi Danish,

Thanks a lot for your inputs.

Indeed! It was just a pull-up problem of the resistors due to a HW issue. When I add the pull-ups by hand it does work. For both i2c6 and i2c2. Now I get what is expected.

You made my day!

Led

i2cdetect 3
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-3.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

in this log nothing comes? how much pull up you added and where?how did you come to the value of added pullup?

Tx

Led
Senior

Hi darla14,

In the answer from Danish you see the value for the pull up. This is the value that is mostly used. To design it well you can also evaluate the current flowing and the minimal voltage the processor needs to recognize the signal. With this you can calculate the allowed voltage drop over the resistor.

As you can read in the communication, the question has been answered.