jevermeister / MPU6050-ChibiOS

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

I2CdevreadBytes & STM32F103 (Single byte read bug) #2

Open enly1 opened 10 years ago

enly1 commented 10 years ago

To get the library to function and detect the MPU6050, I had to modify the I2CdevreadBytes function to add in specific support for the STM32F103 chip as in Chibios/Hardware, you are unable to read a single byte from the I2C bus.

It is reported as a hardware issue and the workaround is to read multiple bytes, so I patched the function to operate that way and the library is now functional.

Patched function code below:

int8_t I2CdevreadBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) { //uint8_t mpu_txbuf[1], mpu_rxbuf[I2CDEV_BUFFER_LENGTH], i; msg_t rdymsg; uint8_t tmpdata[2];

if(length > I2CDEV_BUFFER_LENGTH) {
    chprintf((BaseSequentialStream *)&SD3,"ERROR readBytes: length > I2CDEV BUFFERLENGTH\n");
    return FALSE;
}
i2cAcquireBus(&I2C_MPU);

if defined(STM32F1XX_I2C)

if (length==1)
{
  rdymsg = i2cMasterTransmitTimeout(&I2C_MPU, devAddr, &regAddr, 1, &tmpdata[0], 2, MS2ST(timeout));
  *data = tmpdata[0];
} else
{
    rdymsg = i2cMasterTransmitTimeout(&I2C_MPU, devAddr, &regAddr, 1, data, length, MS2ST(timeout));
}

else

rdymsg = i2cMasterTransmitTimeout(&I2C_MPU, devAddr, &regAddr, 1, data, length, MS2ST(timeout));

endif

i2cReleaseBus(&I2C_MPU);
if(rdymsg == RDY_TIMEOUT || rdymsg == RDY_RESET) {
    chprintf((BaseSequentialStream *)&SD3,"I2C ERROR: %d\n", i2cGetErrors(&I2CD1));
    return FALSE;
}
return TRUE;

}

Note that it could be made fractionally more efficient by wrapping uint8_t tmpdata[2]; with the #ifdef but I didn't test that before copy/pasting the code.

jevermeister commented 10 years ago

I have some STM32F103 boards laying around at work. Maybe I'll try it out if I have some spare time. Can't this issue fixed by ChibiOS instead? I would prefer that over adding hardware-specific code.

enly1 commented 10 years ago

Its not a chibios issue as such - long running discussion, but the issue is do you read 2 bytes the one requested and another or the register before and the one after etc ... It kind of really should be dealt with in the upper layer code, but threw this in to get it going.

Not sure if this would be safe as a standard option, but for use with this i2c device it works well (so far in testing).

So it was just as much as a heads up than a planned commit suggestion.