I am interfacing an MPU-9250 to an STM8S207 microcontroller. The MPU-9250 is accessed via 400kHz I2C. I have no isses with getting measurement data from the temperature, gyro and accelerometer, but can not get the built-in AK8963 magnetometer measurement results. I can read out the AK8963 device ID correctly, looks like the Fuse-ROM calibration values are correct, but when I program the 0x0A (CNTL1) mode register to 0x01 or 0x02 (single or 8Hz measurements), the DRDY flag never transitions to 1, and the CNTL1 register reads back 0x03, which is a reserved value.
Any ideas what I am missing?
The initialization sequence I'm using is below, after configure_imu() is called, reg 0x0A from the AK8963 reads back as 0x03.
void configure_imu()
{
u8 status, mag_mode, mag_sense[3];
i2c_write_byte(MPU_I2CAddress, 27,GYRO_FULL_SCALE_2000_DPS); // Configure gyroscope range
i2c_write_byte(MPU_I2CAddress, 28,ACC_FULL_SCALE_16_G); // Configure accelerometers range
i2c_write_byte(MPU_I2CAddress, 0x37,0x02); // Set bypass mode for external I2C master connection
i2c_write_byte(MPU_I2CAddress, 0x6B,0x01); // Clock source is PLLGYROZ
i2c_write_byte(MPU_I2CAddress, 0x19,0x04); // Set SMPLRT_DIV to 0x04; this gives a 200 Hz sample rate when using the DLPF
i2c_write_byte(MPU_I2CAddress, 0x1A,0x03); // 42 Hz LPF
i2c_write_byte(MPU_I2CAddress, 0x6A,0x01); // Disable master mode and clear all signal paths
//i2c_write_byte(MPU_I2CAddress, 0x37,0x32); // Interrupts pin stays high until cleared, cleared on any read, I2C bypass
//i2c_write_byte(MPU_I2CAddress, 0x38,0x01); // Data ready interrupt enabled
status = i2c_read(MAG_I2CAddress, 0x00, I2C_rx_rd_ptr++, 1);
if (status==0) return;
i2c_write_byte(MAG_I2CAddress, 0x0B,0x01); // Software Reset Magnetometer
Delay(10000);
i2c_write_byte(MAG_I2CAddress, 0x0B,0x00); // Deassert Software Reset Magnetometer
Delay(10000);
do { status = i2c_read(MAG_I2CAddress, 0x0A, &mag_mode, 1); }
while ((status==1) && (mag_mode>0));
i2c_write_byte(MAG_I2CAddress, 0x0A,0x0F); // Enter Fuse-ROM mode
Delay(10000);
i2c_read(MAG_I2CAddress, 0x10, mag_sense, 3); // Read the x-, y-, and z-axis calibration values
i2c_write_byte(MAG_I2CAddress, 0x0A,0x00); // Enter power-down mode
Delay(10000);
i2c_write_byte(MAG_I2CAddress, 0x0A,0x02); // Magnetometer to enter continuous 8Hz measurement mode
}
Thank you all for the comments! In the next version of the board I replaced the MPU-9250, however widespread it is, with a Bosch BMO055. It's little help if you are already committed to MPU9150/9250, but if board re-spin is still an option for you, I highly recommend the Bosch part. It has the Sensor Fusion engine built in, generating the acceleration / heading / quarternion information right outside the box without any MCU post-processing - which is actually what I needed.