From e8615511d97ae0dfd74dcec36a28f34db776612d Mon Sep 17 00:00:00 2001 From: William Clark Date: Wed, 10 Jan 2024 17:57:25 +0000 Subject: [PATCH] interupt reg + sync reads --- main.c | 12 +++--------- mpu6050.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- mpu6050.h | 12 ++++++++++++ 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 4ee7373..cd8e675 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,7 @@ int main() { mpu6050.cfg.gyro = MPU6050_GYRO_FS_250; mpu6050.cfg.acc = MPU6050_ACC_FS_2G; + mpu6050.cfg.int_enable.data_rdy = 1; /* reset all signal paths */ /* enable gyro, acc and temp */ @@ -48,7 +49,7 @@ int main() { /* enable DATA_RDY interrupt (polling for now) */ /* active when internal writes to all out data regs are done */ - if (i2c_write(REG_INT_ENABLE, 0x01)) { + if (i2c_write(REG_INT_ENABLE, mpu6050.cfg.int_enable.data_rdy & 1)) { exit(1); } @@ -63,15 +64,8 @@ int main() { usleep(200 * 1000); LOOP: - if (mpu6050_read_gyro(&mpu6050)) { - exit(1); - } - if (mpu6050_read_acc(&mpu6050)) { - exit(1); - } - - if (mpu6050_read_temp(&mpu6050)) { + if (mpu6050_read(&mpu6050)) { exit(1); } diff --git a/mpu6050.c b/mpu6050.c index cca6453..a162ca0 100644 --- a/mpu6050.c +++ b/mpu6050.c @@ -44,12 +44,20 @@ int mpu6050_deinit(mpu6050_t *mpu6050) { int mpu6050_read_acc(mpu6050_t *mpu6050) { uint8_t data[6]; uint8_t shift; + uint8_t int_status; int err = 0; assert(mpu6050); - shift = acc_i16_shift(mpu6050->cfg.acc); + /* if data_rdy interrupt is enabled, wait for data to be ready */ + if (mpu6050->cfg.int_enable.data_rdy) { + do { + err |= mpu6050->dev.read(REG_INT_STATUS, &int_status, 1); + mpu6050->dev.sleep(1000); /* 1 ms */ + } while(!err && !(int_status & 1)); + } + err |= mpu6050->dev.read(REG_ACCEL_XOUT_H, data, 6); mpu6050->data.acc.x = (int16_t)(data[0] << 8 | data[1]) >> shift; mpu6050->data.acc.y = (int16_t)(data[2] << 8 | data[3]) >> shift; @@ -62,12 +70,20 @@ int mpu6050_read_acc(mpu6050_t *mpu6050) { int mpu6050_read_gyro(mpu6050_t *mpu6050) { uint8_t data[6]; uint8_t shift; + uint8_t int_status; int err = 0; assert(mpu6050); - shift = gyro_i16_shift(mpu6050->cfg.gyro); + /* if data_rdy interrupt is enabled, wait for data to be ready */ + if (mpu6050->cfg.int_enable.data_rdy) { + do { + err |= mpu6050->dev.read(REG_INT_STATUS, &int_status, 1); + mpu6050->dev.sleep(1000); /* 1 ms */ + } while(!err && !(int_status & 1)); + } + err |= mpu6050->dev.read(REG_GYRO_XOUT_H, data, 6); mpu6050->data.gyro.x = ((int16_t)(data[0] << 8 | data[1]) >> shift); @@ -89,6 +105,41 @@ int mpu6050_read_temp(mpu6050_t *mpu6050) { return err; } +/* combines the operations of read_temp(), read_gyro() and read_acc() */ +/* if data_rdy interrupt is enabled, this will read all data synched */ +int mpu6050_read(mpu6050_t *mpu6050) { + uint8_t data[14]; /* gyro + accel + temp */ + uint8_t shift_gyro, shift_acc, int_status; + int err = 0; + + assert(mpu6050); + + shift_gyro = gyro_i16_shift(mpu6050->cfg.gyro); + shift_acc = acc_i16_shift(mpu6050->cfg.acc); + + /* if data_rdy interrupt is enabled, wait for data to be ready */ + if (mpu6050->cfg.int_enable.data_rdy) { + do { + err |= mpu6050->dev.read(REG_INT_STATUS, &int_status, 1); + mpu6050->dev.sleep(1000); /* 1 ms */ + } while(!err && !(int_status & 1)); + } + + err |= mpu6050->dev.read(REG_ACCEL_XOUT_H, data, 14); + /* 0-5 acc */ + mpu6050->data.acc.x = (int16_t)(data[0] << 8 | data[1]) >> shift_acc; + mpu6050->data.acc.y = (int16_t)(data[2] << 8 | data[3]) >> shift_acc; + mpu6050->data.acc.z = (int16_t)(data[4] << 8 | data[5]) >> shift_acc; + /* 6-7 temp */ + mpu6050->data.temp = (int16_t)(data[6] << 8 | data[7])/34 + 365; + /* 8-13 gyro */ + mpu6050->data.gyro.x = ((int16_t)(data[ 8] << 8 | data[ 9]) >> shift_gyro); + mpu6050->data.gyro.y = ((int16_t)(data[10] << 8 | data[11]) >> shift_gyro); + mpu6050->data.gyro.z = ((int16_t)(data[12] << 8 | data[13]) >> shift_gyro); + + return err; +} + /* How much to shift down an i16 accel sample depending on full-scale mode set */ static uint8_t acc_i16_shift(uint8_t fs) { switch(fs) { diff --git a/mpu6050.h b/mpu6050.h index 92bb124..104d495 100644 --- a/mpu6050.h +++ b/mpu6050.h @@ -23,9 +23,19 @@ struct mpu6050_dev { int (*deinit)(void); }; +/* for configuring REG_INT_ENABLE */ +struct mpu6050_int_enable { + uint8_t mot; /* enables motion detect interrupt */ + uint8_t fifo_overflow; /* enables FIFO buffer overflow interrupt */ + uint8_t i2c_mst; /* enables any i2c master to generate interrupt */ + uint8_t data_rdy; /* enable interrupt upon finished write to data out registers */ +}; + +/* configuring variables that are written to the device */ struct mpu6050_config { uint8_t gyro; uint8_t acc; + struct mpu6050_int_enable int_enable; }; /* 1 lsb = 1 mg (1/1000 g) */ @@ -42,6 +52,7 @@ struct mpu6050_gyroscope { int16_t z; }; +/* stores all converted data read from the device */ struct mpu6050_data { struct mpu6050_accelerometer acc; struct mpu6050_gyroscope gyro; @@ -61,5 +72,6 @@ int mpu6050_deinit(mpu6050_t *mpu6050); int mpu6050_read_acc(mpu6050_t *mpu6050); int mpu6050_read_gyro(mpu6050_t *mpu6050); int mpu6050_read_temp(mpu6050_t *mpu6050); +int mpu6050_read(mpu6050_t *mpu6050); #endif \ No newline at end of file