Differences between MPU9150 and MPU9250 for accessing the compass (magnetometer)

By barakman , 21 January 2016

Hi.

I am using the same code (register read/write operations) for both MPU9150 and MPU9250.

I am able to access the accelerometer and the gyroscope on both devices, but I am unable to access the magnetometer (compass) on MPU9250.

My initialization code is very simple:
1. Register PWR_MGMT_1: Reset all the internal registers of the MPU to their default values
WriteReg(0x68, 0x6B, 0x80); Delay_ms(100);
2. Register INT_PIN_CFG: Allow the host application processor to directly access the auxiliary I2C bus of the MPU
WriteReg(0x68, 0x37, 0x02); Delay_ms(100);
3. Register PWR_MGMT_1: Set the MPU clock source to one of the gyroscope clocks (more accurate), and disable the temperature sensor
WriteReg(0x68, 0x6B, 0x09); Delay_ms(100);

After that, my initial attempt to access the compass completes successfully on MPU9150 but never returns on MPU9250:
1. Register CNTL1: Power-down mode
WriteReg(0x0C, 0x0A, 0x00);

I have compared the register contents of each device after the initialization procedure.

MPU9150 Register Contents | MPU9250 Register Contents
-------------------------------------|-------------------------------------
837F04CD E4CE01D8 F63D02B8 E96F6F94 | C5CEDDED 9813DD4F E5F1FFFC 005F5A87
37000000 00000000 00000000 00000000 | B0AAB900 00000000 00000000 00000000
00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000
00000000 00000002 00000501 A0FBDC3F | 00000000 00000002 0000057F FF0508B7
B0000000 DFFF1900 8C000000 00000000 | 4412F0FF FC006300 74000000 00000000
00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000
00000000 00000000 00000009 00000000 | 00000100 00000000 00000009 00000000
B4B5F3FB 4DD9ED7F 7B7D0F3F 3EE9EB6F | 319A5AF4 0D009206 00009BC9 4D20558A

The only differences in writable registers are given below:

Address | Value on MPU9150 | Value on MPU9250 | Description for MPU9150 | Description for MPU9250
---------|------------------|------------------|-------------------------|-------------------------
0x00 | 0x83 | 0xC5 | | SELF_TEST_X_GYRO
0x01 | 0x7F | 0xCE | | SELF_TEST_Y_GYRO
0x02 | 0x04 | 0xDD | | SELF_TEST_Z_GYRO
0x03 | 0xCD | 0xED | |
0x04 | 0xE4 | 0x98 | |
0x05 | 0xCE | 0x13 | |
0x06 | 0x01 | 0xDD | |
0x07 | 0xD8 | 0x4F | |
0x08 | 0xF6 | 0xE5 | |
0x09 | 0x3D | 0xF1 | |
0x0A | 0x02 | 0xFF | |
0x0B | 0xB8 | 0xFC | |
0x0C | 0xE9 | 0x00 | |
0x0D | 0x6F | 0x5F | SELF_TEST_X | SELF_TEST_X_ACCEL
0x0E | 0x6F | 0x5A | SELF_TEST_Y | SELF_TEST_Y_ACCEL
0x0F | 0x94 | 0x87 | SELF_TEST_Z | SELF_TEST_Z_ACCEL
0x10 | 0x37 | 0xB0 | SELF_TEST_A |
0x11 | 0x00 | 0xAA | |
0x12 | 0x00 | 0xB9 | |
---------|------------------|------------------|-------------------------|-------------------------
0x62 | 0x00 | 0x01 | |
---------|------------------|------------------|-------------------------|-------------------------
0x70 | 0xB4 | 0x31 | |
0x71 | 0xB5 | 0x9A | |
0x72 | 0xF3 | 0x5A | FIFO_COUNTH | FIFO_COUNTH
0x73 | 0xFB | 0xF4 | FIFO_COUNTL | FIFO_COUNTL
0x74 | 0x4D | 0x0D | FIFO_R_W | FIFO_R_W
0x75 | 0xD9 | 0x00 | WHO_AM_I | WHO_AM_I
0x76 | 0xED | 0x92 | |
0x77 | 0x7F | 0x06 | | XA_OFFSET_H
0x78 | 0x7B | 0x00 | | XA_OFFSET_L
0x79 | 0x7D | 0x00 | |
0x7A | 0x0F | 0x9B | | YA_OFFSET_H
0x7B | 0x3F | 0xC9 | | YA_OFFSET_L
0x7C | 0x3E | 0x4D | |
0x7D | 0xE9 | 0x20 | | ZA_OFFSET_H
0x7E | 0xEB | 0x55 | | ZA_OFFSET_L
0x7F | 0x6F | 0x8A | |

Please note that I also included the read-only WHO_AM_I register, because:
1. It is within that segment of different registers (between 0x70 and 0x7F)
2. It shows a value different from what the data-sheet specifies (0x68 on MPU9150 and 0x71 on MPU9250)

I have taken each one of the following actions in an attempt to resolve the problem, but none of them seemed to show any positive results:
1. Before accessing the compass on MPU9250, I wrote the entire register contents that I had previously read from MPU9150 into MPU9250
2. When accessing the compass on MPU9250, instead of using 0x0C as the address of the AKM device on the I2C bus, I tried addresses 0x0D, 0x0E and 0x0F
I found a driver which was using 0x0C<<1 instead of 0x0C, so I tried addresses 0x0C<<1, 0x0D<<1, 0x0E<<1 and 0x0F<<1 (0x18, 0x19, 0x1A and 0x1B) as well

I admit that I have not tried to combine both of the actions above, because at that point, I was pretty sure that something else was fundamentally wrong.

Again - the general question is:
Are there any differences between MPU9150 and MPU9250 for accessing the compass, that I am missing?
Or is my initialization code wrong (or partially incomplete), in a manner that somehow allows me to access the compass on MPU9150 but not on MPU9250?

Thanks

phpbb Topic ID
32912