Arduino_core_stm32: i2c problem with release 1.8.0

Created on 10 Jan 2020  路  16Comments  路  Source: stm32duino/Arduino_Core_STM32

I was using Arduino_Core_STM32 release 1.5.0 with MPU9250 library by hideakitai. It was working fine until I upgraded to the latest release of 1.8.0. With 1.8.0, i2c bus was not able to locate the AK8963 device.

I've tested Arduino_Core_STM32 release 1.5.0, 1.6.0, 1.6.1, 1.7.0 & 1.8.0. Only 1.8.0 has problem with the MPU9250 library. All other releases worked fine.

Hardware Configuration:
Blue pill (stm32f103c8) with i2c (PB11, PB10) connected to a MPU9250 link

Sample sketch to reproduce the problem:

#include "MPU9250.h"
MPU9250 mpu;

void setup()
{
    Serial.begin(115200);
    Wire.begin();
    delay(2000);
    mpu.setup();
}

void loop()
{
    static uint32_t prev_ms = millis();
    if ((millis() - prev_ms) > 16)
    {
        mpu.update();

        Serial.print("roll, pitch, yaw: ");
        Serial.print(mpu.getRoll());
        Serial.print("\t");
        Serial.print(mpu.getPitch());
        Serial.print("\t");
        Serial.println(mpu.getYaw());

        prev_ms = millis();
    }
}

Output with AK9963 not found (with rel 1.8.0):

MPU9250 WHO AM I = 71
MPU9250 is online...
AK8963  WHO AM I = 0
Could not connect to AK8963: 0x0
roll, pitch, yaw: 0.00.0.00.-3.00
roll, pitch, yaw: 0.00.0.00.-3.00

Expected output when working (with release 1.5.0 to 1.7.0):

MPU9250 WHO AM I = 71
MPU9250 is online...
AK8963  WHO AM I = 48
Calibration values: 
X-Axis sensitivity adjustment value 1.20
Y-Axis sensitivity adjustment value 1.21
Z-Axis sensitivity adjustment value 1.16
X-Axis sensitivity offset value 0.00
Y-Axis sensitivity offset value 0.00
Z-Axis sensitivity offset value 0.00
roll, pitch, yaw: 170.50.-67.37.-155.35
roll, pitch, yaw: 171.00.-68.81.-155.60
Bug

All 16 comments

Hi @pacman1945,
I am not fully aware of MPU9250, and I don't have this module to test,
but as far as I understand, it is composed of 2 components, one for accelerometer/Gyroscope, and one for magnetometer (AK8963).
From your log it seems that accelerometer MPU9250 is properly responding to I2C command

MPU9250 WHO AM I = 71
MPU9250 is online...

But magnetometer is not
AK8963 WHO AM I = 0

As far as I understand, AK8963 can :

  • either be access directly on I2C bus, bluepill should see 2 I2C devices,
  • or indirectly through MPU9250, bluepill should see only 1 device (pass-through or bypass mode ??).

Which mode are you using?
To confirm this, maybe you can run I2C scan (copy arduino example) on both release 1.7.0 and 1.8.0 ? (scan should be run after mpu.setup(); )

Just added the i2c scanner and the MPU9250 appeared as 2 devices after mpu.setup() under release 1.5.0. As for release 1.8.0, the i2c scanner couldn't find any devices after mpu.setup() is called.

Ver rel 1.5.0

I2C Scanning before mpu.setup() is called
I2C scanner. Scanning ...
Wire Found address: 104 (0x68)
Scanning completed, Wire found 1 devices
MPU9250 WHO AM I = 71
MPU9250 is online...
AK8963  WHO AM I = 48
Calibration values: 
X-Axis sensitivity adjustment value 1.20
Y-Axis sensitivity adjustment value 1.21
Z-Axis sensitivity adjustment value 1.16
X-Axis sensitivity offset value 0.00
Y-Axis sensitivity offset value 0.00
Z-Axis sensitivity offset value 0.00
I2C Scanning after mpu.setup() is called
I2C scanner. Scanning ...
Wire Found address: 12 (0xC)
Wire Found address: 104 (0x68)
Scanning completed, Wire found 2 devices

With rel 1.8.0

I2C Scanning before mpu.setup() is called
I2C scanner. Scanning ...
Wire Found address: 104 (0x68)
Scanning completed, Wire found 1 devices
MPU9250 WHO AM I = 71
MPU9250 is online...
AK8963  WHO AM I = 0
Could not connect to AK8963: 0x0
I2C Scanning after mpu.setup() is called
I2C scanner. Scanning ...
Scanning completed, Wire found 0 devices

