AK8975 - MPU9150 problems

Hi,

I'm trying to use an MPU-9150 but am struggling to get anything sensible out of the compass.
I get good data from the accelerometer and gyros but the compass returns the same value for each axis which doesn't seem right.
On closer inspection I'm getting an error flag suggesting that the data is not being read at the correct time (ST2 = 4).

I'm using the arduino to read values from the MPU6050, which in tern interrogates the AK8975, but I think I can narrow down the problem (or at least one problem) to communication between the MPU6050 and AK8975 which is a fairly common task. So I'm hoping that someone else has had the same issue, or could offer some advice regarding how to correctly time the read requests.

I've tried as many example codes as I could but I still can't work out how to correct this problem so any help is much appreciated.

Attached are the relevant datasheets.

Wingers

AK8975.pdf (628 KB)

RM-MPU-9150A-00v4_2.pdf (789 KB)

Here is the code that I'm using to setup the communication between MPU6050 and AK8975:

// Initialise compass
void Compass_Setup()
{
  //setup compass i2c parameters
   I2C_ADDRESS = AK8975_I2C_ADDRESS; // set to AK8975 (compass) address
  
   I2C_write(0x0A, 0x00); // PowerDownMode
   I2C_write(0x0A, 0x0F); // SelfTest
   I2C_write(0x0A, 0x00); // PowerDownMode
   
   I2C_ADDRESS = MPU9150_I2C_ADDRESS; //reset to MPU address

  // Setup MPU9150 to receive data from compass and write it to internal registers.
  I2C_write(0x24, 0x40);      // Setup device to wait for external sensor (compass) data before firing interupt

// Slave 0
  I2C_write(0x25, 0x8C);      // Set I2C address for slave 0.
  I2C_write(0x26, 0x02);      // Set internal register for compass data.
  I2C_write(0x27, 0x88);      // Set I2C control for slave 0.

// Slave 1
  I2C_write(0x28, 0x0C);      // Set I2C address for slave 1.
  I2C_write(0x29, 0x0A);      // Set internal register for compass I2C control field.
  I2C_write(0x2A, 0x81);      // Set I2C control for slave 1.

  I2C_write(0x2D, 0x00);      // disable slv2
  I2C_write(0x30, 0x00);      // disable slv3

  I2C_write(0x64, 0x01);      // overvride register
  I2C_write(0x67, 0x03);      // set delay rate
  I2C_write(0x01, 0x80);

  I2C_write(0x34, 0x04);      // set i2c slv4 delay
  I2C_write(0x64, 0x00);      // set power-down mode
  I2C_write(0x6A, 0x00);      // clear usr setting
  I2C_write(0x64, 0x01);      // set register (to turn AK8975 into single measure mode each cycle)
  I2C_write(0x6A, 0x20);      // enable master i2c mode
  I2C_write(0x34, 0x13);      // disable slv4
}

// Read one byte from MPU
int I2C_read(int addr)
  {
    Wire.beginTransmission(I2C_ADDRESS);
    Wire.write(addr);
    Wire.endTransmission(false);  //False retains control of the i2c pins should another master device attempt comunication.

    Wire.requestFrom(I2C_ADDRESS, 1, true);
    byte Res = Wire.read();

    return Res;
  }

// Read two bytes from MPU
int I2C_read(int addrL, int addrH)
  {
    Wire.beginTransmission(I2C_ADDRESS);
    Wire.write(addrL);
    Wire.endTransmission(false);  //False retains control of the i2c pins should another master device attempt comunication.

    Wire.requestFrom(I2C_ADDRESS, 1, true);
    byte L = Wire.read();

    Wire.beginTransmission(I2C_ADDRESS);
    Wire.write(addrH);
    Wire.endTransmission(false);  //False retains control of the i2c pins should another master device attempt comunication.

    Wire.requestFrom(I2C_ADDRESS, 1, true);
    byte H = Wire.read();

    return (H << 8) + L;
  }

// Write one byte to MPU
int I2C_write(int addr,int data){
     Wire.beginTransmission(I2C_ADDRESS);
     Wire.write(addr);
     Wire.write(data);
     Wire.endTransmission(true);

     return 1;
 }

Wingers

Hi, have you already solved the problem? I also meet the same problem,when I useing the MPU-9150