You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
5.7 KiB
263 lines
5.7 KiB
/* mpu6050.c */ |
|
|
|
#include "sensors.h" |
|
#include "mpu6050.h" |
|
#include "i2c.h" |
|
#include "uart.h" |
|
#include "dcm.h" |
|
#include "fisqrt.h" |
|
#include "stick.h" |
|
#include "watchdog.h" |
|
#include "status.h" |
|
#include "abs.h" |
|
#include "event.h" |
|
#include "timer.h" |
|
#include "panic.h" |
|
#include "log.h" |
|
|
|
i2c_result mpu6050_result; |
|
unsigned int mpu6050_generation; |
|
|
|
signed int gyro_zero_roll; |
|
signed int gyro_zero_pitch; |
|
signed int gyro_zero_yaw; |
|
|
|
#define GYRO_ZERO_COUNT 1000 |
|
|
|
unsigned int mpu6050_gyro_zero_count; |
|
|
|
unsigned char mpu6050_sample_data[14]; |
|
|
|
/*unsigned char mpu6050_whoami_command[1] = {0x75}; */ |
|
unsigned char mpu6050_whoami_command[1] = {0x6B}; |
|
|
|
struct i2c_transaction mpu6050_whoami_transaction2; |
|
|
|
struct i2c_transaction mpu6050_whoami_transaction = { |
|
(0x68 << 1) + 0, /* write */ |
|
1, |
|
mpu6050_whoami_command, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
&mpu6050_whoami_transaction2 |
|
}; |
|
|
|
struct i2c_transaction mpu6050_whoami_transaction2 = { |
|
(0x68 << 1) + 1, /* read */ |
|
1, |
|
mpu6050_sample_data, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
NULL |
|
}; |
|
|
|
/* Accelerometer scaling */ |
|
#define AFS_SEL 2 |
|
|
|
|
|
unsigned char mpu6050_init_command[] = {0x6B, 0x01}; |
|
unsigned char mpu6050_accel_init_command[] = {0x1c, (AFS_SEL<<3)}; |
|
|
|
struct i2c_transaction mpu6050_accel_init_transaction = { |
|
(0x68 << 1) + 0, /* write */ |
|
2, |
|
mpu6050_accel_init_command, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
NULL |
|
}; |
|
|
|
struct i2c_transaction mpu6050_init_transaction = { |
|
(0x68 << 1) + 0, /* write */ |
|
2, |
|
mpu6050_init_command, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
&mpu6050_accel_init_transaction |
|
}; |
|
|
|
unsigned char mpu6050_sample_command[] = {0x3B}; |
|
|
|
struct i2c_transaction mpu6050_sample_transaction2; |
|
|
|
struct i2c_transaction mpu6050_sample_transaction = { |
|
(0x68 << 1) + 0, /* write */ |
|
1, |
|
mpu6050_sample_command, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
&mpu6050_sample_transaction2 |
|
}; |
|
|
|
struct i2c_transaction mpu6050_sample_transaction2 = { |
|
(0x68 << 1) + 1, /* read */ |
|
14, |
|
mpu6050_sample_data, |
|
&mpu6050_result, |
|
EVENT_MPU6050_I2C_COMPLETE, |
|
NULL |
|
}; |
|
|
|
void mpu6050_event_handler(void); |
|
|
|
bool mpu6050_init(void) |
|
{ |
|
event_register(EVENT_MPU6050_I2C_COMPLETE, mpu6050_event_handler); |
|
|
|
if (!i2c_start_transaction(&mpu6050_init_transaction)) |
|
return FALSE; |
|
while (i2c_busy()) ; |
|
|
|
return (mpu6050_result == I2C_SUCCESS); |
|
} |
|
|
|
/* LSB / g */ |
|
/* 1 for +- 2g */ |
|
/* 2 for +- 4g */ |
|
/* 4 for +- 8g */ |
|
/* 8 for +- 16g */ |
|
#define ACCEL_STEP (16384.0 / (float)(1<<AFS_SEL)) |
|
|
|
#define TWO_PI 6.28318531f |
|
#define DEG_TO_RAD (TWO_PI/360.0f) |
|
|
|
/* A step of 131 = 1 degree. */ |
|
/* Overall, this is LSB / rad/s */ |
|
#define GYRO_STEP (131.0 / DEG_TO_RAD) |
|
|
|
/* LSB / degree C */ |
|
#define TEMP_STEP 340.0 |
|
#define TEMP_OFFSET 36.53 |
|
|
|
#define ACCEL_SCALE (1.0 / ACCEL_STEP) |
|
#define GYRO_SCALE (1.0 / GYRO_STEP) |
|
#define TEMP_SCALE (1.0 / TEMP_STEP) |
|
|
|
#if 0 |
|
bool mpu6050_sample(void) |
|
{ |
|
unsigned int x, y, z; |
|
unsigned int temp; |
|
unsigned int roll, pitch, yaw; |
|
|
|
if (!i2c_start_transaction(&mpu6050_sample_transaction)) |
|
return FALSE; |
|
|
|
while (i2c_busy()); |
|
|
|
if (mpu6050_result != I2C_SUCCESS) |
|
return FALSE; |
|
|
|
mpu6050_result = I2C_IN_PROGRESS; |
|
|
|
x = (mpu6050_sample_data[0] << 8) + mpu6050_sample_data[1]; |
|
y = (mpu6050_sample_data[2] << 8) + mpu6050_sample_data[3]; |
|
z = (mpu6050_sample_data[4] << 8) + mpu6050_sample_data[5]; |
|
|
|
temp = (mpu6050_sample_data[6] << 8) + mpu6050_sample_data[7]; |
|
|
|
roll = (mpu6050_sample_data[ 8] << 8) + mpu6050_sample_data[ 9]; |
|
pitch = (mpu6050_sample_data[10] << 8) + mpu6050_sample_data[11]; |
|
yaw = (mpu6050_sample_data[12] << 8) + mpu6050_sample_data[13]; |
|
|
|
putstr("MPU6050 sample data:\r\n"); |
|
putstr("x: "); |
|
puthex(x); |
|
putstr(", y: "); |
|
puthex(y); |
|
putstr(", z: "); |
|
puthex(z); |
|
putstr("\r\ntemperature:"); |
|
puthex(temp); |
|
putstr("\r\nroll:"); |
|
puthex(roll); |
|
putstr(", pitch:"); |
|
puthex(pitch); |
|
putstr(", yaw:"); |
|
puthex(yaw); |
|
putstr("\r\n\r\n"); |
|
#if 0 |
|
sensors_write_gyro_data(roll, pitch, yaw); |
|
sensors_write_accel_data(x, y, z); |
|
#endif |
|
|
|
return TRUE; |
|
} |
|
#endif |
|
|
|
bool mpu6050_start_sample(void) |
|
{ |
|
return i2c_start_transaction(&mpu6050_sample_transaction); |
|
} |
|
|
|
void mpu6050_start_zero(void) |
|
{ |
|
mpu6050_gyro_zero_count = GYRO_ZERO_COUNT; |
|
gyro_zero_roll = 0; |
|
gyro_zero_pitch = 0; |
|
gyro_zero_yaw = 0; |
|
} |
|
|
|
void mpu6050_event_handler(void) |
|
{ |
|
signed short int xi, yi, zi; |
|
signed short int tempi; |
|
signed short int rolli, pitchi, yawi; |
|
|
|
float x, y, z; |
|
float temp; |
|
float roll, pitch, yaw; |
|
|
|
CHECKPOINT(9); |
|
|
|
if (mpu6050_result != I2C_SUCCESS) |
|
return; |
|
|
|
mpu6050_result = I2C_IN_PROGRESS; |
|
|
|
sensors_sample_done(); |
|
|
|
xi = (mpu6050_sample_data[0] << 8) + mpu6050_sample_data[1]; |
|
yi = (mpu6050_sample_data[2] << 8) + mpu6050_sample_data[3]; |
|
zi = (mpu6050_sample_data[4] << 8) + mpu6050_sample_data[5]; |
|
|
|
tempi = (mpu6050_sample_data[6] << 8) + mpu6050_sample_data[7]; |
|
|
|
rolli = (mpu6050_sample_data[ 8] << 8)+mpu6050_sample_data[ 9]; |
|
pitchi = (mpu6050_sample_data[10] << 8)+mpu6050_sample_data[11]; |
|
yawi = (mpu6050_sample_data[12] << 8)+mpu6050_sample_data[13]; |
|
|
|
if (mpu6050_gyro_zero_count) { |
|
gyro_zero_roll += rolli; |
|
gyro_zero_pitch += pitchi; |
|
gyro_zero_yaw += yawi; |
|
if (--mpu6050_gyro_zero_count == 0) { |
|
gyro_zero_roll /= GYRO_ZERO_COUNT; |
|
gyro_zero_pitch /= GYRO_ZERO_COUNT; |
|
gyro_zero_yaw /= GYRO_ZERO_COUNT; |
|
} |
|
} else { |
|
rolli -= gyro_zero_roll; |
|
pitchi -= gyro_zero_pitch; |
|
yawi -= gyro_zero_yaw; |
|
} |
|
|
|
x = ((float)xi) * ACCEL_SCALE; |
|
y = ((float)yi) * ACCEL_SCALE; |
|
z = ((float)zi) * ACCEL_SCALE; |
|
|
|
temp = ((float)tempi) * TEMP_SCALE + TEMP_OFFSET; |
|
|
|
roll = ((float)rolli) * GYRO_SCALE; |
|
pitch = ((float)pitchi) * GYRO_SCALE; |
|
yaw = ((float)yawi) * GYRO_SCALE; |
|
|
|
sensors_write_gyro_data(roll, pitch, yaw); |
|
sensors_write_accel_data(x, y, z); |
|
sensors_write_temp_data(temp); |
|
|
|
log_put_array((char *)mpu6050_sample_data, 14); |
|
|
|
CHECKPOINT(10); |
|
} |
|
|
|
|