interupt reg + sync reads
This commit is contained in:
parent
f331f3d47d
commit
e8615511d9
12
main.c
12
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);
|
||||
}
|
||||
|
||||
|
55
mpu6050.c
55
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) {
|
||||
|
12
mpu6050.h
12
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
|
Loading…
Reference in New Issue
Block a user