I've found a few other people ask about this, but all of them are coding in Arduino, and I'm struggling to translate it into my project.
I'm on a research team developing a Cube Satellite for launch, and my role is to communicate with the peripherals, including the IMU (MPU-9250). I'm cross compiling with uClinux, coding in C.
So far, I can successfully read the accelerometer, gyroscope, and temperature, but cannot get the readings from the magnetometer. The magnetometer (AK8963) has its own address (0x0C), and I've been trying to communicate with it by writing to I2C_SLV0_ADDR(0x25), I2C_SLV0_REG(0x26), and I2C_SLV0_CTRL(0x27). Once I didn't appear to get any results, I tried to resolve it by writing to FIFO Enable(0x23) and I2C Master Control(0x24)
The datasheet and register map imply that the values taken from the magnetometer are stored in registers External Sensor Data(0x49-0x60), but I'm not getting anything in those registers when I try this.
Here's some code that shows the data I'm writing to the registers:
write_register(0x23, 0x04);
write_register(0x24, 0b11110000);
write_register(0x25,0x8c);
write_register(0x26,0x00);
write_register(0x27,0b11110001);
So my questions are: 1. Am I going about this process the right way, or am I completely off?
- If I am on the right track, am I reading from the correct registers?
Thanks for your help everyone! Let me know if there's anything I need to clarify!
Alright! I figured out my own question :)
1) I was indeed going about the process the wrong way. There is a much easier way to do that and I will show how in detail.
2) I was not reading from the correct registers. I'll show what to do below.
So, connecting to the Magnetometer is super easy, but not intuitive at all. It does act like its own slave with its own slave address, but that address is inaccessible initially.
Since I'm cross compiling with uClinux, I can use the bash command
i2cdetect 0(when screening into my SmartFusion2) to check all the slaves on my i2C 0 bus. When I execute this command after resetting my board, I get the following address map printed out:So you can see that only the address for the IMU(0x68) is showing. To get the magnetometer showing up properly, you have to enable a bypass bit on INT_PIN_CFG(0x37). I've attached my code below in case anyone needs to replicate this.
Once the code is compiled and run, the command
i2cdetect 0returns the following datamap.The program also returns 0x48, the correct value when reading from the magnetometer's 'who am I?' register. The magnetometer can now be read just like any other register. Hope this helps!!