jevermeister / MPU6050-ChibiOS

Code based on i2cdevlib by Jeff Rowberg
15 stars 15 forks source link

I2CdevwriteWords - Function Broken #1

Closed enly1 closed 10 years ago

enly1 commented 10 years ago

Hi,

Not sure if the library is still in use, but I started using it a couple of days ago to deal with the MPU6050 on a custom board. My board appeared to throw bogus quats until the gyro recalibrated itself.

After lots of head scratching, I decided to check the library code to see if I could track down the issue and it turns out that the I2CdevwriteWords function is incorrectly coded / ported from the original sources.

The array indexes starting at 1 result in the wrong bytes being sent over I2C.

Buffer population loop (original and updated shown in place)

bool_t I2CdevwriteWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data) { uint8_t mpu_txbuf[I2CDEV_BUFFER_LENGTH], mpu_rxbuf[1], i; msg_t rdymsg;

if(((length * 2) + 1)> I2CDEV_BUFFER_LENGTH) {
    return FALSE;
}
mpu_txbuf[0] = regAddr;

// BUG IN CODE FOR WRITING BYTES ... BAD LOGIC
for(i=1;i<((length * 2) + 1);i += 2) {
  mpu_txbuf[i] = (data[i] >> 8) & 0xff;
  mpu_txbuf[i+1] = data[i] & 0xff;
}

for(i=0;i<length*2; i+=2)
{
  mpu_txbuf[i+1] = (data[i] >> 8) & 0xff;
  mpu_txbuf[i+2] = data[i] & 0xff;

}

i2cAcquireBus(&I2C_MPU);
rdymsg = i2cMasterTransmit(&I2C_MPU, devAddr, mpu_txbuf, (length * 2) + 1, mpu_rxbuf, 0);
i2cReleaseBus(&I2C_MPU);
if(rdymsg == RDY_TIMEOUT || rdymsg == RDY_RESET) {
    return FALSE;
}
return TRUE;

}

Hope it helps.

Only really shows up if you use the MPUsetXGyroOffsetUser type functions as they write words not bytes as the MPUsetXGyroOffset functions do.

jevermeister commented 10 years ago

I wrote the code during my master thesis and haven't touched it since then. Unfortunately I also don't have a MPU6050 at home to test your changes and I never used this function.

Looks correct though. I'll submit the changes. Thanks!