Hi @pacman1945,
Looking at your log, it looks like the problem is not specially with AK8963, but rather during mpu.setup() something went wrong, and probably I2C bus is in bad state preventing any further transfer.
Are you able to capture I2C signals (SCL and SDA) with logical analyzer ? (otherwise with oscilloscope)

@pacman1945 :

Why don't you call :

    Wire.setSCL(<your SCL>);
    Wire.setSDA(<your SDA>);

before Wire.begin() ? PB11, PB10 does not seem to be default I2C pins for ""Blue Pill", right ?

PB11, PB10 does not seem to be default I2C pins for ""Blue Pill", right

Right @pacman1945 :
https://github.com/stm32duino/Arduino_Core_STM32/blob/a6f7a98691959c7b445a9353b67b1bded18d1e0b/variants/PILL_F103XX/variant.h#L102-L103

As the library you used the default Wire instance:
https://github.com/hideakitai/MPU9250/blob/9575a32cf1a8e80af7196cdf1c62d041609e0efa/MPU9250.h#L61

I wonder how it can work on PB11, PB10? 馃槙

Hi everyone,
I confirm issue with I2C library of the Core v1.8.0 for several X-NUCLEO libraries that use I2C bus. I suspect that the issue is due to the introduction of I2C_OTHER_FRAME in the twi.c. If I comment the references to I2C_OTHER_FRAME in twi.c, I do not see any issue on my side.
Best Regards,
Carlo

Thanks @cparata for the feedback.
Stange as I've tested one X-Nucleo with I2C and several other I2C device (eeprom, sensor, display...).
Anyway, It seems there is an issue since repeated start was introduced, so If we found a fixe I will release an 1.8.1 or I will revert it.

Sorry for listing the i2c bus as PB11 & PB10. The was the actual pins that I had used in my project. But for testing purpose and to run the sample sketch, I changed the i2c bus to use PB7 & PB6.

I can't capture i2c signals as I don't have a logic analyzer or oscilloscope. I'll test the suggestion from Carlo and will report back here.

I tried to add "#undef I2C_OTHER_FRAME" to twi.c, but it didn't work. Maybe I should do something else instead of undef.

Anyway, I modified stm32f1xx_hal_i2c.h & stm32f1xx_hal_i2c.c to remove all I2C_OTHER_FRAME definitions and references and this seems to fix the problem. Thanks everyone for the help.

Basically, what I did was to comment every references to I2C_OTHER_FRAME in the twi.c, so the code can call "HAL_I2C_Master_Transmit_IT" and "HAL_I2C_Master_Receive_IT" respectively in the i2c_master_write and in the i2c_master_read that it is equivalent to the second fix that you tried. So, we are aligned in the outcomes.
Best Regards,
Carlo

Hi @pacman1945 and @cparata,
After some (difficult) analysis, we propose you a draft patch see PR #883
Can you both tell me whether you reproduce your issue with this patch ?
Thanks.
I will continue non regression testing on my side.
Note: Patch concern, for now, only STM32F1 and STM32F4.

Hi @ABOSTM ,
thanks for the update. I will try your fix tomorrow and I let you know. Anyway if the issue impacts F4 and F1, should it also impact L1 and F2 that share the same I2C hardware IP of the first 2 families?
Best Regards,
Carlo

Hi Carlo, yes it impact also L1 and F2. But for now it is only a draft patch. It will probably be reworked by development team, and I wait for the official delivery to cover all impacted families. I provided the patch for F1 and F4 so that you can test on your side on both setup that reproduce the issue.

Hi Alexandre,
I confirm that the fix seems working fine on my side. I tested some sketches with NUCLEO-F401RE and X-NUCLEO-6180XA1, X-NUCLEO-53L0A1, X-NUCLEO-53L1A1 and X-NUCLEO-IKS01A3 that with original Core v1.8.0 got issues and now they work all fine on my side.
Best Regards,
Carlo

Thanks Carlo for your test and feedback

Official patch ready for all concerned STM32 families F1, F2, F4 and L1. #883

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Hoel picture Hoel  路  4Comments

pawelsky picture pawelsky  路  4Comments

Jorgen-VikingGod picture Jorgen-VikingGod  路  8Comments

romainreignier picture romainreignier  路  7Comments

ghent360 picture ghent360  路  5Comments