1122 lines
38 KiB
C
1122 lines
38 KiB
C
#include "app_config.h"
|
||
#include "asm/clock.h"
|
||
#include "asm/cpu.h"
|
||
#include "generic/typedef.h"
|
||
#include "generic/gpio.h"
|
||
#include "mpu9250.h"
|
||
#include "typedef.h"
|
||
#include "system/includes.h"
|
||
#include "media/includes.h"
|
||
#include "asm/iic_hw.h"
|
||
#include "asm/iic_soft.h"
|
||
#include "asm/timer.h"
|
||
#include "imuSensor_manage.h"
|
||
|
||
#if TCFG_TP_MPU9250_ENABLE
|
||
|
||
#undef LOG_TAG_CONST
|
||
#define LOG_TAG "[mpu9250]"
|
||
#define LOG_ERROR_ENABLE
|
||
#define LOG_INFO_ENABLE
|
||
#include "debug.h"
|
||
|
||
#if TCFG_MPU9250_USER_IIC_TYPE
|
||
#define iic_init(iic) hw_iic_init(iic)
|
||
#define iic_uninit(iic) hw_iic_uninit(iic)
|
||
#define iic_start(iic) hw_iic_start(iic)
|
||
#define iic_stop(iic) hw_iic_stop(iic)
|
||
#define iic_tx_byte(iic, byte) hw_iic_tx_byte(iic, byte)
|
||
#define iic_rx_byte(iic, ack) hw_iic_rx_byte(iic, ack)
|
||
#define iic_read_buf(iic, buf, len) hw_iic_read_buf(iic, buf, len)
|
||
#define iic_write_buf(iic, buf, len) hw_iic_write_buf(iic, buf, len)
|
||
#define iic_suspend(iic) hw_iic_suspend(iic)
|
||
#define iic_resume(iic) hw_iic_resume(iic)
|
||
#else
|
||
#define iic_init(iic) soft_iic_init(iic)
|
||
#define iic_uninit(iic) soft_iic_uninit(iic)
|
||
#define iic_start(iic) soft_iic_start(iic)
|
||
#define iic_stop(iic) soft_iic_stop(iic)
|
||
#define iic_tx_byte(iic, byte) soft_iic_tx_byte(iic, byte)
|
||
#define iic_rx_byte(iic, ack) soft_iic_rx_byte(iic, ack)
|
||
#define iic_read_buf(iic, buf, len) soft_iic_read_buf(iic, buf, len)
|
||
#define iic_write_buf(iic, buf, len) soft_iic_write_buf(iic, buf, len)
|
||
#define iic_suspend(iic) soft_iic_suspend(iic)
|
||
#define iic_resume(iic) soft_iic_resume(iic)
|
||
#endif
|
||
|
||
static mpu9250_param *mpu9250_iic_info;
|
||
static mpu9250_data mpu9250_raw_data = {0};
|
||
|
||
|
||
#define MPU9250_INT_IO (-1)//TCFG_TP_INT_IO //pg5
|
||
/* #define MPU9250_INT_IO IO_PORTA_04 */
|
||
/* #define MPU9250_NCS_IO IO_PORTA_05 */
|
||
/* #define MPU9250_FSYNC_IO IO_PORTA_05 */
|
||
#define MPU9250_INT_R() gpio_read(MPU9250_INT_IO)
|
||
static u8 mpu9250_int_pin = MPU9250_INT_IO;
|
||
static u8 mpu_i2c_buf_write(u8 slave_addr, u8 reg_addr, u8 *buf, u8 len)
|
||
{
|
||
u8 i;
|
||
iic_start(mpu9250_iic_info->iic_hdl);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr)) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
udelay(mpu9250_iic_info->iic_delay);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, reg_addr)) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
|
||
for (i = 0; i < len; i++) {
|
||
udelay(mpu9250_iic_info->iic_delay);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, buf[i])) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
}
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return i;
|
||
}
|
||
|
||
|
||
static u8 mpu_i2c_buf_read(u8 slave_addr, u8 reg_addr, u8 *buf, u8 len)
|
||
{
|
||
u8 i;
|
||
iic_start(mpu9250_iic_info->iic_hdl);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr)) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
udelay(mpu9250_iic_info->iic_delay);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, reg_addr)) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
udelay(mpu9250_iic_info->iic_delay);
|
||
|
||
iic_start(mpu9250_iic_info->iic_hdl);
|
||
if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr + 1)) {
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
return 0;
|
||
}
|
||
for (i = 0; i < len; i++) {
|
||
udelay(mpu9250_iic_info->iic_delay);
|
||
if (i == (len - 1)) {
|
||
*buf++ = iic_rx_byte(mpu9250_iic_info->iic_hdl, 0);
|
||
} else {
|
||
*buf++ = iic_rx_byte(mpu9250_iic_info->iic_hdl, 1);
|
||
}
|
||
}
|
||
iic_stop(mpu9250_iic_info->iic_hdl);
|
||
|
||
return i;
|
||
}
|
||
|
||
//设置MPU9250陀螺仪传感器满量程范围
|
||
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
|
||
//返回值:1,设置成功
|
||
// 0,设置失败
|
||
u8 mpu6500_set_full_scale_gyro_range(u8 fsr)//0x1b(bit34)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
fsr &= 0x3;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_GYRO_CFG_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (((temp_data & 0x18) >> 3) != fsr) {
|
||
SFR(temp_data, 3, 2, fsr);
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_GYRO_CFG_REG, &temp_data, 1);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
//设置MPU9250加速度传感器满量程范围
|
||
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
|
||
//返回值:1,设置成功
|
||
// 0,设置失败
|
||
u8 mpu6500_set_full_scale_accel_range(u8 fsr)//0x1c(bit34)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
fsr &= 0x3;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (((temp_data & 0x18) >> 3) != fsr) {
|
||
SFR(temp_data, 3, 2, fsr);
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG, &temp_data, 1);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
*For the DLPF to be used, fchoice[1:0] must be set to 2’b11, fchoice_b[1:0] is 2’b00.
|
||
See table 3 below.
|
||
The DLPF is configured by DLPF_CFG, when FCHOICE_B [1:0] = 2b’00. The gyroscope and
|
||
temperature sensor are filtered according to the value of DLPF_CFG and FCHOICE_B as shown in the table below. Note that FCHOICE mentioned in the table below is the inverted value of FCHOICE_B (e.g. FCHOICE=2b’00 is same as FCHOICE_B=2b’11).
|
||
|
||
//设置MPU9250gyroscope and temperature sensor的数字低通滤波器
|
||
//lpf:数字低通滤波频率(Hz)
|
||
//返回值:1,设置成功
|
||
// 0,设置失败
|
||
* */
|
||
u8 mpu_set_dlpf(u16 lpf)//0x1a(bit012)
|
||
{
|
||
u8 data = 0;
|
||
if (lpf >= 188) {
|
||
data = 1;
|
||
} else if (lpf >= 98) {
|
||
data = 2;
|
||
} else if (lpf >= 42) {
|
||
data = 3;
|
||
} else if (lpf >= 20) {
|
||
data = 4;
|
||
} else if (lpf >= 10) {
|
||
data = 5;
|
||
} else {
|
||
data = 6;
|
||
}
|
||
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
data &= 0x07;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_CFG_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if ((temp_data & 0x07) != data) {
|
||
temp_data &= ~0x07;
|
||
temp_data |= data;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_CFG_REG, &temp_data, 1); //设置数字低通滤波器
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/*
|
||
*Divides the internal sample rate (see register CONFIG) to generate the
|
||
sample rate that controls sensor data output rate, FIFO sample rate.
|
||
NOTE: This register is only effective when Fchoice = 2’b11 (fchoice_b
|
||
register bits are 2’b00), and (0 < dlpf_cfg < 7), such that the average filter’s
|
||
output is selected (see chart below).
|
||
This is the update rate of sensor register.
|
||
SAMPLE_RATE= Internal_Sample_Rate / (1 + SMPLRT_DIV)
|
||
Data should be sampled at or above sample rate; SMPLRT_DIV is only used for1kHz internal sampling.
|
||
//rate:4~1000(Hz)
|
||
//设置mpu9250gyroscope的采样率(假定 Fs=1KHz)
|
||
//返回值:1,设置成功
|
||
// 0,设置失败
|
||
* */ //0x19
|
||
u8 mpu_set_rate(u16 rate)// 设置采样速率: 1000 / (1 + rate)
|
||
{
|
||
u8 data;
|
||
if (rate > 1000) {
|
||
rate = 1000;
|
||
}
|
||
if (rate < 4) {
|
||
rate = 4;
|
||
}
|
||
data = 1000 / rate - 1;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_SAMPLE_RATE_REG, &data, 1); //设置数字低通滤波器
|
||
/* return mpu_set_dlpf(rate/2); //自动设置LPF为采样率的一半 */
|
||
return mpu_set_dlpf(98);
|
||
}
|
||
|
||
bool mpu6500_set_sleep_enabled(u8 enable);// 唤醒MPU6500
|
||
//返回值:1,成功
|
||
// 0,错误代码
|
||
u8 mpu9250_init1(void *param)//bypass模式读取ak8963数据
|
||
{
|
||
u8 res = 0, temp_data = 0;
|
||
if (param == NULL) {
|
||
log_info("mpu9250 init fail(no param)\n");
|
||
return false;
|
||
}
|
||
mpu9250_iic_info = (mpu9250_param *)param;
|
||
|
||
temp_data = 0X80;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1); //复位MPU9250
|
||
mdelay(100); //延时100ms
|
||
temp_data = 0X00;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1); //唤醒MPU9250
|
||
mdelay(10); //延时
|
||
mpu6500_set_full_scale_gyro_range(MPU6500_GYRO_FS_2000);//陀螺仪传感器,±2000dps
|
||
mpu6500_set_full_scale_accel_range(0); //加速度传感器,±2g
|
||
mpu_set_rate(50); //设置采样率50Hz
|
||
mpu6500_set_sleep_enabled(false); // 唤醒MPU6500
|
||
temp_data = 0X00;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1); //关闭所有中断
|
||
temp_data = 0X00;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1); //I2C主模式关闭
|
||
temp_data = 0X00;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_FIFO_EN_REG, &temp_data, 1); //关闭FIFO
|
||
temp_data = 0X82;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1); //INT引脚低电平有效,开启bypass模式,可以直接读取磁力计
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, &temp_data, 1); //读取MPU6500的ID
|
||
if (temp_data == 0x71) { //器件ID正确
|
||
log_info("read mpu id:0x%x", temp_data);
|
||
temp_data = 0X01;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1); //设置CLKSEL,PLL X轴为参考
|
||
temp_data = 0X00;
|
||
mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT2_REG, &temp_data, 1); //加速度与陀螺仪都工作
|
||
mpu_set_rate(50); //设置采样率为50Hz
|
||
} else {
|
||
log_error("read mpu id(0x%x) fail!", temp_data);
|
||
return false;
|
||
}
|
||
|
||
res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_WHO_AM_I, &temp_data, 1); //读取AK8963 ID
|
||
if (temp_data == 0x48) {
|
||
log_info("read mag id:0x%x", temp_data);
|
||
temp_data = 0X11;
|
||
mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1); //设置AK8963为单次测量模式
|
||
} else {
|
||
log_error("read mag id(0x%x) fail!", temp_data);
|
||
/* return false; */
|
||
}
|
||
return true;
|
||
}
|
||
|
||
//得到温度值
|
||
//temp温度值
|
||
//返回值:2,成功
|
||
// 其他,错误代码
|
||
u8 mpu_get_temperature(float *temp)
|
||
{
|
||
u8 buf[2], res;
|
||
short raw;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_TEMP_OUTH_REG, buf, 2);
|
||
if (res == 2) {
|
||
raw = ((s16)buf[0] << 8) | buf[1];
|
||
*temp = 21 + (raw) / 333.87;
|
||
}
|
||
return res;
|
||
}
|
||
//得到陀螺仪值(原始值)
|
||
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
|
||
//返回值:6,成功
|
||
// 其他,错误代码
|
||
u8 mpu_get_gyroscope(short *gx, short *gy, short *gz)
|
||
{
|
||
u8 buf[6], res;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_GYRO_XOUTH_REG, buf, 6);
|
||
if (res == 6) {
|
||
*gx = ((u16)buf[0] << 8) | buf[1];
|
||
*gy = ((u16)buf[2] << 8) | buf[3];
|
||
*gz = ((u16)buf[4] << 8) | buf[5];
|
||
}
|
||
return res;
|
||
}
|
||
//得到加速度值(原始值)
|
||
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
|
||
//返回值:6,成功
|
||
// 其他,错误代码
|
||
u8 mpu_get_accelerometer(short *ax, short *ay, short *az)
|
||
{
|
||
u8 buf[6], res;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, buf, 6);
|
||
if (res == 6) {
|
||
*ax = ((u16)buf[0] << 8) | buf[1];
|
||
*ay = ((u16)buf[2] << 8) | buf[3];
|
||
*az = ((u16)buf[4] << 8) | buf[5];
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//得到磁力计值(原始值)
|
||
//mx,my,mz:磁力计x,y,z轴的原始读数(带符号)
|
||
//返回值:6,成功
|
||
// 其他,错误代码
|
||
u8 mpu_get_magnetometer(short *mx, short *my, short *mz)
|
||
{
|
||
u8 buf[6], res;
|
||
res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_XOUT_L, buf, 6);
|
||
if (res == 6) {
|
||
*mx = ((u16)buf[1] << 8) | buf[0];
|
||
*my = ((u16)buf[3] << 8) | buf[2];
|
||
*mz = ((u16)buf[5] << 8) | buf[4];
|
||
}
|
||
buf[0] = 0X11;
|
||
mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, buf, 1); //AK8963每次读完以后都需要重新设置为单次测量模式
|
||
return res;
|
||
}
|
||
|
||
//iic scl:<=400KHz
|
||
|
||
|
||
#if 0
|
||
|
||
static mpu9250_param mpu9250_iic_info_test1 = {
|
||
.iic_hdl = 0,
|
||
.iic_delay = 0, //字节间延时,单位us
|
||
};
|
||
|
||
void mpu9250_test1()
|
||
{
|
||
iic_init(mpu9250_iic_info_test1.iic_hdl);
|
||
gpio_set_direction(mpu9250_int_pin, 1);
|
||
gpio_set_die(mpu9250_int_pin, 1);
|
||
/* gpio_set_pull_up(mpu9250_int_pin, 1); */
|
||
/* gpio_set_pull_down(mpu9250_int_pin, 0); */
|
||
|
||
if (mpu9250_init1(&mpu9250_iic_info_test1)) {
|
||
log_info("mpu9250 Device init pass!\n");
|
||
|
||
while (1) {
|
||
mpu_get_temperature(&mpu9250_raw_data.temp_data);
|
||
mpu_get_gyroscope(&mpu9250_raw_data.gyro_data.x_data, &mpu9250_raw_data.gyro_data.y_data, &mpu9250_raw_data.gyro_data.z_data);
|
||
mpu_get_accelerometer(&mpu9250_raw_data.accel_data.x_data, &mpu9250_raw_data.accel_data.y_data, &mpu9250_raw_data.accel_data.z_data);
|
||
mpu_get_magnetometer(&mpu9250_raw_data.mag_data.x_data, &mpu9250_raw_data.mag_data.y_data, &mpu9250_raw_data.mag_data.z_data);
|
||
log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.accel_data.x_data, mpu9250_raw_data.accel_data.y_data, mpu9250_raw_data.accel_data.z_data);
|
||
log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.gyro_data.x_data, mpu9250_raw_data.gyro_data.y_data, mpu9250_raw_data.gyro_data.z_data);
|
||
log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.mag_data.x_data, mpu9250_raw_data.mag_data.y_data, mpu9250_raw_data.mag_data.z_data);
|
||
log_info("mpu9250_raw_data.temp_data:%d", (s16)mpu9250_raw_data.temp_data);
|
||
wdt_clear();
|
||
mdelay(10);
|
||
}
|
||
} else {
|
||
log_info("mpu9250 Device init fail!\n");
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
/******************************mpu6500 config****************************/
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_reset()// 复位MPU6500
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
temp_data |= BIT(7);
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_sleep_enabled(u8 enable)// 唤醒MPU6500
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(6);
|
||
} else {
|
||
temp_data &= ~ BIT(6);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/** Set clock source setting.
|
||
* An internal 8MHz oscillator, gyroscope based clock, or external sources c&= ~ * be selected as the MPU-60X0 clock source. When the internal 8 MHz oscillat|= * or an external source is chosen as the clock source, the MPU-60X0 can operate in low power modes with the gyroscopes disabled.
|
||
*
|
||
* Upon power up, the MPU-60X0 clock source defaults to the internal oscillator.
|
||
* However, it is highly recommended that the device be configured to use one of the gyroscopes (or an external clock source) as the clock reference f|= * improved stability. The clock source can be selected according to the following table:
|
||
* CLK_SEL | Clock Source
|
||
* --------+--------------------------------------
|
||
* 0 | Internal oscillat|= * 1 | PLL with X Gyro reference
|
||
* 2 | PLL with Y Gyro reference
|
||
* 3 | PLL with Z Gyro reference
|
||
* 4 | PLL with external 32.768kHz reference
|
||
* 5 | PLL with external 19.2MHz reference
|
||
* 6 | Reserved
|
||
* 7 | Stops the clock and keeps the timing generator in reset
|
||
* */
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_clocksource(u8 clocksource)// 设置X轴陀螺作为时钟
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
clocksource &= 0x07;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if ((temp_data & 0x07) != clocksource) {
|
||
temp_data &= ~0x07;
|
||
temp_data |= clocksource;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_temp_enabled(u8 enable)// 使能温度传感器
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data &= ~ BIT(3);
|
||
} else {
|
||
temp_data |= BIT(3);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_int_enabled(u8 int_data)// 关闭中断
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = int_data;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
|
||
return res;
|
||
}
|
||
//return:1:ok, 0:fail
|
||
//数据就绪中断使能
|
||
// This event occurs each time a write operation to all of the sensor registers has been completed. Will be set 0 for disabled, 1 for enabled.
|
||
bool mpu6500SetIntDataReadyEnabled(u8 enable)//0x38(bit0)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(0);
|
||
} else {
|
||
temp_data &= ~ BIT(0);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_iic_MST_enabled(u8 enable)//I2C主模式开关
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(5);
|
||
} else {
|
||
temp_data &= ~ BIT(5);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
// I2C_MST_EN (Register 106 bit[5]) has to be equal to 0
|
||
// 1:旁路模式,磁力计和其它连接到主IIC ; 0:主机模式
|
||
bool mpu6500_set_iic_bypass_enabled(u8 enable)//0x37(bit1)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
/* mpu6500_set_iic_MST_enabled(false)//I2C主模式关 */
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(1);
|
||
} else {
|
||
temp_data &= ~ BIT(1);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//默认0x00:rate4k
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500_set_accel_DLPF(u8 dlpf_data)// 设置加速计数字低通滤波
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
dlpf_data &= 0x07;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG_2, &temp_data, 1);
|
||
if (res == 1) {
|
||
if ((temp_data & 0x07) != dlpf_data) {
|
||
temp_data &= ~0x07;
|
||
temp_data |= dlpf_data;
|
||
temp_data |= BIT(3);//bit3=1,dlpf才才有效
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG_2, &temp_data, 1);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
|
||
//return:1:ok, 0:fail
|
||
// 从机读取速率: 100Hz = (1000Hz / (1 + slave_delay))
|
||
bool mpu6500SetSlave4MasterDelay(u8 slave_delay)//0x34(bit0~4)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
slave_delay &= 0x1f;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV4_CTRL_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if ((temp_data & 0x1f) != slave_delay) {
|
||
temp_data &= ~0x1f;
|
||
temp_data |= slave_delay;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV4_CTRL_REG, &temp_data, 1);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
//Set wait-for-external-sensor-data enabled value.
|
||
bool mpu6500SetWaitForExternalSensorEnabled(u8 enable)//0x24(bit6)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(6);
|
||
} else {
|
||
temp_data &= ~ BIT(6);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
//This bit controls the I2C Master’s transition from one slave read to the next
|
||
//slave read. If 0, there is a restart between reads. If 1, there is a stop between
|
||
//reads.
|
||
bool mpu6500SetSlaveReadWriteTransitionEnabled(u8 enable)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(4);
|
||
} else {
|
||
temp_data &= ~ BIT(4);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
//Set I2C master clock speed.
|
||
bool mpu6500SetMasterClockSpeed(u8 iic_master_rate)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
iic_master_rate &= 0x0f;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
temp_data &= ~ 0x0f;
|
||
temp_data |= iic_master_rate;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
//bit7: Set interrupt logic level mode.(0=active-high, 1=active-low)
|
||
//bit6: Set interrupt drive mode.(0=push-pull, 1=open-drain)
|
||
//bit5: Set interrupt latch mode.(0=50us-pulse, 1=latch-until-int-cleared)
|
||
//bit4: Set interrupt latch clear mode.(0=status-read-only, 1=any-register-read)
|
||
bool mpu6500SetInterruptMode(u8 int_cfg)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
int_cfg &= 0xf0;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
temp_data &= ~ 0xf0;
|
||
temp_data |= int_cfg;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500SetSlaveAddress(u8 num, u8 addr)
|
||
{
|
||
u8 temp_data = 0;
|
||
if (num > 3) {
|
||
return false;
|
||
}
|
||
temp_data = addr;
|
||
return mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_ADDR_REG + num * 3, &temp_data, 1);
|
||
}
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500SetSlaveRegister(u8 num, u8 reg)
|
||
{
|
||
u8 temp_data = 0;
|
||
if (num > 3) {
|
||
return false;
|
||
}
|
||
temp_data = reg;
|
||
return mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_REG + num * 3, &temp_data, 1);
|
||
}
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500SetSlaveDataLength(u8 num, u8 length)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
if (num > 3) {
|
||
return false;
|
||
}
|
||
length &= 0x0f;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
|
||
if (res == 1) {
|
||
temp_data &= ~ 0x0f;
|
||
temp_data |= length;
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500SetSlaveEnabled(u8 num, u8 enable)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
if (num > 3) {
|
||
return false;
|
||
}
|
||
enable &= 0x0f;
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(7);
|
||
} else {
|
||
temp_data &= ~ BIT(7);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool mpu6500SetSlaveDelayEnabled(u8 num, u8 enable)
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
if (num > 4) {
|
||
return false;
|
||
}
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_DELAY_REG, &temp_data, 1);
|
||
if (res == 1) {
|
||
if (enable) {
|
||
temp_data |= BIT(num);
|
||
} else {
|
||
temp_data &= ~ BIT(num);
|
||
}
|
||
res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_DELAY_REG, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/*设置传感器从模式读取*/
|
||
static void sensors_setup_slave_read(void)
|
||
{
|
||
mpu6500SetSlave4MasterDelay(9);// 从机读取速率: 100Hz = (1000Hz / (1 + 9))//zxb
|
||
|
||
mpu6500_set_iic_bypass_enabled(false); //主机模式
|
||
mpu6500SetWaitForExternalSensorEnabled(true);
|
||
mpu6500SetInterruptMode(0x90);//中断低电平有效 推挽输出 中断锁存模式(0=50us-pulse) 中断清除模式(1=any-register-read)
|
||
mpu6500SetSlaveReadWriteTransitionEnabled(false); // 关闭从机间读写结束位的传输
|
||
mpu6500SetMasterClockSpeed(13); // 设置i2c速度400kHz
|
||
|
||
#if MAG_AK8963_ENABLE
|
||
// 设置MPU6500主机要读取的寄存器
|
||
mpu6500SetSlaveAddress(0, 0x80 | MAG_IIC_ADDRESS); // 设置磁力计为0号从机
|
||
mpu6500SetSlaveRegister(0, MAG_STATE_1); // 从机0需要读取的寄存器
|
||
mpu6500SetSlaveDataLength(0, SENSORS_MAG_BUFF_LEN); // 读取8个字节(ST1, x, y, z heading, ST2 (overflow check))
|
||
mpu6500SetSlaveDelayEnabled(0, true);
|
||
mpu6500SetSlaveEnabled(0, true);
|
||
#endif
|
||
mpu6500_set_iic_MST_enabled(true); //使能mpu6500主机模式
|
||
mpu6500SetIntDataReadyEnabled(true); //数据就绪中断使能
|
||
}
|
||
|
||
|
||
|
||
/******************************ak8963 config****************************/
|
||
//return:1:ok, 0:fail
|
||
bool ak8963_check_connection()
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_WHO_AM_I, &temp_data, 1); //读取AK8963 ID
|
||
if (temp_data == 0x48) {
|
||
log_info("read mag id:0x%x ok!", temp_data);
|
||
} else {
|
||
log_error("read mag id(0x%x) fail!", temp_data);
|
||
return false;
|
||
}
|
||
return true;
|
||
|
||
}
|
||
/* bool ak8963_check_connection() */
|
||
/* { */
|
||
/* u8 res=0; */
|
||
/* u8 temp_data=0; */
|
||
/* while(1){ */
|
||
/* if(res==0xfe)return false; */
|
||
/* mpu_i2c_buf_read(res,MAG_WHO_AM_I,&temp_data,1); //读取AK8963 ID */
|
||
/* if(temp_data==0x48) */
|
||
/* { */
|
||
/* log_info("read mag id:0x%x ok!",temp_data); */
|
||
/* }else { */
|
||
/* log_error("read mag id(0x%x) fail!",temp_data); */
|
||
/* res +=2; */
|
||
/* temp_data=0; */
|
||
/* #<{(| return false; |)}># */
|
||
/* } */
|
||
/* mdelay(10); */
|
||
/* } */
|
||
/* return true; */
|
||
/* */
|
||
/* } */
|
||
|
||
//return:1:ok, 0:fail
|
||
bool ak8963_set_mode(u8 data)
|
||
{
|
||
u8 temp_data = data;
|
||
return mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
|
||
}
|
||
|
||
//return:1:ok, 0:fail
|
||
bool ak8963Reset()
|
||
{
|
||
u8 res = 0;
|
||
u8 temp_data = 0;
|
||
res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
|
||
if (res == 1) {
|
||
temp_data &= ~0x0f;
|
||
res = mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
|
||
bool mpu9250_init2(void *param)//主模式获取ak8963
|
||
{
|
||
u8 res = 0, temp_data = 0;
|
||
if (param == NULL) {
|
||
log_info("mpu9250 init fail(no param)\n");
|
||
return false;
|
||
}
|
||
mpu9250_iic_info = (mpu9250_param *)param;
|
||
|
||
mdelay(10);
|
||
mpu6500_reset(); // 复位MPU6500
|
||
mdelay(20);
|
||
res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, &temp_data, 1); //读取MPU6500的ID
|
||
if (temp_data == 0x71) { //器件ID正确
|
||
log_info("read mpu id:0x%x ok!", temp_data);
|
||
} else {
|
||
log_error("read mpu id(0x%x) fail!", temp_data);
|
||
return false;
|
||
}
|
||
mpu6500_set_sleep_enabled(false); // 唤醒MPU6500
|
||
mdelay(10);
|
||
mpu6500_set_clocksource(MPU6500_CLOCK_PLL_XGYRO);// 设置X轴陀螺作为时钟
|
||
mdelay(10);// 延时等待时钟稳定
|
||
mpu6500_set_temp_enabled(true);// 使能温度传感器
|
||
mpu6500_set_int_enabled(0x00);// 关闭中断
|
||
|
||
mpu6500_set_iic_MST_enabled(false);//I2C主模式关//zxb
|
||
mpu6500_set_iic_bypass_enabled(true);// 旁路模式,磁力计和气压连接到主IICnot sure//zxb
|
||
|
||
mpu6500_set_full_scale_gyro_range(MPU6500_GYRO_FS_2000); // 设置陀螺量程
|
||
mpu6500_set_full_scale_accel_range(MPU6500_ACCEL_FS_16);// 设置加速计量程
|
||
/* mpu6500_set_accel_DLPF(MPU6500_ACCEL_DLPF_BW_41); // 设置加速计数字低通滤波 */
|
||
|
||
mpu_set_rate(MPU6500_DATA_SAMPLE_RATE);//设置采样速率: 1000Hz(max)//zxb
|
||
|
||
#if MAG_AK8963_ENABLE
|
||
if (ak8963_check_connection() == true) {
|
||
ak8963_set_mode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz
|
||
log_info("AK8963 I2C connection [OK].\n");
|
||
} else {
|
||
log_error("AK8963 I2C connection [FAIL].\n");
|
||
return false;
|
||
}
|
||
#endif
|
||
|
||
//外部中断
|
||
mdelay(150);
|
||
sensors_setup_slave_read();
|
||
return true;
|
||
}
|
||
|
||
|
||
static u8 init_flag = 0;
|
||
static u8 imu_busy = 0;
|
||
static mpu9250_param mpu9250_info_data;
|
||
volatile u8 mpu9250_int_flag = 0;
|
||
#if MAG_AK8963_ENABLE
|
||
#define SENSORS_MPU_BUFF_LEN (SENSORS_MPU6500_BUFF_LEN + SENSORS_MAG_BUFF_LEN)
|
||
#else
|
||
#define SENSORS_MPU_BUFF_LEN SENSORS_MPU6500_BUFF_LEN
|
||
#endif
|
||
u8 read_mpu_buf[SENSORS_MPU_BUFF_LEN];
|
||
|
||
void mpu9250_int_callback()
|
||
{
|
||
if (init_flag == 0) {
|
||
log_error("mpu9250 init fail!");
|
||
return;
|
||
}
|
||
if (imu_busy) {
|
||
log_error("mpu9250 busy!");
|
||
return;
|
||
}
|
||
imu_busy = 1;
|
||
|
||
mpu9250_int_flag = 1;
|
||
mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, read_mpu_buf, SENSORS_MPU_BUFF_LEN);
|
||
#if 1
|
||
s16 x = 0, y = 0, z = 0;
|
||
if (mpu9250_int_flag) {/*{{{*/
|
||
x = (((s16) read_mpu_buf[0]) << 8) | read_mpu_buf[1];
|
||
y = ((((s16) read_mpu_buf[2]) << 8) | read_mpu_buf[3]);
|
||
z = (((s16) read_mpu_buf[4]) << 8) | read_mpu_buf[5];
|
||
log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
x = (((s16) read_mpu_buf[8]) << 8) | read_mpu_buf[9];
|
||
y = (((s16) read_mpu_buf[10]) << 8) | read_mpu_buf[11];
|
||
z = (((s16) read_mpu_buf[12]) << 8) | read_mpu_buf[13];
|
||
log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
#if MAG_AK8963_ENABLE
|
||
if (read_mpu_buf[0 + SENSORS_MPU6500_BUFF_LEN]&BIT(0)) {
|
||
x = (((s16) read_mpu_buf[2 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[1 + SENSORS_MPU6500_BUFF_LEN ];
|
||
y = (((s16) read_mpu_buf[4 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[3 + SENSORS_MPU6500_BUFF_LEN ];
|
||
z = (((s16) read_mpu_buf[6 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[5 + SENSORS_MPU6500_BUFF_LEN ];
|
||
log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
}
|
||
#endif
|
||
x = (((s16) read_mpu_buf[6]) << 8) | read_mpu_buf[7];
|
||
x = 21 + (s16)((float)(x) / 333.87);
|
||
log_info("mpu9250_raw_data.temp_data:%d", x);
|
||
|
||
mpu9250_int_flag = 0;
|
||
}/*}}}*/
|
||
#endif
|
||
imu_busy = 0;
|
||
}
|
||
|
||
s8 mpu9250_dev_init(void *arg)
|
||
{
|
||
if (arg == NULL) {
|
||
log_error("mpu9250 init fail(no arg)\n");
|
||
return -1;
|
||
}
|
||
#if 1//MPU9250_USER_INTERFACE_I2C
|
||
mpu9250_info_data.iic_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl;
|
||
mpu9250_info_data.iic_delay = ((struct imusensor_platform_data *)arg)->peripheral_param0; //这个延时并非影响iic的时钟频率,而是2Byte数据之间的延时
|
||
// u8 iic_clk; //iic_clk: <=400kHz
|
||
#else
|
||
mpu9250_info_data.spi_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl, //SPIx (role:master)
|
||
mpu9250_info_data.spi_cs_pin = ((struct imusensor_platform_data *)arg)->peripheral_param0; //IO_PORTA_05
|
||
mpu9250_info_data.spi_work_mode = ((struct imusensor_platform_data *)arg)->peripheral_param1; //1:3wire(SPI_MODE_UNIDIR_1BIT) or 0:4wire(SPI_MODE_BIDIR_1BIT) (与spi结构体一样)
|
||
// u8 port; //SPIx group:A,B,C,D (spi结构体)
|
||
// U8 spi_clk; //spi_clk: <=1MHz (spi结构体)
|
||
#endif
|
||
iic_init(mpu9250_info_data.iic_hdl);
|
||
//int module io init
|
||
mpu9250_int_pin = ((struct imusensor_platform_data *)arg)->imu_sensor_int_io;
|
||
gpio_set_direction(mpu9250_int_pin, 1);
|
||
gpio_set_die(mpu9250_int_pin, 1);
|
||
/* gpio_set_pull_up(mpu9250_int_pin, 1); */
|
||
/* gpio_set_pull_down(mpu9250_int_pin, 0); */
|
||
|
||
if (imu_busy) {
|
||
log_error("mpu9250 busy!");
|
||
return -1;
|
||
}
|
||
imu_busy = 1;
|
||
|
||
if (mpu9250_init2(&mpu9250_info_data)) {
|
||
log_info("mpu9250 Device init success!\n");
|
||
log_info("int mode en!");
|
||
/* port_wkup_enable(mpu9250_int_pin, 1, mpu9250_int_callback); //PA08-IO中断,1:下降沿触发,回调函数mpu9250_int_callback*/
|
||
#ifdef CONFIG_CPU_BR23
|
||
io_ext_interrupt_init(mpu9250_int_pin, 1, mpu9250_int_callback);
|
||
#elif defined(CONFIG_CPU_BR28)
|
||
// br28外部中断回调函数,按照现在的外部中断注册方式
|
||
// io配置在板级,定义在板级头文件,这里只是注册回调函数
|
||
/* port_edge_wkup_set_callback_by_index(3, mpu9250_int_callback); // 序号需要和板级配置中的wk_param对应上 */
|
||
port_edge_wkup_set_callback(mpu9250_int_callback);
|
||
#elif defined(CONFIG_CPU_BR27)
|
||
port_edge_wkup_set_callback(mpu9250_int_callback);
|
||
#endif
|
||
init_flag = 1;
|
||
imu_busy = 0;
|
||
return 0;
|
||
} else {
|
||
log_info("mpu9250 Device init fail!\n");
|
||
imu_busy = 0;
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
|
||
int mpu9250_dev_ctl(u8 cmd, void *arg);
|
||
REGISTER_IMU_SENSOR(mpu9250_sensor) = {
|
||
.logo = "mpu9250",
|
||
.imu_sensor_init = mpu9250_dev_init,
|
||
.imu_sensor_check = NULL,
|
||
.imu_sensor_ctl = mpu9250_dev_ctl,
|
||
};
|
||
|
||
int mpu9250_dev_ctl(u8 cmd, void *arg)
|
||
{
|
||
int ret = -1;
|
||
if (init_flag == 0) {
|
||
log_error("mpu9250 init fail!");
|
||
return ret;//0:ok,,<0:err
|
||
}
|
||
if (imu_busy) {
|
||
log_error("mpu9250 busy!");
|
||
return ret;//0:ok,,<0:err
|
||
}
|
||
imu_busy = 1;
|
||
|
||
switch (cmd) {
|
||
case IMU_GET_SENSOR_NAME:
|
||
memcpy((u8 *)arg, &(mpu9250_sensor.logo), 20);
|
||
break;
|
||
case IMU_SENSOR_ENABLE:
|
||
/* cbuf_init(&hrsensor_cbuf, hrsensorcbuf, 24 * sizeof(int)); */
|
||
mpu9250_init2(&mpu9250_info_data);
|
||
break;
|
||
case IMU_SENSOR_DISABLE:
|
||
/* cbuf_clear(&hrsensor_cbuf); */
|
||
break;
|
||
case IMU_SENSOR_RESET:
|
||
break;
|
||
case IMU_SENSOR_SLEEP:
|
||
break;
|
||
case IMU_SENSOR_WAKEUP:
|
||
break;
|
||
case IMU_SENSOR_INT_DET://传感器中断状态检查
|
||
break;
|
||
case IMU_SENSOR_DATA_READY://传感器数据准备就绪待读
|
||
mpu9250_int_callback();
|
||
break;
|
||
case IMU_SENSOR_CHECK_DATA://检查传感器缓存buf是否存满
|
||
break;
|
||
case IMU_SENSOR_READ_DATA://默认读传感器所有数据
|
||
break;
|
||
case IMU_GET_ACCEL_DATA://加速度数据
|
||
break;
|
||
case IMU_GET_GYRO_DATA://陀螺仪数据
|
||
break;
|
||
case IMU_GET_MAG_DATA://磁力计数据
|
||
break;
|
||
case IMU_SENSOR_SEARCH://检查传感器id
|
||
mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, (u8 *)arg, 1); //读取MPU9250的ID
|
||
if (*(u8 *)arg == 0x71) {
|
||
ret = 0;
|
||
log_info("mpu9250 online!\n");
|
||
} else {
|
||
log_error("mpu9250 offline!\n");
|
||
}
|
||
break;
|
||
default:
|
||
log_error("--cmd err!\n");
|
||
break;
|
||
}
|
||
imu_busy = 0;
|
||
return ret;
|
||
}
|
||
|
||
|
||
/***************************mpu9250 test*******************************/
|
||
#if 0
|
||
|
||
static mpu9250_param mpu9250_iic_info_test2 = {
|
||
.iic_hdl = 1,
|
||
.iic_delay = 0, //iic字节间间隔,单位us
|
||
};
|
||
|
||
void port_wkup_irq_cbfun_test(u8 index, u8 gpio)
|
||
{
|
||
mpu9250_int_flag = 1;
|
||
mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, read_mpu_buf, SENSORS_MPU_BUFF_LEN);
|
||
}
|
||
void read_mpu_all_reg();
|
||
void mpu9250_test2()
|
||
{
|
||
s16 x = 0, y = 0, z = 0;
|
||
iic_init(mpu9250_iic_info_test2.iic_hdl);
|
||
if (mpu9250_init2(&mpu9250_iic_info_test2)) {
|
||
log_info("mpu9250 Device init pass!\n");
|
||
log_info("-------------------port wkup isr---------------------------");
|
||
/* port_wkup_enable(mpu9250_int_pin, 1, port_wkup_irq_cbfun_test); //PA08-IO中断,1:下降沿触发,回调函数port_wkup_irq_cbfun_test */
|
||
#ifdef CONFIG_CPU_BR23
|
||
io_ext_interrupt_init(mpu9250_int_pin, 1, port_wkup_irq_cbfun_test);
|
||
#elif defined(CONFIG_CPU_BR28)
|
||
// br28外部中断回调函数,按照现在的外部中断注册方式
|
||
// io配置在板级,定义在板级头文件,这里只是注册回调函数
|
||
/* port_edge_wkup_set_callback_by_index(3, port_wkup_irq_cbfun_test); // 序号需要和板级配置中的wk_param对应上 */
|
||
port_edge_wkup_set_callback(port_wkup_irq_cbfun_test);
|
||
#elif defined(CONFIG_CPU_BR27)
|
||
port_edge_wkup_set_callback(port_wkup_irq_cbfun_test);
|
||
#endif
|
||
|
||
/* read_mpu_all_reg(); */
|
||
while (1) {
|
||
if (mpu9250_int_flag) {
|
||
x = (((s16) read_mpu_buf[0]) << 8) | read_mpu_buf[1];
|
||
y = ((((s16) read_mpu_buf[2]) << 8) | read_mpu_buf[3]);
|
||
z = (((s16) read_mpu_buf[4]) << 8) | read_mpu_buf[5];
|
||
log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
x = (((s16) read_mpu_buf[8]) << 8) | read_mpu_buf[9];
|
||
y = (((s16) read_mpu_buf[10]) << 8) | read_mpu_buf[11];
|
||
z = (((s16) read_mpu_buf[12]) << 8) | read_mpu_buf[13];
|
||
log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
#if MAG_AK8963_ENABLE
|
||
if (read_mpu_buf[0 + SENSORS_MPU6500_BUFF_LEN]&BIT(0)) {
|
||
x = (((s16) read_mpu_buf[2 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[1 + SENSORS_MPU6500_BUFF_LEN ];
|
||
y = (((s16) read_mpu_buf[4 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[3 + SENSORS_MPU6500_BUFF_LEN ];
|
||
z = (((s16) read_mpu_buf[6 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[5 + SENSORS_MPU6500_BUFF_LEN ];
|
||
log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", x, y, z);
|
||
}
|
||
#endif
|
||
x = (((s16) read_mpu_buf[6]) << 8) | read_mpu_buf[7];
|
||
x = 21 + (s16)((float)(x) / 333.87);
|
||
log_info("mpu9250_raw_data.temp_data:%d", x);
|
||
|
||
mpu9250_int_flag = 0;
|
||
}
|
||
wdt_clear();
|
||
mdelay(10);
|
||
}
|
||
} else {
|
||
log_info("mpu9250 Device init fail!\n");
|
||
}
|
||
}
|
||
|
||
void read_mpu_all_reg()
|
||
{
|
||
u8 addr_tab[62] = {0, 1, 2, 13, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 114, 115, 116, 117, 119, 120, 122, 123, 125, 126};
|
||
u8 ii = 0;
|
||
u8 temp1_data[62];
|
||
for (ii = 0; ii < 62; ii++) {
|
||
mpu_i2c_buf_read(MPU9250_ADDRESS_W, addr_tab[ii], &temp1_data[ii], 1);
|
||
}
|
||
log_info("addr:%d", addr_tab[61]);
|
||
log_info_hexdump(temp1_data, 62);
|
||
log_info("id:0x%x", temp1_data[55]);
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|