This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/CC2640R2F: I2C bus read failure when accessing the 2nd device connected to the same hardware I2C bus

Part Number: CC2640R2F

Tool/software: TI-RTOS

Environment:

  • simplelink_cc2640r2_sdk_2_30_00_28
  • CC2640R2F LaunchXL hardware + MPU9250 breakout

my failure happens when accessing the built-in magnetometer in MPU9250 IC. The magnetometer is a second I2C component in the same chip package. The primary I2C component takes care of the I2C bus mux.

In order to access the second I2C component, according to MPU9250 manual, we need to write 0 to register 0x6A then 2 to 0x37,(I2C bus device address 0x68). Now we can access the secondary I2C component. It is verified by a reading of WhoAmI register with device I2C bus address 0x0C, which is for the secondary I2C component.
This logic is verified with a quick arduino hack. In order to prevent any register tempering left by previous operation, this arduino test setup has been power cycled before testing.

Modified on i2ctmp007 sample project, the two write operation to the primary device (MPU6050_ADDRESS_AD0_LOW) are successful, both I2C_transfer call returns true. I further read back the register value and confirmed the correct write operation.
Next, the read operation from the secondary device (with different I2C bus address) ends up with I2C_transfer return false.
I tried adding 10ms pause, power cycle the device, close and re-open the I2C bus, change to 100KHz IO speed, none is the silver bullet.
The same 9250 device is tested again in the arduino hack testing environment, and it works as expected.
I start to think there might be some steps needed when switching from operating one I2C slave device to another one, but I didn't find clue in the "I2C.h File Reference" of dev.ti.com/.../

I double checked the i2ctmp007 sample project and sensorTag sample project, no difference in I2C_Params_init,I2C_open steps.

The HW wiring is VCC/GND/SCL/SDA

Is there any other direction I can follow to solve this problem?

i2ctmp007 code extraction:
txBuffer[0] = MAG_WHO_AM_I;
i2cTransaction.slaveAddress = MPU9250_AK8963_ADDRESS;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = 1;
success = I2C_transfer(i2c, &i2cTransaction);

arduino test code extraction:
void setup() {
Serial.begin(115200);
I2CSetup(MPU6050_ADDRESS_AD0_LOW,I2C_FREQ);
startTrans(MPU6050_ADDRESS_AD0_LOW);
write(USER_CTRL_AD);
write(0x00,true);
startTrans(MPU6050_ADDRESS_AD0_LOW);
write(INT_BYPASS_CONFIG_AD);
write(0x02,true);
}
void loop(){
startTrans(MPU9250_AK8963_ADDRESS);
write(MAG_WHO_AM_I);
requestFrom(MPU9250_AK8963_ADDRESS,1,true);
Serial.println(readBuffer());
delay(1000);
}

  • a bit more observations, after the unsuccessful I2C read attempt:
    DATACK_N asserted
    ADRACK_N asserted
    The slave device didn't acknowledge the incoming data. It seems the slave is not in the right operation mode.
    But the two previous configuration write operations have been confirmed with readback value.
    It is 100% repeatable so that we may rule out power glitch.
    The operation mode is I2C_MODE_BLOCKING.
    Speed setting I2C_400kHz is identical to the arduino counterpart.
  • I haven't looked at the details in you post but communication with a MPU9250 has been covered before on the forum. Have you looked at:
    e2e.ti.com/.../543640 as one example