Hi Tomas,
I have now tried to work with all my I2C devices, and I get strange values from all of them.
I have tried to lower my bitrate on the bus - I'm now running 250kHz
Here is a trace of the whole of a 7 byte read from adr 0 and up

Here I've zoomed in on the first part of the transfer

And here's further zoomed on the last bit of the zoom above

Here's how I've set up the different devices:
#define aAcce 0x1d
#define aGyro 0x20
#define aComp 0x0e
//registers in the MM8652 acceleromter
#define aDaCfg 0x0e
#define aCtrl1 0x2a
#define aCtrl2 0x2b
#define aCtrl3 0x2c
#define aCtrl4 0x2d
#define aCtrl5 0x2e
//registers in the FXA21002C Gyro
#define gCtrl0 0x0d
#define gCtrl1 0x13
#define gCtrl2 0x14
//registers in the MAG3110 Magnetometer
#define cCtrl1 0x10
#define cCtrl2 0x11
//disable I2C devices
IIC_WriteReg(aComp, cCtrl1, 0x00); //stop magnetometer
IIC_WriteReg(aAcce, aCtrl1, 0x00); //stop accelerometer
IIC_WriteReg(aGyro, gCtrl1, 0x00); //stop gyro
//reset i2Cdevices
IIC_WriteReg(aComp, cCtrl2, 0x10); //reset magnetometer
IIC_WriteReg(aAcce, aCtrl2, 0x40); //Reset accelerometer
IIC_WriteReg(aGyro, gCtrl1, 0x40); //Reset gyro
__delay_ms(10);
//Setup MMA8652 Accelerometer
IIC_WriteReg(aAcce, aDaCfg, 0x00); //select 2g range
IIC_WriteReg(aAcce, aCtrl2, 0x02); //High resolution
IIC_WriteReg(aAcce, aCtrl3, 0x02); //Interrupt active high
IIC_WriteReg(aAcce, aCtrl4, 0x01); //Interrupt on Data Ready
IIC_WriteReg(aAcce, aCtrl5, 0x01); //Data ready comes out on Int1 pin
IIC_WriteReg(aAcce, aCtrl1, 0x29); //Sample at 12.5Hz and activate
//Setup Gyro FXAS21002C
IIC_WriteReg(aGyro, gCtrl0, 0x03); //250 degrees per second
IIC_WriteReg(aGyro, gCtrl2, 0x0e); //Interrupt at data ready on pin 1 active high
IIC_WriteReg(aGyro, gCtrl1, 0x1f); //Sample at 12.Hz and activate
//setup MAG3110 Magnetometer
IIC_WriteReg(aComp, cCtrl2, 0x80); //run continous
IIC_WriteReg(aComp, cCtrl1, 0x19); //Sample at 10Hz and activate
This is my code to get the acceleration values, I now use you code Tomas so I place the values in the low 12 bits of a signed integer
I then check that the sum of the absolute acceration values are at least 900 - othervise the MM8652 has dropped measuring gravity
- and check that I can read the control registers correctly.
int X,Y,Z;
int AccTid=0, GyroTid=0, MagTid=0;
unsigned long g=0, z=0, i2cgood=0, i2cbad=0;
while(1) {
if (AccDataRdy) {
char buf[7];
IIC_ReadRegs(aAcce, 0, 7, buf);
X = (buf[1]<<8 | buf[2])>>4;
Y = (buf[3]<<8 | buf[4])>>4;
Z = (buf[5]<<8 | buf[6])>>4;
int tot;
tot = abs(X) + abs(Y)+ abs(Z);
if (tot < 900) z++; else g++;
if (CheckRegs) {
//Now check read all written I2C registers
IIC_ReadRegs(aAcce, aCtrl1, 7, buf); //First MMA8652 accelerometer
if (buf[0] == 0x29) i2cgood++; else i2cbad++; //Check CTRL_REG1
if (buf[1] == 0x02) i2cgood++; else i2cbad++; //Check CTRL_REG2
if (buf[2] == 0x02) i2cgood++; else i2cbad++; //Check CTRL_REG3
if (buf[3] == 0x01) i2cgood++; else i2cbad++; //Check CTRL_REG4
if (buf[4] == 0x01) i2cgood++; else i2cbad++; //Check CTRL_REG5
if (IIC_ReadReg(aAcce, aDaCfg) == 0x00) i2cgood++; else i2cbad++; //Check XYZ_DATA_CFG
IIC_ReadRegs(aGyro, gCtrl1, 2, buf); //Next Gyro FXAS21002C
if (buf[0] == 0x1f) i2cgood++; else i2cbad++; //Check CTRL_REG1
if (buf[1] == 0x0e) i2cgood++; else i2cbad++; //Check CTRL_REG2
if (IIC_ReadReg(aGyro, gCtrl0) == 0x03) i2cgood++; else i2cbad++; //Check CTRL_REG0
IIC_ReadRegs(aComp, cCtrl1, 2, buf); //Last MAG3110 Magnetometer
if (buf[0] == 0x19) i2cgood++; else i2cbad++; //Check CTRL_REG1
//CTRL_REG2 can't be read back - always reads as 0
// if (buf[1] == 0x80) i2cgood++; else i2cbad++; //Check CTRL_REG2
}
AccTid++;
if (AccTid >= 25) {
AccTid=0;
while (!DebugDone);
sprintf(DebugInfo,"ACC X:%6d Y:%6d Z:%6d -g: %lu +g: %lu -r: %lu +r: %lu\r\n", X, Y, Z, z,g, i2cbad, i2cgood);
// z=g=0;
SendDebugInfo(DebugInfo);
}
}
Here's an example of my debug output:
ACC X: -2 Y: -1 Z: 1043 -g: 5364 +g: 51286 -r: 0 +r: 566500
ACC X: -2 Y: -5 Z: -1 -g: 5368 +g: 51307 -r: 0 +r: 566750
ACC X: -2 Y: -2 Z: 1042 -g: 5370 +g: 51330 -r: 0 +r: 567000
ACC X: -1 Y: -2 Z: 1042 -g: 5370 +g: 51355 -r: 0 +r: 567250
ACC X: -2 Y: -3 Z: 1042 -g: 5374 +g: 51376 -r: 0 +r: 567500
ACC X: -2 Y: -3 Z: 1042 -g: 5376 +g: 51399 -r: 0 +r: 567750
ACC X: -3 Y: -2 Z: 1043 -g: 5376 +g: 51424 -r: 0 +r: 568000
ACC X: -3 Y: -3 Z: -1 -g: 5378 +g: 51447 -r: 0 +r: 568250
ACC X: 16 Y: -2 Z: 1041 -g: 5381 +g: 51469 -r: 0 +r: 568500
ACC X: -4 Y: -2 Z: 1041 -g: 5386 +g: 51489 -r: 0 +r: 568750
ACC X: -3 Y: -4 Z: 1040 -g: 5387 +g: 51513 -r: 0 +r: 569000
As you can fom this test - horizontal gavity is dropped around 10% of the samples
-g (without gravity) is 5387 samples and good samples is 51513
Half a million control registers have been read and all the reads returned the expected values.
If I tilt the board about 10 degrees about 40% of the samples has no gravity
ACC X: 176 Y: -3 Z: 1025 -g: 19377 +g: 30511 -r: 0 +r: 498880
ACC X: 176 Y: -3 Z: 1026 -g: 19381 +g: 30532 -r: 0 +r: 499130
ACC X: -3 Y: -7 Z: -2 -g: 19387 +g: 30551 -r: 0 +r: 499380
ACC X: 177 Y: -4 Z: 1024 -g: 19397 +g: 30566 -r: 0 +r: 499630
ACC X: 177 Y: -3 Z: 1024 -g: 19407 +g: 30581 -r: 0 +r: 499880
I hope this is enough information for you to pinpoint what I'm doing wrong.
I have attached the log files - one line for every 25 samples.
The gyro seems to drift a lot - I've made code that averages the first 16 samples of each channel and I then subtract that from the raw samples - but a simple integation (summation) of the samples still drift - If I then redo my offset it starts to drift in other directions
We are talking about 100,000 LSB in around 10 minutes at 12.5 Hz samplerate
The compass is pointing south (I believe) and returns
X jumping between either 0 or 2000
Y relatively stable at 800-1000
Z around zero
But I can read the control registers from both devices - very strange
Morten