当前位置:   article > 正文

STM32MPU6050角度的读取(STM32驱动MPU6050)_lsb2g 16384

lsb2g 16384

注:文末附STM32驱动MPU6050代码工程链接,需要的读者请自取。

一、MPU6050介绍

MPU6050是一款集成了三轴陀螺仪和三轴加速度计的传感器芯片,由英国飞利浦半导体(现为恩智浦半导体)公司生产。它通过电子接口(如I2C或SPI)与微控制器进行通信,可用于测量物体的加速度和角速度,广泛应用于无人机、机器人、游戏手柄、智能手机和其他电子设备中。

MPU6050内置的三轴陀螺仪用于测量物体的角速度或转动速率,而三轴加速度计则用于测量物体的加速度或静止状态下的重力加速度。通过同时使用这两种传感器,可以实现对物体姿态的精确测量,例如倾斜角度、旋转速度等。

除了基本的数据输出功能,MPU6050还具有一些高级功能,比如嵌入式温度传感器、数字运动处理器(DMP)等。DMP可以处理传感器数据并通过内部FIFO缓冲区提供四元数等复杂的姿态解算数据,从而减轻主控制器的负担,简化软件开发流程。

总的来说,MPU6050是一款功能强大、性能稳定的传感器模块,适用于许多需要姿态检测和运动跟踪的应用场景。

二、加速度计 

加速度计顾名思义,就是测量加速度的.那么,我们如何认识这个加速度呢?在此用一个盒子形
状的立方体来做模型,认识加速度,如下,盒子内的图像。

如果我们把盒子形状的立方体 放在一个没引力场的地方,球会保持在盒子的中间.你可以想
象,这个盒子是在外太空,远离任何天体,很难找到这样的地方,就想象飞船轨道围绕地球
飞,一切都是在失重状态下。那么六个壁面感受到的压力都是0.
如果我们突然将立方体向左侧移动(我们加快加速,1G =9.8米/ S ^ 2),皮球打在了
墙上X-。然后,我们测量球适用于在X轴上的壁和输出-1g值的压力。如下图

 

 请注意,加速度计反应的加速向量与当前的受力方向是相反的.如上图所示,受力方向向
左,但是加速度的向量方向为右.

如果我们把这个小盒子拿来放在地球上,那么小球会落在Z-壁面上,并会为1G的底壁施加一
个力,在下面的图片所示:

 

 在这种情况下,框不动,但我们仍然可以得到Z轴的读数-1G。球在墙壁上的压力造成的引
力场。
到目前为止,我们已经分析了单个轴加速度计的输出,这时你会得到一个单轴加速度计。
三轴加速度计的真正价值,即是他们可以同时检测到所有三个轴的惯性力。让我们回到我
们的盒模型,并让旋转45度在右边的框中。球会触及两面墙:Z和X-在下面的图片所示:

 

x 和 z 轴受到值的0.71是不是任意的? 它们实际上是一个近似SQRT(1/2).要知道当盒子
只受重力场时,x^2+Y^2+z^2 =1g 这将变得更加清晰,为大家介绍一下下一个样
子的加速度计。
在之前的盒子模型中,我们有固定的引力场及旋转。在刚刚说明的两个例子中,我们分析
了2个不同的输出框位置,而力矢量保持不变。这更有利于了解加速度计如何与外部交互,
并显示当前读数。 

 ​​​​​​​

 请看一下上面的模型,这是一个新的模型代替刚刚的盒子立方体。试想一下,在新模型中
的每个轴是垂直于盒子的壁面。向量R是加速度计测量(从上面的例子或这两者的组合,它
可以是引力场或惯性力)的力矢量。接收时,Ry,R Z与上的X,Y,Z轴的R矢量投影。请注
意下面的关系式:
R ^ 2 = RX ^ 2 + RY ^ 2 + RZ ^ 2 (公式1)
请记住,早一点我告诉你,SQRT(1/2)的值不是随机的〜0.71。如果您将上述公式中,回
顾我们的引力场为1 g后,我们可以验证:
1 ^ 2 =(-SQRT(1/2))^ 2 + 0 ^ 2 +(-SQRT(1/2))^ 2
简单地通过代以R = 1时,接收= SQRT(1/2)时,Ry = 0,RZ = SQRT(1/2)在方程
经过以上的理论分析我们越来越接近现实生活中的加速度计。
值RX,RY,RZ实际上是呈线性关系对应到真正的现实加速度计的x轴 y轴 z轴.
在此提出一个问题, 加速度计如何将这些信息告诉我们?
目前市面上的加速度计从输出上区分为两种,一种是数字的,另一种是模拟
的.miniAHRS 使用的是MPU6050三轴加速度计,是I2C接口的数字传感器.通过特定的命令
可以配置加速度的量程,并将内部ADC的转换结果读出来.
现在,我们有我们的加速度计的读数,以LSB为单位的,它仍然不是g(9.8米/秒^
2),需要最后的转换,我们要知道加速度计灵敏度,通常表示为LSB /g。比方说当我们
选择2g的量程时,对应的灵敏度= 16384 LSB/ G 。为了得到最终的力值,单位为g,我们
用下面的公式:
RX = ADCRx /灵敏度
也就是说 当x轴的计数为ADCRx 时,那么对应的加速度值就是 (ADCRx/16384)g.回到加速度向量模型,将相关角度符号补上,如下图

方向余弦

 我们感兴趣的是向量R 和 X、Y、Z轴之间的角度,将它们定义为 Axr Ayr Azr. 可以看到
由R 和Rx 组成的直角三角形:
COS(Axr)= RX / R 依此类推:
COS(Ayr)= RY / R
COS(Azr)= RZ / R
可以得到 R = SQRT(RX ^ 2 + RY ^ 2 + RZ ^ 2)
我们发现 当使用 arccos() 反余弦 :
Axr = arccos(RX / R)
Ayr = arccos(RY / R)
Azr = arccos(RZ / R)
已以通过很多公式解释加速度计模型。我们也会很快解释陀螺仪 以及如何用加速度计和陀
螺仪的数据进行整合,以得到更精确的角度估计。
在这之前 我们先来看看更有用的公式:
cosX = cos(Axr) = Rx / R
cosY = cos(Ayr) = Ry / R
cosZ = cos(Azr) = Rz / R
这三个公式通常被称为方向余弦。你可以轻松地验证:
SQRT(cosX ^ 2 + COSY ^ 2 + cosZ ^ 2)= 1
这个属性可以避免监视R矢量的模(长度)。很多时候,我们只对惯性矢量方向感兴趣,对
矢量进行规范化对简化程序运算很有意义。

 重力向量

我们暂且从理论分析回到现实的传感器输出中,当水平放置MPU6050,只有Z轴感受到重力向
量,它将输出1g。对应的ADC值就是16384 (2g的量程)。此时,R就是重力向量,
Rx=0. Ry=0. Rz = R =1g.
满足
R ^ 2 = RX ^ 2 + RY ^ 2 + RZ ^ 2 得到重力向量与各个轴的夹角
Axr = arccos(RX / R) = 90度
Ayr = arccos(RY / R) = 90度
Azr = arccos(RZ / R) = 0 度

加速度计的标定

当MPU6050水平放置时,理论上Z轴感受到重力 将读出16384。同时X 轴和Y轴的读数将是0.
可实际并不是这样的。这是由于每个芯片在制作时都不一样,数据手册上的都是理论的
值,真正的芯片在水平时Z轴可能并不是16384.我们需要找到当各个轴在0g重力时的计数,
1g时的读数,以及-1g时的读数,得到一个补偿值,在每次读取ADC结果后都进行补偿。这
个过程我们称之为标定。用数学公式表示为:
ADCx = K*Gx + Offset
ADCx 传感器输出

Gx真实的加速值
Offset加速度为0g时传感器的输出
K标度因数

三、陀螺仪 

陀螺仪是测试角速度的传感器,也有人把角速度说成角速率,说的是一样的物理量。拿电
机做例子,当我们说一个电机10转每秒。一转是360度,那么它的主轴在一秒内转过3600
度。也就是说这个电机在转动时的角速度是3600dps.dps 就是dergee per second 度每秒
(或者写成 deg/s).
MPU6050 集成了三轴的陀螺仪.角速度全格感测范围为±250、±500、±1000与±
2000°/sec (dps).当选择量程为±250dps的时候,将会得到分辩率为131LSB/(º/s).也就
是当载体在X+轴转动1dps时,ADC将输出131. ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

 回到加速度向量模型,将相关角度符号补上,如下图

 

 陀螺仪测量什么?

 MPU6050带有三个陀螺仪,每个陀螺仪各自负责检测相应轴的转动速度,也就是检测围绕
各个轴转动的速度。像三轴的陀螺仪将同时检测 X Y Z轴的旋转。
由上面这个模型图,首先我们定义:
Rxz - 是R向量在XZ平面上的投影
Ryz - 是R向量在XY平面上的投影
Rxz和Rz所形成的直角三角形,利用勾股定理,我们得到:
Rxz ^ 2 = RX ^ 2 + RZ ^ 2,和同样:
Ryz ^ 2 = RY ^ 2 + RZ ^ 2
还要注意的是:
R ^ 2 = RXZ ^ 2 + Ry^ 2,这可以来自从公式1和上面的等式,或它可以是来自于由R和Ryz
R ^ 2 = Ryz ^ 2 + Rx^ 2 形成的直角三角
我们不会在本文中使用这些公式,只是让读者认识到所有值之间的关系。
同时我们将定义Z轴和Rxz 、RyZ之间的夹角。
Axz - Rxz和Z轴间的夹角
Ayz - Ryz和Z轴间的夹角
现在看看,从这个模型中,陀螺仪测量什么?
上述的说明,已经知道陀螺仪测量角度的变化率.为了解释这一点,让我们假设,我们已经
测量围绕Y轴的旋转角(这将是Axz角)在时刻t0,我们将其定义为Axz0,接下来,我们测
量这个角度是在稍后的时间t1是Axz1。变化率将被计算如下:
RateAxz =(Axz1 - Axz0)/(t1 - t0)
如果Axz单位是度,并以秒为时间单位,那么RateAxz将以deg / s表示。
MPU6050并不会以 deg / s 单位输出,我们需要在读完后进行转换。先来看看各个量程对
应的灵敏度。

 从ADC值到 dps

 通过I2C接口读出来的转换结果ADC值,并不是以度每秒为单位。一般按以下公式进行转
换:
Anglerate = ADCrate /灵敏度
以量程为±1000º/s为例,说明如何转换。假设读取x轴的ADC值为200,从上表中得知在
±1000º/s下的灵敏度为32.8LSB/(º/s) 。根据上面的公式:
Anglerate = 200/32.8 = 6.09756º/s
这就是说,MPU6050检测到模块正在以约6度每秒的速度绕X轴(或者叫在YZ平面上)旋转.
ADC值并不都是正的,请注意,当出现负数时,意味着该设备从现有的正方向相反的方向旋转.

 四、STM32驱动MPU6050

1、核心代码

(1)IIC通信

  1. #include "mpuiic.h"
  2. #include "delay.h"
  3. /**************************************************************************
  4. 作 者 :小小扫地僧
  5. **************************************************************************/
  6. //MPU IIC 延时函数
  7. void MPU_IIC_Delay(void)
  8. {
  9. delay_us(2);
  10. }
  11. //初始化IIC
  12. void MPU_IIC_Init(void)
  13. {
  14. GPIO_InitTypeDef GPIO_InitStructure;
  15. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //端口配置
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  18. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M
  19. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
  20. }
  21. //产生IIC起始信号
  22. void MPU_IIC_Start(void)
  23. {
  24. MPU_SDA_OUT(); //sda线输出
  25. MPU_IIC_SDA=1;
  26. MPU_IIC_SCL=1;
  27. MPU_IIC_Delay();
  28. MPU_IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  29. MPU_IIC_Delay();
  30. MPU_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  31. }
  32. //产生IIC停止信号
  33. void MPU_IIC_Stop(void)
  34. {
  35. MPU_SDA_OUT();//sda线输出
  36. MPU_IIC_SCL=0;
  37. MPU_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  38. MPU_IIC_Delay();
  39. MPU_IIC_SCL=1;
  40. MPU_IIC_SDA=1;//发送I2C总线结束信号
  41. MPU_IIC_Delay();
  42. }
  43. //等待应答信号到来
  44. //返回值:1,接收应答失败
  45. // 0,接收应答成功
  46. u8 MPU_IIC_Wait_Ack(void)
  47. {
  48. u8 ucErrTime=0;
  49. MPU_SDA_IN(); //SDA设置为输入
  50. MPU_IIC_SDA=1;MPU_IIC_Delay();
  51. MPU_IIC_SCL=1;MPU_IIC_Delay();
  52. while(MPU_READ_SDA)
  53. {
  54. ucErrTime++;
  55. if(ucErrTime>250)
  56. {
  57. MPU_IIC_Stop();
  58. return 1;
  59. }
  60. }
  61. MPU_IIC_SCL=0;//时钟输出0
  62. return 0;
  63. }
  64. //产生ACK应答
  65. void MPU_IIC_Ack(void)
  66. {
  67. MPU_IIC_SCL=0;
  68. MPU_SDA_OUT();
  69. MPU_IIC_SDA=0;
  70. MPU_IIC_Delay();
  71. MPU_IIC_SCL=1;
  72. MPU_IIC_Delay();
  73. MPU_IIC_SCL=0;
  74. }
  75. //不产生ACK应答
  76. void MPU_IIC_NAck(void)
  77. {
  78. MPU_IIC_SCL=0;
  79. MPU_SDA_OUT();
  80. MPU_IIC_SDA=1;
  81. MPU_IIC_Delay();
  82. MPU_IIC_SCL=1;
  83. MPU_IIC_Delay();
  84. MPU_IIC_SCL=0;
  85. }
  86. //IIC发送一个字节
  87. //返回从机有无应答
  88. //1,有应答
  89. //0,无应答
  90. void MPU_IIC_Send_Byte(u8 txd)
  91. {
  92. u8 t;
  93. MPU_SDA_OUT();
  94. MPU_IIC_SCL=0;//拉低时钟开始数据传输
  95. for(t=0;t<8;t++)
  96. {
  97. MPU_IIC_SDA=(txd&0x80)>>7;
  98. txd<<=1;
  99. MPU_IIC_SCL=1;
  100. MPU_IIC_Delay();
  101. MPU_IIC_SCL=0;
  102. MPU_IIC_Delay();
  103. }
  104. }
  105. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  106. u8 MPU_IIC_Read_Byte(unsigned char ack)
  107. {
  108. unsigned char i,receive=0;
  109. MPU_SDA_IN();//SDA设置为输入
  110. for(i=0;i<8;i++ )
  111. {
  112. MPU_IIC_SCL=0;
  113. MPU_IIC_Delay();
  114. MPU_IIC_SCL=1;
  115. receive<<=1;
  116. if(MPU_READ_SDA)receive++;
  117. MPU_IIC_Delay();
  118. }
  119. if (!ack)
  120. MPU_IIC_NAck();//发送nACK
  121. else
  122. MPU_IIC_Ack(); //发送ACK
  123. return receive;
  124. }

(2)IIC通信头文件

  1. #ifndef __MPUIIC_H
  2. #define __MPUIIC_H
  3. #include "sys.h"
  4. //IO方向设置
  5. #define MPU_SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(uint32_t)8<<28;}
  6. #define MPU_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(uint32_t)3<<28;}
  7. //IO操作函数
  8. #define MPU_IIC_SCL PBout(6) //SCL
  9. #define MPU_IIC_SDA PBout(7) //SDA
  10. #define MPU_READ_SDA PBin(7) //SDA
  11. //IIC所有操作函数
  12. void MPU_IIC_Delay(void); //MPU IIC延时函数
  13. void MPU_IIC_Init(void); //初始化IIC的IO口
  14. void MPU_IIC_Start(void); //发送IIC开始信号
  15. void MPU_IIC_Stop(void); //发送IIC停止信号
  16. void MPU_IIC_Send_Byte(u8 txd); //IIC发送一个字节
  17. u8 MPU_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  18. u8 MPU_IIC_Wait_Ack(void); //IIC等待ACK信号
  19. void MPU_IIC_Ack(void); //IIC发送ACK信号
  20. void MPU_IIC_NAck(void); //IIC不发送ACK信号
  21. void IMPU_IC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
  22. u8 MPU_IIC_Read_One_Byte(u8 daddr,u8 addr);
  23. #endif

 (3)mpu6050.c

  1. #include "mpu6050.h"
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "usart.h"
  5. /**************************************************************************
  6. 作 者 :小小扫地僧
  7. **************************************************************************/
  8. //初始化MPU6050
  9. //返回值:0,成功
  10. //其他,错误代码
  11. u8 MPU_Init(void)
  12. {
  13. u8 res;
  14. MPU_IIC_Init();//初始化IIC总线
  15. MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050
  16. delay_ms(100);
  17. MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050
  18. MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps
  19. MPU_Set_Accel_Fsr(0); //加速度传感器,±2g
  20. MPU_Set_Rate(200); //设置采样率50Hz
  21. MPU_Write_Byte(MPU_INT_EN_REG,0X00); //关闭所有中断
  22. MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭
  23. MPU_Write_Byte(MPU_FIFO_EN_REG,0X00); //关闭FIFO
  24. MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效
  25. res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
  26. if(res==MPU_ADDR)//器件ID正确
  27. {
  28. MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考
  29. MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作
  30. MPU_Set_Rate(200); //设置采样率为50Hz
  31. }
  32. else return 1;
  33. return 0;
  34. }
  35. //设置MPU6050陀螺仪传感器满量程范围
  36. //fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
  37. //返回值:0,设置成功
  38. // 其他,设置失败
  39. u8 MPU_Set_Gyro_Fsr(u8 fsr)
  40. {
  41. return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围
  42. }
  43. //设置MPU6050加速度传感器满量程范围
  44. //fsr:0,±2g;1,±4g;2,±8g;3,±16g
  45. //返回值:0,设置成功
  46. // 其他,设置失败
  47. u8 MPU_Set_Accel_Fsr(u8 fsr)
  48. {
  49. return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围
  50. }
  51. //设置MPU6050的数字低通滤波器
  52. //lpf:数字低通滤波频率(Hz)
  53. //返回值:0,设置成功
  54. // 其他,设置失败
  55. u8 MPU_Set_LPF(u16 lpf)
  56. {
  57. u8 data=0;
  58. if(lpf>=188)data=1;
  59. else if(lpf>=98)data=2;
  60. else if(lpf>=42)data=3;
  61. else if(lpf>=20)data=4;
  62. else if(lpf>=10)data=5;
  63. else data=6;
  64. return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器
  65. }
  66. //设置MPU6050的采样率(假定Fs=1KHz)
  67. //rate:4~1000(Hz)
  68. //返回值:0,设置成功
  69. // 其他,设置失败
  70. u8 MPU_Set_Rate(u16 rate)
  71. {
  72. u8 data;
  73. if(rate>1000)rate=1000;
  74. if(rate<4)rate=4;
  75. data=1000/rate-1;
  76. data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data); //设置数字低通滤波器
  77. return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半
  78. }
  79. //得到温度值
  80. //返回值:温度值(扩大了100倍)
  81. short MPU_Get_Temperature(void)
  82. {
  83. u8 buf[2];
  84. short raw;
  85. float temp;
  86. MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf);
  87. raw=((u16)buf[0]<<8)|buf[1];
  88. temp=36.53+((double)raw)/340;
  89. return temp*100;;
  90. }
  91. //得到陀螺仪值(原始值)
  92. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  93. //返回值:0,成功
  94. // 其他,错误代码
  95. u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
  96. {
  97. u8 buf[6],res;
  98. res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
  99. if(res==0)
  100. {
  101. *gx=((u16)buf[0]<<8)|buf[1];
  102. *gy=((u16)buf[2]<<8)|buf[3];
  103. *gz=((u16)buf[4]<<8)|buf[5];
  104. }
  105. return res;
  106. }
  107. //得到加速度值(原始值)
  108. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  109. //返回值:0,成功
  110. //其他,错误代码
  111. u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
  112. {
  113. u8 buf[6],res;
  114. res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
  115. if(res==0)
  116. {
  117. *ax=((u16)buf[0]<<8)|buf[1];
  118. *ay=((u16)buf[2]<<8)|buf[3];
  119. *az=((u16)buf[4]<<8)|buf[5];
  120. }
  121. return res;
  122. }
  123. //IIC连续写
  124. //addr:器件地址
  125. //reg:寄存器地址
  126. //len:写入长度
  127. //buf:数据区
  128. //返回值:0,正常
  129. //其他,错误代码
  130. u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
  131. {
  132. u8 i;
  133. MPU_IIC_Start();
  134. MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令
  135. if(MPU_IIC_Wait_Ack()) //等待应答
  136. {
  137. MPU_IIC_Stop();
  138. return 1;
  139. }
  140. MPU_IIC_Send_Byte(reg); //写寄存器地址
  141. MPU_IIC_Wait_Ack(); //等待应答
  142. for(i=0;i<len;i++)
  143. {
  144. MPU_IIC_Send_Byte(buf[i]); //发送数据
  145. if(MPU_IIC_Wait_Ack()) //等待ACK
  146. {
  147. MPU_IIC_Stop();
  148. return 1;
  149. }
  150. }
  151. MPU_IIC_Stop();
  152. return 0;
  153. }
  154. //IIC连续读
  155. //addr:器件地址
  156. //reg:要读取的寄存器地址
  157. //len:要读取的长度
  158. //buf:读取到的数据存储区
  159. //返回值:0,正常
  160. //其他,错误代码
  161. u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
  162. {
  163. MPU_IIC_Start();
  164. MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令
  165. if(MPU_IIC_Wait_Ack()) //等待应答
  166. {
  167. MPU_IIC_Stop();
  168. return 1;
  169. }
  170. MPU_IIC_Send_Byte(reg); //写寄存器地址
  171. MPU_IIC_Wait_Ack(); //等待应答
  172. MPU_IIC_Start();
  173. MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令
  174. MPU_IIC_Wait_Ack(); //等待应答
  175. while(len)
  176. {
  177. if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK
  178. else *buf=MPU_IIC_Read_Byte(1); //读数据,发送ACK
  179. len--;
  180. buf++;
  181. }
  182. MPU_IIC_Stop(); //产生一个停止条件
  183. return 0;
  184. }
  185. //IIC写一个字节
  186. //reg:寄存器地址
  187. //data:数据
  188. //返回值:0,正常
  189. // 其他,错误代码
  190. u8 MPU_Write_Byte(u8 reg,u8 data)
  191. {
  192. MPU_IIC_Start();
  193. MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
  194. if(MPU_IIC_Wait_Ack()) //等待应答
  195. {
  196. MPU_IIC_Stop();
  197. return 1;
  198. }
  199. MPU_IIC_Send_Byte(reg); //写寄存器地址
  200. MPU_IIC_Wait_Ack(); //等待应答
  201. MPU_IIC_Send_Byte(data);//发送数据
  202. if(MPU_IIC_Wait_Ack()) //等待ACK
  203. {
  204. MPU_IIC_Stop();
  205. return 1;
  206. }
  207. MPU_IIC_Stop();
  208. return 0;
  209. }
  210. //IIC读一个字节
  211. //reg:寄存器地址
  212. //返回值:读到的数据
  213. u8 MPU_Read_Byte(u8 reg)
  214. {
  215. u8 res;
  216. MPU_IIC_Start();
  217. MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
  218. MPU_IIC_Wait_Ack(); //等待应答
  219. MPU_IIC_Send_Byte(reg); //写寄存器地址
  220. MPU_IIC_Wait_Ack(); //等待应答
  221. MPU_IIC_Start();
  222. MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令
  223. MPU_IIC_Wait_Ack(); //等待应答
  224. res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK
  225. MPU_IIC_Stop(); //产生一个停止条件
  226. return res;
  227. }

(4)mpu6050.h

  1. #ifndef __MPU6050_H
  2. #define __MPU6050_H
  3. #include "mpuiic.h"
  4. //#define MPU_ACCEL_OFFS_REG 0X06 //accel_offs寄存器,可读取版本号,寄存器手册未提到
  5. //#define MPU_PROD_ID_REG 0X0C //prod id寄存器,在寄存器手册未提到
  6. #define MPU_SELF_TESTX_REG 0X0D //自检寄存器X
  7. #define MPU_SELF_TESTY_REG 0X0E //自检寄存器Y
  8. #define MPU_SELF_TESTZ_REG 0X0F //自检寄存器Z
  9. #define MPU_SELF_TESTA_REG 0X10 //自检寄存器A
  10. #define MPU_SAMPLE_RATE_REG 0X19 //采样频率分频器
  11. #define MPU_CFG_REG 0X1A //配置寄存器
  12. #define MPU_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器
  13. #define MPU_ACCEL_CFG_REG 0X1C //加速度计配置寄存器
  14. #define MPU_MOTION_DET_REG 0X1F //运动检测阀值设置寄存器
  15. #define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器
  16. #define MPU_I2CMST_CTRL_REG 0X24 //IIC主机控制寄存器
  17. #define MPU_I2CSLV0_ADDR_REG 0X25 //IIC从机0器件地址寄存器
  18. #define MPU_I2CSLV0_REG 0X26 //IIC从机0数据地址寄存器
  19. #define MPU_I2CSLV0_CTRL_REG 0X27 //IIC从机0控制寄存器
  20. #define MPU_I2CSLV1_ADDR_REG 0X28 //IIC从机1器件地址寄存器
  21. #define MPU_I2CSLV1_REG 0X29 //IIC从机1数据地址寄存器
  22. #define MPU_I2CSLV1_CTRL_REG 0X2A //IIC从机1控制寄存器
  23. #define MPU_I2CSLV2_ADDR_REG 0X2B //IIC从机2器件地址寄存器
  24. #define MPU_I2CSLV2_REG 0X2C //IIC从机2数据地址寄存器
  25. #define MPU_I2CSLV2_CTRL_REG 0X2D //IIC从机2控制寄存器
  26. #define MPU_I2CSLV3_ADDR_REG 0X2E //IIC从机3器件地址寄存器
  27. #define MPU_I2CSLV3_REG 0X2F //IIC从机3数据地址寄存器
  28. #define MPU_I2CSLV3_CTRL_REG 0X30 //IIC从机3控制寄存器
  29. #define MPU_I2CSLV4_ADDR_REG 0X31 //IIC从机4器件地址寄存器
  30. #define MPU_I2CSLV4_REG 0X32 //IIC从机4数据地址寄存器
  31. #define MPU_I2CSLV4_DO_REG 0X33 //IIC从机4写数据寄存器
  32. #define MPU_I2CSLV4_CTRL_REG 0X34 //IIC从机4控制寄存器
  33. #define MPU_I2CSLV4_DI_REG 0X35 //IIC从机4读数据寄存器
  34. #define MPU_I2CMST_STA_REG 0X36 //IIC主机状态寄存器
  35. #define MPU_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器
  36. #define MPU_INT_EN_REG 0X38 //中断使能寄存器
  37. #define MPU_INT_STA_REG 0X3A //中断状态寄存器
  38. #define MPU_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器
  39. #define MPU_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器
  40. #define MPU_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器
  41. #define MPU_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器
  42. #define MPU_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器
  43. #define MPU_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器
  44. #define MPU_TEMP_OUTH_REG 0X41 //温度值高八位寄存器
  45. #define MPU_TEMP_OUTL_REG 0X42 //温度值低8位寄存器
  46. #define MPU_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器
  47. #define MPU_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器
  48. #define MPU_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器
  49. #define MPU_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器
  50. #define MPU_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器
  51. #define MPU_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器
  52. #define MPU_I2CSLV0_DO_REG 0X63 //IIC从机0数据寄存器
  53. #define MPU_I2CSLV1_DO_REG 0X64 //IIC从机1数据寄存器
  54. #define MPU_I2CSLV2_DO_REG 0X65 //IIC从机2数据寄存器
  55. #define MPU_I2CSLV3_DO_REG 0X66 //IIC从机3数据寄存器
  56. #define MPU_I2CMST_DELAY_REG 0X67 //IIC主机延时管理寄存器
  57. #define MPU_SIGPATH_RST_REG 0X68 //信号通道复位寄存器
  58. #define MPU_MDETECT_CTRL_REG 0X69 //运动检测控制寄存器
  59. #define MPU_USER_CTRL_REG 0X6A //用户控制寄存器
  60. #define MPU_PWR_MGMT1_REG 0X6B //电源管理寄存器1
  61. #define MPU_PWR_MGMT2_REG 0X6C //电源管理寄存器2
  62. #define MPU_FIFO_CNTH_REG 0X72 //FIFO计数寄存器高八位
  63. #define MPU_FIFO_CNTL_REG 0X73 //FIFO计数寄存器低八位
  64. #define MPU_FIFO_RW_REG 0X74 //FIFO读写寄存器
  65. #define MPU_DEVICE_ID_REG 0X75 //器件ID寄存器
  66. //如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
  67. //如果接V3.3,则IIC地址为0X69(不包含最低位).
  68. #define MPU_ADDR 0X68
  69. 因为模块AD0默认接GND,所以转为读写地址后,为0XD10XD0(如果接VCC,则为0XD30XD2)
  70. //#define MPU_READ 0XD1
  71. //#define MPU_WRITE 0XD0
  72. u8 MPU_Init(void); //初始化MPU6050
  73. u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);//IIC连续写
  74. u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf); //IIC连续读
  75. u8 MPU_Write_Byte(u8 reg,u8 data); //IIC写一个字节
  76. u8 MPU_Read_Byte(u8 reg); //IIC读一个字节
  77. u8 MPU_Set_Gyro_Fsr(u8 fsr);
  78. u8 MPU_Set_Accel_Fsr(u8 fsr);
  79. u8 MPU_Set_LPF(u16 lpf);
  80. u8 MPU_Set_Rate(u16 rate);
  81. u8 MPU_Set_Fifo(u8 sens);
  82. short MPU_Get_Temperature(void);
  83. u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz);
  84. u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az);
  85. #endif

(5)inv_mpu.c

  1. /*
  2. $License:
  3. Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
  4. See included License.txt for License information.
  5. $
  6. */
  7. /**
  8. * @addtogroup DRIVERS Sensor Driver Layer
  9. * @brief Hardware drivers to communicate with sensors via I2C.
  10. *
  11. * @{
  12. * @file inv_mpu.c
  13. * @brief An I2C-based driver for Invensense gyroscopes.
  14. * @details This driver currently works for the following devices:
  15. * MPU6050
  16. * MPU6500
  17. * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus)
  18. * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus)
  19. */
  20. #include <stdio.h>
  21. #include <stdint.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <math.h>
  25. #include "inv_mpu.h"
  26. #include "inv_mpu_dmp_motion_driver.h"
  27. #include "mpu6050.h"
  28. #include "delay.h"
  29. #include "usart.h"
  30. #define MPU6050 //定义我们使用的传感器为MPU6050
  31. #define MOTION_DRIVER_TARGET_MSP430 //定义驱动部分,采用MSP430的驱动(移植到STM32F1)
  32. /* The following functions must be defined for this platform:
  33. * i2c_write(unsigned char slave_addr, unsigned char reg_addr,
  34. * unsigned char length, unsigned char const *data)
  35. * i2c_read(unsigned char slave_addr, unsigned char reg_addr,
  36. * unsigned char length, unsigned char *data)
  37. * delay_ms(unsigned long num_ms)
  38. * get_ms(unsigned long *count)
  39. * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin)
  40. * labs(long x)
  41. * fabsf(float x)
  42. * min(int a, int b)
  43. */
  44. #if defined MOTION_DRIVER_TARGET_MSP430
  45. //#include "msp430.h"
  46. //#include "msp430_i2c.h"
  47. //#include "msp430_clock.h"
  48. //#include "msp430_interrupt.h"
  49. #define i2c_write MPU_Write_Len
  50. #define i2c_read MPU_Read_Len
  51. #define delay_ms delay_ms
  52. #define get_ms mget_ms
  53. //static inline int reg_int_cb(struct int_param_s *int_param)
  54. //{
  55. // return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit,
  56. // int_param->active_low);
  57. //}
  58. #define log_i printf //打印信息
  59. #define log_e printf //打印信息
  60. /* labs is already defined by TI's toolchain. */
  61. /* fabs is for doubles. fabsf is for floats. */
  62. #define fabs fabsf
  63. #define min(a,b) ((a<b)?a:b)
  64. #elif defined EMPL_TARGET_MSP430
  65. #include "msp430.h"
  66. #include "msp430_i2c.h"
  67. #include "msp430_clock.h"
  68. #include "msp430_interrupt.h"
  69. #include "log.h"
  70. #define i2c_write msp430_i2c_write
  71. #define i2c_read msp430_i2c_read
  72. #define delay_ms msp430_delay_ms
  73. #define get_ms msp430_get_clock_ms
  74. static inline int reg_int_cb(struct int_param_s *int_param)
  75. {
  76. return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit,
  77. int_param->active_low);
  78. }
  79. #define log_i MPL_LOGI
  80. #define log_e MPL_LOGE
  81. /* labs is already defined by TI's toolchain. */
  82. /* fabs is for doubles. fabsf is for floats. */
  83. #define fabs fabsf
  84. #define min(a,b) ((a<b)?a:b)
  85. #elif defined EMPL_TARGET_UC3L0
  86. /* Instead of using the standard TWI driver from the ASF library, we're using
  87. * a TWI driver that follows the slave address + register address convention.
  88. */
  89. #include "twi.h"
  90. #include "delay.h"
  91. #include "sysclk.h"
  92. #include "log.h"
  93. #include "sensors_xplained.h"
  94. #include "uc3l0_clock.h"
  95. #define i2c_write(a, b, c, d) twi_write(a, b, d, c)
  96. #define i2c_read(a, b, c, d) twi_read(a, b, d, c)
  97. /* delay_ms is a function already defined in ASF. */
  98. #define get_ms uc3l0_get_clock_ms
  99. static inline int reg_int_cb(struct int_param_s *int_param)
  100. {
  101. sensor_board_irq_connect(int_param->pin, int_param->cb, int_param->arg);
  102. return 0;
  103. }
  104. #define log_i MPL_LOGI
  105. #define log_e MPL_LOGE
  106. /* UC3 is a 32-bit processor, so abs and labs are equivalent. */
  107. #define labs abs
  108. #define fabs(x) (((x)>0)?(x):-(x))
  109. #else
  110. #error Gyro driver is missing the system layer implementations.
  111. #endif
  112. #if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250
  113. #error Which gyro are you using? Define MPUxxxx in your compiler options.
  114. #endif
  115. /* Time for some messy macro work. =]
  116. * #define MPU9150
  117. * is equivalent to..
  118. * #define MPU6050
  119. * #define AK8975_SECONDARY
  120. *
  121. * #define MPU9250
  122. * is equivalent to..
  123. * #define MPU6500
  124. * #define AK8963_SECONDARY
  125. */
  126. #if defined MPU9150
  127. #ifndef MPU6050
  128. #define MPU6050
  129. #endif /* #ifndef MPU6050 */
  130. #if defined AK8963_SECONDARY
  131. #error "MPU9150 and AK8963_SECONDARY cannot both be defined."
  132. #elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */
  133. #define AK8975_SECONDARY
  134. #endif /* #if defined AK8963_SECONDARY */
  135. #elif defined MPU9250 /* #if defined MPU9150 */
  136. #ifndef MPU6500
  137. #define MPU6500
  138. #endif /* #ifndef MPU6500 */
  139. #if defined AK8975_SECONDARY
  140. #error "MPU9250 and AK8975_SECONDARY cannot both be defined."
  141. #elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */
  142. #define AK8963_SECONDARY
  143. #endif /* #if defined AK8975_SECONDARY */
  144. #endif /* #if defined MPU9150 */
  145. #if defined AK8975_SECONDARY || defined AK8963_SECONDARY
  146. #define AK89xx_SECONDARY
  147. #else
  148. /* #warning "No compass = less profit for Invensense. Lame." */
  149. #endif
  150. static int set_int_enable(unsigned char enable);
  151. /* Hardware registers needed by driver. */
  152. struct gyro_reg_s {
  153. unsigned char who_am_i;
  154. unsigned char rate_div;
  155. unsigned char lpf;
  156. unsigned char prod_id;
  157. unsigned char user_ctrl;
  158. unsigned char fifo_en;
  159. unsigned char gyro_cfg;
  160. unsigned char accel_cfg;
  161. // unsigned char accel_cfg2;
  162. // unsigned char lp_accel_odr;
  163. unsigned char motion_thr;
  164. unsigned char motion_dur;
  165. unsigned char fifo_count_h;
  166. unsigned char fifo_r_w;
  167. unsigned char raw_gyro;
  168. unsigned char raw_accel;
  169. unsigned char temp;
  170. unsigned char int_enable;
  171. unsigned char dmp_int_status;
  172. unsigned char int_status;
  173. // unsigned char accel_intel;
  174. unsigned char pwr_mgmt_1;
  175. unsigned char pwr_mgmt_2;
  176. unsigned char int_pin_cfg;
  177. unsigned char mem_r_w;
  178. unsigned char accel_offs;
  179. unsigned char i2c_mst;
  180. unsigned char bank_sel;
  181. unsigned char mem_start_addr;
  182. unsigned char prgm_start_h;
  183. #if defined AK89xx_SECONDARY
  184. unsigned char s0_addr;
  185. unsigned char s0_reg;
  186. unsigned char s0_ctrl;
  187. unsigned char s1_addr;
  188. unsigned char s1_reg;
  189. unsigned char s1_ctrl;
  190. unsigned char s4_ctrl;
  191. unsigned char s0_do;
  192. unsigned char s1_do;
  193. unsigned char i2c_delay_ctrl;
  194. unsigned char raw_compass;
  195. /* The I2C_MST_VDDIO bit is in this register. */
  196. unsigned char yg_offs_tc;
  197. #endif
  198. };
  199. /* Information specific to a particular device. */
  200. struct hw_s {
  201. unsigned char addr;
  202. unsigned short max_fifo;
  203. unsigned char num_reg;
  204. unsigned short temp_sens;
  205. short temp_offset;
  206. unsigned short bank_size;
  207. #if defined AK89xx_SECONDARY
  208. unsigned short compass_fsr;
  209. #endif
  210. };
  211. /* When entering motion interrupt mode, the driver keeps track of the
  212. * previous state so that it can be restored at a later time.
  213. * TODO: This is tacky. Fix it.
  214. */
  215. struct motion_int_cache_s {
  216. unsigned short gyro_fsr;
  217. unsigned char accel_fsr;
  218. unsigned short lpf;
  219. unsigned short sample_rate;
  220. unsigned char sensors_on;
  221. unsigned char fifo_sensors;
  222. unsigned char dmp_on;
  223. };
  224. /* Cached chip configuration data.
  225. * TODO: A lot of these can be handled with a bitmask.
  226. */
  227. struct chip_cfg_s {
  228. /* Matches gyro_cfg >> 3 & 0x03 */
  229. unsigned char gyro_fsr;
  230. /* Matches accel_cfg >> 3 & 0x03 */
  231. unsigned char accel_fsr;
  232. /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */
  233. unsigned char sensors;
  234. /* Matches config register. */
  235. unsigned char lpf;
  236. unsigned char clk_src;
  237. /* Sample rate, NOT rate divider. */
  238. unsigned short sample_rate;
  239. /* Matches fifo_en register. */
  240. unsigned char fifo_enable;
  241. /* Matches int enable register. */
  242. unsigned char int_enable;
  243. /* 1 if devices on auxiliary I2C bus appear on the primary. */
  244. unsigned char bypass_mode;
  245. /* 1 if half-sensitivity.
  246. * NOTE: This doesn't belong here, but everything else in hw_s is const,
  247. * and this allows us to save some precious RAM.
  248. */
  249. unsigned char accel_half;
  250. /* 1 if device in low-power accel-only mode. */
  251. unsigned char lp_accel_mode;
  252. /* 1 if interrupts are only triggered on motion events. */
  253. unsigned char int_motion_only;
  254. struct motion_int_cache_s cache;
  255. /* 1 for active low interrupts. */
  256. unsigned char active_low_int;
  257. /* 1 for latched interrupts. */
  258. unsigned char latched_int;
  259. /* 1 if DMP is enabled. */
  260. unsigned char dmp_on;
  261. /* Ensures that DMP will only be loaded once. */
  262. unsigned char dmp_loaded;
  263. /* Sampling rate used when DMP is enabled. */
  264. unsigned short dmp_sample_rate;
  265. #ifdef AK89xx_SECONDARY
  266. /* Compass sample rate. */
  267. unsigned short compass_sample_rate;
  268. unsigned char compass_addr;
  269. short mag_sens_adj[3];
  270. #endif
  271. };
  272. /* Information for self-test. */
  273. struct test_s {
  274. unsigned long gyro_sens;
  275. unsigned long accel_sens;
  276. unsigned char reg_rate_div;
  277. unsigned char reg_lpf;
  278. unsigned char reg_gyro_fsr;
  279. unsigned char reg_accel_fsr;
  280. unsigned short wait_ms;
  281. unsigned char packet_thresh;
  282. float min_dps;
  283. float max_dps;
  284. float max_gyro_var;
  285. float min_g;
  286. float max_g;
  287. float max_accel_var;
  288. };
  289. /* Gyro driver state variables. */
  290. struct gyro_state_s {
  291. const struct gyro_reg_s *reg;
  292. const struct hw_s *hw;
  293. struct chip_cfg_s chip_cfg;
  294. const struct test_s *test;
  295. };
  296. /* Filter configurations. */
  297. enum lpf_e {
  298. INV_FILTER_256HZ_NOLPF2 = 0,
  299. INV_FILTER_188HZ,
  300. INV_FILTER_98HZ,
  301. INV_FILTER_42HZ,
  302. INV_FILTER_20HZ,
  303. INV_FILTER_10HZ,
  304. INV_FILTER_5HZ,
  305. INV_FILTER_2100HZ_NOLPF,
  306. NUM_FILTER
  307. };
  308. /* Full scale ranges. */
  309. enum gyro_fsr_e {
  310. INV_FSR_250DPS = 0,
  311. INV_FSR_500DPS,
  312. INV_FSR_1000DPS,
  313. INV_FSR_2000DPS,
  314. NUM_GYRO_FSR
  315. };
  316. /* Full scale ranges. */
  317. enum accel_fsr_e {
  318. INV_FSR_2G = 0,
  319. INV_FSR_4G,
  320. INV_FSR_8G,
  321. INV_FSR_16G,
  322. NUM_ACCEL_FSR
  323. };
  324. /* Clock sources. */
  325. enum clock_sel_e {
  326. INV_CLK_INTERNAL = 0,
  327. INV_CLK_PLL,
  328. NUM_CLK
  329. };
  330. /* Low-power accel wakeup rates. */
  331. enum lp_accel_rate_e {
  332. #if defined MPU6050
  333. INV_LPA_1_25HZ,
  334. INV_LPA_5HZ,
  335. INV_LPA_20HZ,
  336. INV_LPA_40HZ
  337. #elif defined MPU6500
  338. INV_LPA_0_3125HZ,
  339. INV_LPA_0_625HZ,
  340. INV_LPA_1_25HZ,
  341. INV_LPA_2_5HZ,
  342. INV_LPA_5HZ,
  343. INV_LPA_10HZ,
  344. INV_LPA_20HZ,
  345. INV_LPA_40HZ,
  346. INV_LPA_80HZ,
  347. INV_LPA_160HZ,
  348. INV_LPA_320HZ,
  349. INV_LPA_640HZ
  350. #endif
  351. };
  352. #define BIT_I2C_MST_VDDIO (0x80)
  353. #define BIT_FIFO_EN (0x40)
  354. #define BIT_DMP_EN (0x80)
  355. #define BIT_FIFO_RST (0x04)
  356. #define BIT_DMP_RST (0x08)
  357. #define BIT_FIFO_OVERFLOW (0x10)
  358. #define BIT_DATA_RDY_EN (0x01)
  359. #define BIT_DMP_INT_EN (0x02)
  360. #define BIT_MOT_INT_EN (0x40)
  361. #define BITS_FSR (0x18)
  362. #define BITS_LPF (0x07)
  363. #define BITS_HPF (0x07)
  364. #define BITS_CLK (0x07)
  365. #define BIT_FIFO_SIZE_1024 (0x40)
  366. #define BIT_FIFO_SIZE_2048 (0x80)
  367. #define BIT_FIFO_SIZE_4096 (0xC0)
  368. #define BIT_RESET (0x80)
  369. #define BIT_SLEEP (0x40)
  370. #define BIT_S0_DELAY_EN (0x01)
  371. #define BIT_S2_DELAY_EN (0x04)
  372. #define BITS_SLAVE_LENGTH (0x0F)
  373. #define BIT_SLAVE_BYTE_SW (0x40)
  374. #define BIT_SLAVE_GROUP (0x10)
  375. #define BIT_SLAVE_EN (0x80)
  376. #define BIT_I2C_READ (0x80)
  377. #define BITS_I2C_MASTER_DLY (0x1F)
  378. #define BIT_AUX_IF_EN (0x20)
  379. #define BIT_ACTL (0x80)
  380. #define BIT_LATCH_EN (0x20)
  381. #define BIT_ANY_RD_CLR (0x10)
  382. #define BIT_BYPASS_EN (0x02)
  383. #define BITS_WOM_EN (0xC0)
  384. #define BIT_LPA_CYCLE (0x20)
  385. #define BIT_STBY_XA (0x20)
  386. #define BIT_STBY_YA (0x10)
  387. #define BIT_STBY_ZA (0x08)
  388. #define BIT_STBY_XG (0x04)
  389. #define BIT_STBY_YG (0x02)
  390. #define BIT_STBY_ZG (0x01)
  391. #define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA)
  392. #define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)
  393. #if defined AK8975_SECONDARY
  394. #define SUPPORTS_AK89xx_HIGH_SENS (0x00)
  395. #define AK89xx_FSR (9830)
  396. #elif defined AK8963_SECONDARY
  397. #define SUPPORTS_AK89xx_HIGH_SENS (0x10)
  398. #define AK89xx_FSR (4915)
  399. #endif
  400. #ifdef AK89xx_SECONDARY
  401. #define AKM_REG_WHOAMI (0x00)
  402. #define AKM_REG_ST1 (0x02)
  403. #define AKM_REG_HXL (0x03)
  404. #define AKM_REG_ST2 (0x09)
  405. #define AKM_REG_CNTL (0x0A)
  406. #define AKM_REG_ASTC (0x0C)
  407. #define AKM_REG_ASAX (0x10)
  408. #define AKM_REG_ASAY (0x11)
  409. #define AKM_REG_ASAZ (0x12)
  410. #define AKM_DATA_READY (0x01)
  411. #define AKM_DATA_OVERRUN (0x02)
  412. #define AKM_OVERFLOW (0x80)
  413. #define AKM_DATA_ERROR (0x40)
  414. #define AKM_BIT_SELF_TEST (0x40)
  415. #define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS)
  416. #define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS)
  417. #define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS)
  418. #define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS)
  419. #define AKM_WHOAMI (0x48)
  420. #endif
  421. #if defined MPU6050
  422. //const struct gyro_reg_s reg = {
  423. // .who_am_i = 0x75,
  424. // .rate_div = 0x19,
  425. // .lpf = 0x1A,
  426. // .prod_id = 0x0C,
  427. // .user_ctrl = 0x6A,
  428. // .fifo_en = 0x23,
  429. // .gyro_cfg = 0x1B,
  430. // .accel_cfg = 0x1C,
  431. // .motion_thr = 0x1F,
  432. // .motion_dur = 0x20,
  433. // .fifo_count_h = 0x72,
  434. // .fifo_r_w = 0x74,
  435. // .raw_gyro = 0x43,
  436. // .raw_accel = 0x3B,
  437. // .temp = 0x41,
  438. // .int_enable = 0x38,
  439. // .dmp_int_status = 0x39,
  440. // .int_status = 0x3A,
  441. // .pwr_mgmt_1 = 0x6B,
  442. // .pwr_mgmt_2 = 0x6C,
  443. // .int_pin_cfg = 0x37,
  444. // .mem_r_w = 0x6F,
  445. // .accel_offs = 0x06,
  446. // .i2c_mst = 0x24,
  447. // .bank_sel = 0x6D,
  448. // .mem_start_addr = 0x6E,
  449. // .prgm_start_h = 0x70
  450. //#ifdef AK89xx_SECONDARY
  451. // ,.raw_compass = 0x49,
  452. // .yg_offs_tc = 0x01,
  453. // .s0_addr = 0x25,
  454. // .s0_reg = 0x26,
  455. // .s0_ctrl = 0x27,
  456. // .s1_addr = 0x28,
  457. // .s1_reg = 0x29,
  458. // .s1_ctrl = 0x2A,
  459. // .s4_ctrl = 0x34,
  460. // .s0_do = 0x63,
  461. // .s1_do = 0x64,
  462. // .i2c_delay_ctrl = 0x67
  463. //#endif
  464. //};
  465. const struct gyro_reg_s reg = {
  466. 0x75, //who_am_i
  467. 0x19, //rate_div
  468. 0x1A, //lpf
  469. 0x0C, //prod_id
  470. 0x6A, //user_ctrl
  471. 0x23, //fifo_en
  472. 0x1B, //gyro_cfg
  473. 0x1C, //accel_cfg
  474. 0x1F, // motion_thr
  475. 0x20, // motion_dur
  476. 0x72, // fifo_count_h
  477. 0x74, // fifo_r_w
  478. 0x43, // raw_gyro
  479. 0x3B, // raw_accel
  480. 0x41, // temp
  481. 0x38, // int_enable
  482. 0x39, // dmp_int_status
  483. 0x3A, // int_status
  484. 0x6B, // pwr_mgmt_1
  485. 0x6C, // pwr_mgmt_2
  486. 0x37, // int_pin_cfg
  487. 0x6F, // mem_r_w
  488. 0x06, // accel_offs
  489. 0x24, // i2c_mst
  490. 0x6D, // bank_sel
  491. 0x6E, // mem_start_addr
  492. 0x70 // prgm_start_h
  493. };
  494. //const struct hw_s hw = {
  495. // .addr = 0x68,
  496. // .max_fifo = 1024,
  497. // .num_reg = 118,
  498. // .temp_sens = 340,
  499. // .temp_offset = -521,
  500. // .bank_size = 256
  501. //#if defined AK89xx_SECONDARY
  502. // ,.compass_fsr = AK89xx_FSR
  503. //#endif
  504. //};
  505. const struct hw_s hw={
  506. 0x68, //addr
  507. 1024, //max_fifo
  508. 118, //num_reg
  509. 340, //temp_sens
  510. -521, //temp_offset
  511. 256 //bank_size
  512. };
  513. //const struct test_s test = {
  514. // .gyro_sens = 32768/250,
  515. // .accel_sens = 32768/16,
  516. // .reg_rate_div = 0, /* 1kHz. */
  517. // .reg_lpf = 1, /* 188Hz. */
  518. // .reg_gyro_fsr = 0, /* 250dps. */
  519. // .reg_accel_fsr = 0x18, /* 16g. */
  520. // .wait_ms = 50,
  521. // .packet_thresh = 5, /* 5% */
  522. // .min_dps = 10.f,
  523. // .max_dps = 105.f,
  524. // .max_gyro_var = 0.14f,
  525. // .min_g = 0.3f,
  526. // .max_g = 0.95f,
  527. // .max_accel_var = 0.14f
  528. //};
  529. const struct test_s test={
  530. 32768/250, //gyro_sens
  531. 32768/16, // accel_sens
  532. 0, // reg_rate_div
  533. 1, // reg_lpf
  534. 0, // reg_gyro_fsr
  535. 0x18, // reg_accel_fsr
  536. 50, // wait_ms
  537. 5, // packet_thresh
  538. 10.0f, // min_dps
  539. 105.0f, // max_dps
  540. 0.14f, // max_gyro_var
  541. 0.3f, // min_g
  542. 0.95f, // max_g
  543. 0.14f // max_accel_var
  544. };
  545. //static struct gyro_state_s st = {
  546. // .reg = &reg,
  547. // .hw = &hw,
  548. // .test = &test
  549. //};
  550. static struct gyro_state_s st={
  551. &reg,
  552. &hw,
  553. {0},
  554. &test
  555. };
  556. #elif defined MPU6500
  557. const struct gyro_reg_s reg = {
  558. .who_am_i = 0x75,
  559. .rate_div = 0x19,
  560. .lpf = 0x1A,
  561. .prod_id = 0x0C,
  562. .user_ctrl = 0x6A,
  563. .fifo_en = 0x23,
  564. .gyro_cfg = 0x1B,
  565. .accel_cfg = 0x1C,
  566. .accel_cfg2 = 0x1D,
  567. .lp_accel_odr = 0x1E,
  568. .motion_thr = 0x1F,
  569. .motion_dur = 0x20,
  570. .fifo_count_h = 0x72,
  571. .fifo_r_w = 0x74,
  572. .raw_gyro = 0x43,
  573. .raw_accel = 0x3B,
  574. .temp = 0x41,
  575. .int_enable = 0x38,
  576. .dmp_int_status = 0x39,
  577. .int_status = 0x3A,
  578. .accel_intel = 0x69,
  579. .pwr_mgmt_1 = 0x6B,
  580. .pwr_mgmt_2 = 0x6C,
  581. .int_pin_cfg = 0x37,
  582. .mem_r_w = 0x6F,
  583. .accel_offs = 0x77,
  584. .i2c_mst = 0x24,
  585. .bank_sel = 0x6D,
  586. .mem_start_addr = 0x6E,
  587. .prgm_start_h = 0x70
  588. #ifdef AK89xx_SECONDARY
  589. ,.raw_compass = 0x49,
  590. .s0_addr = 0x25,
  591. .s0_reg = 0x26,
  592. .s0_ctrl = 0x27,
  593. .s1_addr = 0x28,
  594. .s1_reg = 0x29,
  595. .s1_ctrl = 0x2A,
  596. .s4_ctrl = 0x34,
  597. .s0_do = 0x63,
  598. .s1_do = 0x64,
  599. .i2c_delay_ctrl = 0x67
  600. #endif
  601. };
  602. const struct hw_s hw = {
  603. .addr = 0x68,
  604. .max_fifo = 1024,
  605. .num_reg = 128,
  606. .temp_sens = 321,
  607. .temp_offset = 0,
  608. .bank_size = 256
  609. #if defined AK89xx_SECONDARY
  610. ,.compass_fsr = AK89xx_FSR
  611. #endif
  612. };
  613. const struct test_s test = {
  614. .gyro_sens = 32768/250,
  615. .accel_sens = 32768/16,
  616. .reg_rate_div = 0, /* 1kHz. */
  617. .reg_lpf = 1, /* 188Hz. */
  618. .reg_gyro_fsr = 0, /* 250dps. */
  619. .reg_accel_fsr = 0x18, /* 16g. */
  620. .wait_ms = 50,
  621. .packet_thresh = 5, /* 5% */
  622. .min_dps = 10.f,
  623. .max_dps = 105.f,
  624. .max_gyro_var = 0.14f,
  625. .min_g = 0.3f,
  626. .max_g = 0.95f,
  627. .max_accel_var = 0.14f
  628. };
  629. static struct gyro_state_s st = {
  630. .reg = &reg,
  631. .hw = &hw,
  632. .test = &test
  633. };
  634. #endif
  635. #define MAX_PACKET_LENGTH (12)
  636. #ifdef AK89xx_SECONDARY
  637. static int setup_compass(void);
  638. #define MAX_COMPASS_SAMPLE_RATE (100)
  639. #endif
  640. /**
  641. * @brief Enable/disable data ready interrupt.
  642. * If the DMP is on, the DMP interrupt is enabled. Otherwise, the data ready
  643. * interrupt is used.
  644. * @param[in] enable 1 to enable interrupt.
  645. * @return 0 if successful.
  646. */
  647. static int set_int_enable(unsigned char enable)
  648. {
  649. unsigned char tmp;
  650. if (st.chip_cfg.dmp_on) {
  651. if (enable)
  652. tmp = BIT_DMP_INT_EN;
  653. else
  654. tmp = 0x00;
  655. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp))
  656. return -1;
  657. st.chip_cfg.int_enable = tmp;
  658. } else {
  659. if (!st.chip_cfg.sensors)
  660. return -1;
  661. if (enable && st.chip_cfg.int_enable)
  662. return 0;
  663. if (enable)
  664. tmp = BIT_DATA_RDY_EN;
  665. else
  666. tmp = 0x00;
  667. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp))
  668. return -1;
  669. st.chip_cfg.int_enable = tmp;
  670. }
  671. return 0;
  672. }
  673. /**
  674. * @brief Register dump for testing.
  675. * @return 0 if successful.
  676. */
  677. int mpu_reg_dump(void)
  678. {
  679. unsigned char ii;
  680. unsigned char data;
  681. for (ii = 0; ii < st.hw->num_reg; ii++) {
  682. if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w)
  683. continue;
  684. if (i2c_read(st.hw->addr, ii, 1, &data))
  685. return -1;
  686. log_i("%#5x: %#5x\r\n", ii, data);
  687. }
  688. return 0;
  689. }
  690. /**
  691. * @brief Read from a single register.
  692. * NOTE: The memory and FIFO read/write registers cannot be accessed.
  693. * @param[in] reg Register address.
  694. * @param[out] data Register data.
  695. * @return 0 if successful.
  696. */
  697. int mpu_read_reg(unsigned char reg, unsigned char *data)
  698. {
  699. if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w)
  700. return -1;
  701. if (reg >= st.hw->num_reg)
  702. return -1;
  703. return i2c_read(st.hw->addr, reg, 1, data);
  704. }
  705. /**
  706. * @brief Initialize hardware.
  707. * Initial configuration:\n
  708. * Gyro FSR: +/- 2000DPS\n
  709. * Accel FSR +/- 2G\n
  710. * DLPF: 42Hz\n
  711. * FIFO rate: 50Hz\n
  712. * Clock source: Gyro PLL\n
  713. * FIFO: Disabled.\n
  714. * Data ready interrupt: Disabled, active low, unlatched.
  715. * @param[in] int_param Platform-specific parameters to interrupt API.
  716. * @return 0 if successful.
  717. */
  718. int mpu_init(void)
  719. {
  720. unsigned char data[6], rev;
  721. /* Reset device. */
  722. data[0] = BIT_RESET;
  723. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data))
  724. return -1;
  725. delay_ms(100);
  726. /* Wake up chip. */
  727. data[0] = 0x00;
  728. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data))
  729. return -1;
  730. #if defined MPU6050
  731. /* Check product revision. */
  732. if (i2c_read(st.hw->addr, st.reg->accel_offs, 6, data))
  733. return -1;
  734. rev = ((data[5] & 0x01) << 2) | ((data[3] & 0x01) << 1) |
  735. (data[1] & 0x01);
  736. if (rev) {
  737. /* Congrats, these parts are better. */
  738. if (rev == 1)
  739. st.chip_cfg.accel_half = 1;
  740. else if (rev == 2)
  741. st.chip_cfg.accel_half = 0;
  742. else {
  743. log_e("Unsupported software product rev %d.\n", rev);
  744. return -1;
  745. }
  746. } else {
  747. if (i2c_read(st.hw->addr, st.reg->prod_id, 1, data))
  748. return -1;
  749. rev = data[0] & 0x0F;
  750. if (!rev) {
  751. log_e("Product ID read as 0 indicates device is either "
  752. "incompatible or an MPU3050.\n");
  753. return -1;
  754. } else if (rev == 4) {
  755. log_i("Half sensitivity part found.\n");
  756. st.chip_cfg.accel_half = 1;
  757. } else
  758. st.chip_cfg.accel_half = 0;
  759. }
  760. #elif defined MPU6500
  761. #define MPU6500_MEM_REV_ADDR (0x17)
  762. if (mpu_read_mem(MPU6500_MEM_REV_ADDR, 1, &rev))
  763. return -1;
  764. if (rev == 0x1)
  765. st.chip_cfg.accel_half = 0;
  766. else {
  767. log_e("Unsupported software product rev %d.\n", rev);
  768. return -1;
  769. }
  770. /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the
  771. * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO.
  772. */
  773. data[0] = BIT_FIFO_SIZE_1024 | 0x8;
  774. if (i2c_write(st.hw->addr, st.reg->accel_cfg2, 1, data))
  775. return -1;
  776. #endif
  777. /* Set to invalid values to ensure no I2C writes are skipped. */
  778. st.chip_cfg.sensors = 0xFF;
  779. st.chip_cfg.gyro_fsr = 0xFF;
  780. st.chip_cfg.accel_fsr = 0xFF;
  781. st.chip_cfg.lpf = 0xFF;
  782. st.chip_cfg.sample_rate = 0xFFFF;
  783. st.chip_cfg.fifo_enable = 0xFF;
  784. st.chip_cfg.bypass_mode = 0xFF;
  785. #ifdef AK89xx_SECONDARY
  786. st.chip_cfg.compass_sample_rate = 0xFFFF;
  787. #endif
  788. /* mpu_set_sensors always preserves this setting. */
  789. st.chip_cfg.clk_src = INV_CLK_PLL;
  790. /* Handled in next call to mpu_set_bypass. */
  791. st.chip_cfg.active_low_int = 1;
  792. st.chip_cfg.latched_int = 0;
  793. st.chip_cfg.int_motion_only = 0;
  794. st.chip_cfg.lp_accel_mode = 0;
  795. memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache));
  796. st.chip_cfg.dmp_on = 0;
  797. st.chip_cfg.dmp_loaded = 0;
  798. st.chip_cfg.dmp_sample_rate = 0;
  799. if (mpu_set_gyro_fsr(2000))
  800. return -1;
  801. if (mpu_set_accel_fsr(2))
  802. return -1;
  803. if (mpu_set_lpf(42))
  804. return -1;
  805. if (mpu_set_sample_rate(50))
  806. return -1;
  807. if (mpu_configure_fifo(0))
  808. return -1;
  809. // if (int_param)
  810. // reg_int_cb(int_param);
  811. #ifdef AK89xx_SECONDARY
  812. setup_compass();
  813. if (mpu_set_compass_sample_rate(10))
  814. return -1;
  815. #else
  816. /* Already disabled by setup_compass. */
  817. if (mpu_set_bypass(0))
  818. return -1;
  819. #endif
  820. mpu_set_sensors(0);
  821. return 0;
  822. }
  823. /**
  824. * @brief Enter low-power accel-only mode.
  825. * In low-power accel mode, the chip goes to sleep and only wakes up to sample
  826. * the accelerometer at one of the following frequencies:
  827. * \n MPU6050: 1.25Hz, 5Hz, 20Hz, 40Hz
  828. * \n MPU6500: 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz
  829. * \n If the requested rate is not one listed above, the device will be set to
  830. * the next highest rate. Requesting a rate above the maximum supported
  831. * frequency will result in an error.
  832. * \n To select a fractional wake-up frequency, round down the value passed to
  833. * @e rate.
  834. * @param[in] rate Minimum sampling rate, or zero to disable LP
  835. * accel mode.
  836. * @return 0 if successful.
  837. */
  838. int mpu_lp_accel_mode(unsigned char rate)
  839. {
  840. unsigned char tmp[2];
  841. if (rate > 40)
  842. return -1;
  843. if (!rate) {
  844. mpu_set_int_latched(0);
  845. tmp[0] = 0;
  846. tmp[1] = BIT_STBY_XYZG;
  847. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp))
  848. return -1;
  849. st.chip_cfg.lp_accel_mode = 0;
  850. return 0;
  851. }
  852. /* For LP accel, we automatically configure the hardware to produce latched
  853. * interrupts. In LP accel mode, the hardware cycles into sleep mode before
  854. * it gets a chance to deassert the interrupt pin; therefore, we shift this
  855. * responsibility over to the MCU.
  856. *
  857. * Any register read will clear the interrupt.
  858. */
  859. mpu_set_int_latched(1);
  860. #if defined MPU6050
  861. tmp[0] = BIT_LPA_CYCLE;
  862. if (rate == 1) {
  863. tmp[1] = INV_LPA_1_25HZ;
  864. mpu_set_lpf(5);
  865. } else if (rate <= 5) {
  866. tmp[1] = INV_LPA_5HZ;
  867. mpu_set_lpf(5);
  868. } else if (rate <= 20) {
  869. tmp[1] = INV_LPA_20HZ;
  870. mpu_set_lpf(10);
  871. } else {
  872. tmp[1] = INV_LPA_40HZ;
  873. mpu_set_lpf(20);
  874. }
  875. tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG;
  876. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp))
  877. return -1;
  878. #elif defined MPU6500
  879. /* Set wake frequency. */
  880. if (rate == 1)
  881. tmp[0] = INV_LPA_1_25HZ;
  882. else if (rate == 2)
  883. tmp[0] = INV_LPA_2_5HZ;
  884. else if (rate <= 5)
  885. tmp[0] = INV_LPA_5HZ;
  886. else if (rate <= 10)
  887. tmp[0] = INV_LPA_10HZ;
  888. else if (rate <= 20)
  889. tmp[0] = INV_LPA_20HZ;
  890. else if (rate <= 40)
  891. tmp[0] = INV_LPA_40HZ;
  892. else if (rate <= 80)
  893. tmp[0] = INV_LPA_80HZ;
  894. else if (rate <= 160)
  895. tmp[0] = INV_LPA_160HZ;
  896. else if (rate <= 320)
  897. tmp[0] = INV_LPA_320HZ;
  898. else
  899. tmp[0] = INV_LPA_640HZ;
  900. if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp))
  901. return -1;
  902. tmp[0] = BIT_LPA_CYCLE;
  903. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp))
  904. return -1;
  905. #endif
  906. st.chip_cfg.sensors = INV_XYZ_ACCEL;
  907. st.chip_cfg.clk_src = 0;
  908. st.chip_cfg.lp_accel_mode = 1;
  909. mpu_configure_fifo(0);
  910. return 0;
  911. }
  912. /**
  913. * @brief Read raw gyro data directly from the registers.
  914. * @param[out] data Raw data in hardware units.
  915. * @param[out] timestamp Timestamp in milliseconds. Null if not needed.
  916. * @return 0 if successful.
  917. */
  918. int mpu_get_gyro_reg(short *data, unsigned long *timestamp)
  919. {
  920. unsigned char tmp[6];
  921. if (!(st.chip_cfg.sensors & INV_XYZ_GYRO))
  922. return -1;
  923. if (i2c_read(st.hw->addr, st.reg->raw_gyro, 6, tmp))
  924. return -1;
  925. data[0] = (tmp[0] << 8) | tmp[1];
  926. data[1] = (tmp[2] << 8) | tmp[3];
  927. data[2] = (tmp[4] << 8) | tmp[5];
  928. if (timestamp)
  929. get_ms(timestamp);
  930. return 0;
  931. }
  932. /**
  933. * @brief Read raw accel data directly from the registers.
  934. * @param[out] data Raw data in hardware units.
  935. * @param[out] timestamp Timestamp in milliseconds. Null if not needed.
  936. * @return 0 if successful.
  937. */
  938. int mpu_get_accel_reg(short *data, unsigned long *timestamp)
  939. {
  940. unsigned char tmp[6];
  941. if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL))
  942. return -1;
  943. if (i2c_read(st.hw->addr, st.reg->raw_accel, 6, tmp))
  944. return -1;
  945. data[0] = (tmp[0] << 8) | tmp[1];
  946. data[1] = (tmp[2] << 8) | tmp[3];
  947. data[2] = (tmp[4] << 8) | tmp[5];
  948. if (timestamp)
  949. get_ms(timestamp);
  950. return 0;
  951. }
  952. /**
  953. * @brief Read temperature data directly from the registers.
  954. * @param[out] data Data in q16 format.
  955. * @param[out] timestamp Timestamp in milliseconds. Null if not needed.
  956. * @return 0 if successful.
  957. */
  958. int mpu_get_temperature(long *data, unsigned long *timestamp)
  959. {
  960. unsigned char tmp[2];
  961. short raw;
  962. if (!(st.chip_cfg.sensors))
  963. return -1;
  964. if (i2c_read(st.hw->addr, st.reg->temp, 2, tmp))
  965. return -1;
  966. raw = (tmp[0] << 8) | tmp[1];
  967. if (timestamp)
  968. get_ms(timestamp);
  969. data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L);
  970. return 0;
  971. }
  972. /**
  973. * @brief Push biases to the accel bias registers.
  974. * This function expects biases relative to the current sensor output, and
  975. * these biases will be added to the factory-supplied values.
  976. * @param[in] accel_bias New biases.
  977. * @return 0 if successful.
  978. */
  979. int mpu_set_accel_bias(const long *accel_bias)
  980. {
  981. unsigned char data[6];
  982. short accel_hw[3];
  983. short got_accel[3];
  984. short fg[3];
  985. if (!accel_bias)
  986. return -1;
  987. if (!accel_bias[0] && !accel_bias[1] && !accel_bias[2])
  988. return 0;
  989. if (i2c_read(st.hw->addr, 3, 3, data))
  990. return -1;
  991. fg[0] = ((data[0] >> 4) + 8) & 0xf;
  992. fg[1] = ((data[1] >> 4) + 8) & 0xf;
  993. fg[2] = ((data[2] >> 4) + 8) & 0xf;
  994. accel_hw[0] = (short)(accel_bias[0] * 2 / (64 + fg[0]));
  995. accel_hw[1] = (short)(accel_bias[1] * 2 / (64 + fg[1]));
  996. accel_hw[2] = (short)(accel_bias[2] * 2 / (64 + fg[2]));
  997. if (i2c_read(st.hw->addr, 0x06, 6, data))
  998. return -1;
  999. got_accel[0] = ((short)data[0] << 8) | data[1];
  1000. got_accel[1] = ((short)data[2] << 8) | data[3];
  1001. got_accel[2] = ((short)data[4] << 8) | data[5];
  1002. accel_hw[0] += got_accel[0];
  1003. accel_hw[1] += got_accel[1];
  1004. accel_hw[2] += got_accel[2];
  1005. data[0] = (accel_hw[0] >> 8) & 0xff;
  1006. data[1] = (accel_hw[0]) & 0xff;
  1007. data[2] = (accel_hw[1] >> 8) & 0xff;
  1008. data[3] = (accel_hw[1]) & 0xff;
  1009. data[4] = (accel_hw[2] >> 8) & 0xff;
  1010. data[5] = (accel_hw[2]) & 0xff;
  1011. if (i2c_write(st.hw->addr, 0x06, 6, data))
  1012. return -1;
  1013. return 0;
  1014. }
  1015. /**
  1016. * @brief Reset FIFO read/write pointers.
  1017. * @return 0 if successful.
  1018. */
  1019. int mpu_reset_fifo(void)
  1020. {
  1021. unsigned char data;
  1022. if (!(st.chip_cfg.sensors))
  1023. return -1;
  1024. data = 0;
  1025. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data))
  1026. return -1;
  1027. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data))
  1028. return -1;
  1029. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data))
  1030. return -1;
  1031. if (st.chip_cfg.dmp_on) {
  1032. data = BIT_FIFO_RST | BIT_DMP_RST;
  1033. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data))
  1034. return -1;
  1035. delay_ms(50);
  1036. data = BIT_DMP_EN | BIT_FIFO_EN;
  1037. if (st.chip_cfg.sensors & INV_XYZ_COMPASS)
  1038. data |= BIT_AUX_IF_EN;
  1039. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data))
  1040. return -1;
  1041. if (st.chip_cfg.int_enable)
  1042. data = BIT_DMP_INT_EN;
  1043. else
  1044. data = 0;
  1045. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data))
  1046. return -1;
  1047. data = 0;
  1048. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data))
  1049. return -1;
  1050. } else {
  1051. data = BIT_FIFO_RST;
  1052. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data))
  1053. return -1;
  1054. if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS))
  1055. data = BIT_FIFO_EN;
  1056. else
  1057. data = BIT_FIFO_EN | BIT_AUX_IF_EN;
  1058. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data))
  1059. return -1;
  1060. delay_ms(50);
  1061. if (st.chip_cfg.int_enable)
  1062. data = BIT_DATA_RDY_EN;
  1063. else
  1064. data = 0;
  1065. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data))
  1066. return -1;
  1067. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable))
  1068. return -1;
  1069. }
  1070. return 0;
  1071. }
  1072. /**
  1073. * @brief Get the gyro full-scale range.
  1074. * @param[out] fsr Current full-scale range.
  1075. * @return 0 if successful.
  1076. */
  1077. int mpu_get_gyro_fsr(unsigned short *fsr)
  1078. {
  1079. switch (st.chip_cfg.gyro_fsr) {
  1080. case INV_FSR_250DPS:
  1081. fsr[0] = 250;
  1082. break;
  1083. case INV_FSR_500DPS:
  1084. fsr[0] = 500;
  1085. break;
  1086. case INV_FSR_1000DPS:
  1087. fsr[0] = 1000;
  1088. break;
  1089. case INV_FSR_2000DPS:
  1090. fsr[0] = 2000;
  1091. break;
  1092. default:
  1093. fsr[0] = 0;
  1094. break;
  1095. }
  1096. return 0;
  1097. }
  1098. /**
  1099. * @brief Set the gyro full-scale range.
  1100. * @param[in] fsr Desired full-scale range.
  1101. * @return 0 if successful.
  1102. */
  1103. int mpu_set_gyro_fsr(unsigned short fsr)
  1104. {
  1105. unsigned char data;
  1106. if (!(st.chip_cfg.sensors))
  1107. return -1;
  1108. switch (fsr) {
  1109. case 250:
  1110. data = INV_FSR_250DPS << 3;
  1111. break;
  1112. case 500:
  1113. data = INV_FSR_500DPS << 3;
  1114. break;
  1115. case 1000:
  1116. data = INV_FSR_1000DPS << 3;
  1117. break;
  1118. case 2000:
  1119. data = INV_FSR_2000DPS << 3;
  1120. break;
  1121. default:
  1122. return -1;
  1123. }
  1124. if (st.chip_cfg.gyro_fsr == (data >> 3))
  1125. return 0;
  1126. if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, &data))
  1127. return -1;
  1128. st.chip_cfg.gyro_fsr = data >> 3;
  1129. return 0;
  1130. }
  1131. /**
  1132. * @brief Get the accel full-scale range.
  1133. * @param[out] fsr Current full-scale range.
  1134. * @return 0 if successful.
  1135. */
  1136. int mpu_get_accel_fsr(unsigned char *fsr)
  1137. {
  1138. switch (st.chip_cfg.accel_fsr) {
  1139. case INV_FSR_2G:
  1140. fsr[0] = 2;
  1141. break;
  1142. case INV_FSR_4G:
  1143. fsr[0] = 4;
  1144. break;
  1145. case INV_FSR_8G:
  1146. fsr[0] = 8;
  1147. break;
  1148. case INV_FSR_16G:
  1149. fsr[0] = 16;
  1150. break;
  1151. default:
  1152. return -1;
  1153. }
  1154. if (st.chip_cfg.accel_half)
  1155. fsr[0] <<= 1;
  1156. return 0;
  1157. }
  1158. /**
  1159. * @brief Set the accel full-scale range.
  1160. * @param[in] fsr Desired full-scale range.
  1161. * @return 0 if successful.
  1162. */
  1163. int mpu_set_accel_fsr(unsigned char fsr)
  1164. {
  1165. unsigned char data;
  1166. if (!(st.chip_cfg.sensors))
  1167. return -1;
  1168. switch (fsr) {
  1169. case 2:
  1170. data = INV_FSR_2G << 3;
  1171. break;
  1172. case 4:
  1173. data = INV_FSR_4G << 3;
  1174. break;
  1175. case 8:
  1176. data = INV_FSR_8G << 3;
  1177. break;
  1178. case 16:
  1179. data = INV_FSR_16G << 3;
  1180. break;
  1181. default:
  1182. return -1;
  1183. }
  1184. if (st.chip_cfg.accel_fsr == (data >> 3))
  1185. return 0;
  1186. if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, &data))
  1187. return -1;
  1188. st.chip_cfg.accel_fsr = data >> 3;
  1189. return 0;
  1190. }
  1191. /**
  1192. * @brief Get the current DLPF setting.
  1193. * @param[out] lpf Current LPF setting.
  1194. * 0 if successful.
  1195. */
  1196. int mpu_get_lpf(unsigned short *lpf)
  1197. {
  1198. switch (st.chip_cfg.lpf) {
  1199. case INV_FILTER_188HZ:
  1200. lpf[0] = 188;
  1201. break;
  1202. case INV_FILTER_98HZ:
  1203. lpf[0] = 98;
  1204. break;
  1205. case INV_FILTER_42HZ:
  1206. lpf[0] = 42;
  1207. break;
  1208. case INV_FILTER_20HZ:
  1209. lpf[0] = 20;
  1210. break;
  1211. case INV_FILTER_10HZ:
  1212. lpf[0] = 10;
  1213. break;
  1214. case INV_FILTER_5HZ:
  1215. lpf[0] = 5;
  1216. break;
  1217. case INV_FILTER_256HZ_NOLPF2:
  1218. case INV_FILTER_2100HZ_NOLPF:
  1219. default:
  1220. lpf[0] = 0;
  1221. break;
  1222. }
  1223. return 0;
  1224. }
  1225. /**
  1226. * @brief Set digital low pass filter.
  1227. * The following LPF settings are supported: 188, 98, 42, 20, 10, 5.
  1228. * @param[in] lpf Desired LPF setting.
  1229. * @return 0 if successful.
  1230. */
  1231. int mpu_set_lpf(unsigned short lpf)
  1232. {
  1233. unsigned char data;
  1234. if (!(st.chip_cfg.sensors))
  1235. return -1;
  1236. if (lpf >= 188)
  1237. data = INV_FILTER_188HZ;
  1238. else if (lpf >= 98)
  1239. data = INV_FILTER_98HZ;
  1240. else if (lpf >= 42)
  1241. data = INV_FILTER_42HZ;
  1242. else if (lpf >= 20)
  1243. data = INV_FILTER_20HZ;
  1244. else if (lpf >= 10)
  1245. data = INV_FILTER_10HZ;
  1246. else
  1247. data = INV_FILTER_5HZ;
  1248. if (st.chip_cfg.lpf == data)
  1249. return 0;
  1250. if (i2c_write(st.hw->addr, st.reg->lpf, 1, &data))
  1251. return -1;
  1252. st.chip_cfg.lpf = data;
  1253. return 0;
  1254. }
  1255. /**
  1256. * @brief Get sampling rate.
  1257. * @param[out] rate Current sampling rate (Hz).
  1258. * @return 0 if successful.
  1259. */
  1260. int mpu_get_sample_rate(unsigned short *rate)
  1261. {
  1262. if (st.chip_cfg.dmp_on)
  1263. return -1;
  1264. else
  1265. rate[0] = st.chip_cfg.sample_rate;
  1266. return 0;
  1267. }
  1268. /**
  1269. * @brief Set sampling rate.
  1270. * Sampling rate must be between 4Hz and 1kHz.
  1271. * @param[in] rate Desired sampling rate (Hz).
  1272. * @return 0 if successful.
  1273. */
  1274. int mpu_set_sample_rate(unsigned short rate)
  1275. {
  1276. unsigned char data;
  1277. if (!(st.chip_cfg.sensors))
  1278. return -1;
  1279. if (st.chip_cfg.dmp_on)
  1280. return -1;
  1281. else {
  1282. if (st.chip_cfg.lp_accel_mode) {
  1283. if (rate && (rate <= 40)) {
  1284. /* Just stay in low-power accel mode. */
  1285. mpu_lp_accel_mode(rate);
  1286. return 0;
  1287. }
  1288. /* Requested rate exceeds the allowed frequencies in LP accel mode,
  1289. * switch back to full-power mode.
  1290. */
  1291. mpu_lp_accel_mode(0);
  1292. }
  1293. if (rate < 4)
  1294. rate = 4;
  1295. else if (rate > 1000)
  1296. rate = 1000;
  1297. data = 1000 / rate - 1;
  1298. if (i2c_write(st.hw->addr, st.reg->rate_div, 1, &data))
  1299. return -1;
  1300. st.chip_cfg.sample_rate = 1000 / (1 + data);
  1301. #ifdef AK89xx_SECONDARY
  1302. mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE));
  1303. #endif
  1304. /* Automatically set LPF to 1/2 sampling rate. */
  1305. mpu_set_lpf(st.chip_cfg.sample_rate >> 1);
  1306. return 0;
  1307. }
  1308. }
  1309. /**
  1310. * @brief Get compass sampling rate.
  1311. * @param[out] rate Current compass sampling rate (Hz).
  1312. * @return 0 if successful.
  1313. */
  1314. int mpu_get_compass_sample_rate(unsigned short *rate)
  1315. {
  1316. #ifdef AK89xx_SECONDARY
  1317. rate[0] = st.chip_cfg.compass_sample_rate;
  1318. return 0;
  1319. #else
  1320. rate[0] = 0;
  1321. return -1;
  1322. #endif
  1323. }
  1324. /**
  1325. * @brief Set compass sampling rate.
  1326. * The compass on the auxiliary I2C bus is read by the MPU hardware at a
  1327. * maximum of 100Hz. The actual rate can be set to a fraction of the gyro
  1328. * sampling rate.
  1329. *
  1330. * \n WARNING: The new rate may be different than what was requested. Call
  1331. * mpu_get_compass_sample_rate to check the actual setting.
  1332. * @param[in] rate Desired compass sampling rate (Hz).
  1333. * @return 0 if successful.
  1334. */
  1335. int mpu_set_compass_sample_rate(unsigned short rate)
  1336. {
  1337. #ifdef AK89xx_SECONDARY
  1338. unsigned char div;
  1339. if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE)
  1340. return -1;
  1341. div = st.chip_cfg.sample_rate / rate - 1;
  1342. if (i2c_write(st.hw->addr, st.reg->s4_ctrl, 1, &div))
  1343. return -1;
  1344. st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1);
  1345. return 0;
  1346. #else
  1347. return -1;
  1348. #endif
  1349. }
  1350. /**
  1351. * @brief Get gyro sensitivity scale factor.
  1352. * @param[out] sens Conversion from hardware units to dps.
  1353. * @return 0 if successful.
  1354. */
  1355. int mpu_get_gyro_sens(float *sens)
  1356. {
  1357. switch (st.chip_cfg.gyro_fsr) {
  1358. case INV_FSR_250DPS:
  1359. sens[0] = 131.f;
  1360. break;
  1361. case INV_FSR_500DPS:
  1362. sens[0] = 65.5f;
  1363. break;
  1364. case INV_FSR_1000DPS:
  1365. sens[0] = 32.8f;
  1366. break;
  1367. case INV_FSR_2000DPS:
  1368. sens[0] = 16.4f;
  1369. break;
  1370. default:
  1371. return -1;
  1372. }
  1373. return 0;
  1374. }
  1375. /**
  1376. * @brief Get accel sensitivity scale factor.
  1377. * @param[out] sens Conversion from hardware units to g's.
  1378. * @return 0 if successful.
  1379. */
  1380. int mpu_get_accel_sens(unsigned short *sens)
  1381. {
  1382. switch (st.chip_cfg.accel_fsr) {
  1383. case INV_FSR_2G:
  1384. sens[0] = 16384;
  1385. break;
  1386. case INV_FSR_4G:
  1387. sens[0] = 8092;
  1388. break;
  1389. case INV_FSR_8G:
  1390. sens[0] = 4096;
  1391. break;
  1392. case INV_FSR_16G:
  1393. sens[0] = 2048;
  1394. break;
  1395. default:
  1396. return -1;
  1397. }
  1398. if (st.chip_cfg.accel_half)
  1399. sens[0] >>= 1;
  1400. return 0;
  1401. }
  1402. /**
  1403. * @brief Get current FIFO configuration.
  1404. * @e sensors can contain a combination of the following flags:
  1405. * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO
  1406. * \n INV_XYZ_GYRO
  1407. * \n INV_XYZ_ACCEL
  1408. * @param[out] sensors Mask of sensors in FIFO.
  1409. * @return 0 if successful.
  1410. */
  1411. int mpu_get_fifo_config(unsigned char *sensors)
  1412. {
  1413. sensors[0] = st.chip_cfg.fifo_enable;
  1414. return 0;
  1415. }
  1416. /**
  1417. * @brief Select which sensors are pushed to FIFO.
  1418. * @e sensors can contain a combination of the following flags:
  1419. * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO
  1420. * \n INV_XYZ_GYRO
  1421. * \n INV_XYZ_ACCEL
  1422. * @param[in] sensors Mask of sensors to push to FIFO.
  1423. * @return 0 if successful.
  1424. */
  1425. int mpu_configure_fifo(unsigned char sensors)
  1426. {
  1427. unsigned char prev;
  1428. int result = 0;
  1429. /* Compass data isn't going into the FIFO. Stop trying. */
  1430. sensors &= ~INV_XYZ_COMPASS;
  1431. if (st.chip_cfg.dmp_on)
  1432. return 0;
  1433. else {
  1434. if (!(st.chip_cfg.sensors))
  1435. return -1;
  1436. prev = st.chip_cfg.fifo_enable;
  1437. st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors;
  1438. if (st.chip_cfg.fifo_enable != sensors)
  1439. /* You're not getting what you asked for. Some sensors are
  1440. * asleep.
  1441. */
  1442. result = -1;
  1443. else
  1444. result = 0;
  1445. if (sensors || st.chip_cfg.lp_accel_mode)
  1446. set_int_enable(1);
  1447. else
  1448. set_int_enable(0);
  1449. if (sensors) {
  1450. if (mpu_reset_fifo()) {
  1451. st.chip_cfg.fifo_enable = prev;
  1452. return -1;
  1453. }
  1454. }
  1455. }
  1456. return result;
  1457. }
  1458. /**
  1459. * @brief Get current power state.
  1460. * @param[in] power_on 1 if turned on, 0 if suspended.
  1461. * @return 0 if successful.
  1462. */
  1463. int mpu_get_power_state(unsigned char *power_on)
  1464. {
  1465. if (st.chip_cfg.sensors)
  1466. power_on[0] = 1;
  1467. else
  1468. power_on[0] = 0;
  1469. return 0;
  1470. }
  1471. /**
  1472. * @brief Turn specific sensors on/off.
  1473. * @e sensors can contain a combination of the following flags:
  1474. * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO
  1475. * \n INV_XYZ_GYRO
  1476. * \n INV_XYZ_ACCEL
  1477. * \n INV_XYZ_COMPASS
  1478. * @param[in] sensors Mask of sensors to wake.
  1479. * @return 0 if successful.
  1480. */
  1481. int mpu_set_sensors(unsigned char sensors)
  1482. {
  1483. unsigned char data;
  1484. #ifdef AK89xx_SECONDARY
  1485. unsigned char user_ctrl;
  1486. #endif
  1487. if (sensors & INV_XYZ_GYRO)
  1488. data = INV_CLK_PLL;
  1489. else if (sensors)
  1490. data = 0;
  1491. else
  1492. data = BIT_SLEEP;
  1493. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) {
  1494. st.chip_cfg.sensors = 0;
  1495. return -1;
  1496. }
  1497. st.chip_cfg.clk_src = data & ~BIT_SLEEP;
  1498. data = 0;
  1499. if (!(sensors & INV_X_GYRO))
  1500. data |= BIT_STBY_XG;
  1501. if (!(sensors & INV_Y_GYRO))
  1502. data |= BIT_STBY_YG;
  1503. if (!(sensors & INV_Z_GYRO))
  1504. data |= BIT_STBY_ZG;
  1505. if (!(sensors & INV_XYZ_ACCEL))
  1506. data |= BIT_STBY_XYZA;
  1507. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) {
  1508. st.chip_cfg.sensors = 0;
  1509. return -1;
  1510. }
  1511. if (sensors && (sensors != INV_XYZ_ACCEL))
  1512. /* Latched interrupts only used in LP accel mode. */
  1513. mpu_set_int_latched(0);
  1514. #ifdef AK89xx_SECONDARY
  1515. #ifdef AK89xx_BYPASS
  1516. if (sensors & INV_XYZ_COMPASS)
  1517. mpu_set_bypass(1);
  1518. else
  1519. mpu_set_bypass(0);
  1520. #else
  1521. if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl))
  1522. return -1;
  1523. /* Handle AKM power management. */
  1524. if (sensors & INV_XYZ_COMPASS) {
  1525. data = AKM_SINGLE_MEASUREMENT;
  1526. user_ctrl |= BIT_AUX_IF_EN;
  1527. } else {
  1528. data = AKM_POWER_DOWN;
  1529. user_ctrl &= ~BIT_AUX_IF_EN;
  1530. }
  1531. if (st.chip_cfg.dmp_on)
  1532. user_ctrl |= BIT_DMP_EN;
  1533. else
  1534. user_ctrl &= ~BIT_DMP_EN;
  1535. if (i2c_write(st.hw->addr, st.reg->s1_do, 1, &data))
  1536. return -1;
  1537. /* Enable/disable I2C master mode. */
  1538. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl))
  1539. return -1;
  1540. #endif
  1541. #endif
  1542. st.chip_cfg.sensors = sensors;
  1543. st.chip_cfg.lp_accel_mode = 0;
  1544. delay_ms(50);
  1545. return 0;
  1546. }
  1547. /**
  1548. * @brief Read the MPU interrupt status registers.
  1549. * @param[out] status Mask of interrupt bits.
  1550. * @return 0 if successful.
  1551. */
  1552. int mpu_get_int_status(short *status)
  1553. {
  1554. unsigned char tmp[2];
  1555. if (!st.chip_cfg.sensors)
  1556. return -1;
  1557. if (i2c_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp))
  1558. return -1;
  1559. status[0] = (tmp[0] << 8) | tmp[1];
  1560. return 0;
  1561. }
  1562. /**
  1563. * @brief Get one packet from the FIFO.
  1564. * If @e sensors does not contain a particular sensor, disregard the data
  1565. * returned to that pointer.
  1566. * \n @e sensors can contain a combination of the following flags:
  1567. * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO
  1568. * \n INV_XYZ_GYRO
  1569. * \n INV_XYZ_ACCEL
  1570. * \n If the FIFO has no new data, @e sensors will be zero.
  1571. * \n If the FIFO is disabled, @e sensors will be zero and this function will
  1572. * return a non-zero error code.
  1573. * @param[out] gyro Gyro data in hardware units.
  1574. * @param[out] accel Accel data in hardware units.
  1575. * @param[out] timestamp Timestamp in milliseconds.
  1576. * @param[out] sensors Mask of sensors read from FIFO.
  1577. * @param[out] more Number of remaining packets.
  1578. * @return 0 if successful.
  1579. */
  1580. int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp,
  1581. unsigned char *sensors, unsigned char *more)
  1582. {
  1583. /* Assumes maximum packet size is gyro (6) + accel (6). */
  1584. unsigned char data[MAX_PACKET_LENGTH];
  1585. unsigned char packet_size = 0;
  1586. unsigned short fifo_count, index = 0;
  1587. if (st.chip_cfg.dmp_on)
  1588. return -1;
  1589. sensors[0] = 0;
  1590. if (!st.chip_cfg.sensors)
  1591. return -1;
  1592. if (!st.chip_cfg.fifo_enable)
  1593. return -1;
  1594. if (st.chip_cfg.fifo_enable & INV_X_GYRO)
  1595. packet_size += 2;
  1596. if (st.chip_cfg.fifo_enable & INV_Y_GYRO)
  1597. packet_size += 2;
  1598. if (st.chip_cfg.fifo_enable & INV_Z_GYRO)
  1599. packet_size += 2;
  1600. if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL)
  1601. packet_size += 6;
  1602. if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data))
  1603. return -1;
  1604. fifo_count = (data[0] << 8) | data[1];
  1605. if (fifo_count < packet_size)
  1606. return 0;
  1607. // log_i("FIFO count: %hd\n", fifo_count);
  1608. if (fifo_count > (st.hw->max_fifo >> 1)) {
  1609. /* FIFO is 50% full, better check overflow bit. */
  1610. if (i2c_read(st.hw->addr, st.reg->int_status, 1, data))
  1611. return -1;
  1612. if (data[0] & BIT_FIFO_OVERFLOW) {
  1613. mpu_reset_fifo();
  1614. return -2;
  1615. }
  1616. }
  1617. get_ms((unsigned long*)timestamp);
  1618. if (i2c_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data))
  1619. return -1;
  1620. more[0] = fifo_count / packet_size - 1;
  1621. sensors[0] = 0;
  1622. if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) {
  1623. accel[0] = (data[index+0] << 8) | data[index+1];
  1624. accel[1] = (data[index+2] << 8) | data[index+3];
  1625. accel[2] = (data[index+4] << 8) | data[index+5];
  1626. sensors[0] |= INV_XYZ_ACCEL;
  1627. index += 6;
  1628. }
  1629. if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) {
  1630. gyro[0] = (data[index+0] << 8) | data[index+1];
  1631. sensors[0] |= INV_X_GYRO;
  1632. index += 2;
  1633. }
  1634. if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) {
  1635. gyro[1] = (data[index+0] << 8) | data[index+1];
  1636. sensors[0] |= INV_Y_GYRO;
  1637. index += 2;
  1638. }
  1639. if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) {
  1640. gyro[2] = (data[index+0] << 8) | data[index+1];
  1641. sensors[0] |= INV_Z_GYRO;
  1642. index += 2;
  1643. }
  1644. return 0;
  1645. }
  1646. /**
  1647. * @brief Get one unparsed packet from the FIFO.
  1648. * This function should be used if the packet is to be parsed elsewhere.
  1649. * @param[in] length Length of one FIFO packet.
  1650. * @param[in] data FIFO packet.
  1651. * @param[in] more Number of remaining packets.
  1652. */
  1653. int mpu_read_fifo_stream(unsigned short length, unsigned char *data,
  1654. unsigned char *more)
  1655. {
  1656. unsigned char tmp[2];
  1657. unsigned short fifo_count;
  1658. if (!st.chip_cfg.dmp_on)
  1659. return -1;
  1660. if (!st.chip_cfg.sensors)
  1661. return -1;
  1662. if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp))
  1663. return -1;
  1664. fifo_count = (tmp[0] << 8) | tmp[1];
  1665. if (fifo_count < length) {
  1666. more[0] = 0;
  1667. return -1;
  1668. }
  1669. if (fifo_count > (st.hw->max_fifo >> 1)) {
  1670. /* FIFO is 50% full, better check overflow bit. */
  1671. if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp))
  1672. return -1;
  1673. if (tmp[0] & BIT_FIFO_OVERFLOW) {
  1674. mpu_reset_fifo();
  1675. return -2;
  1676. }
  1677. }
  1678. if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data))
  1679. return -1;
  1680. more[0] = fifo_count / length - 1;
  1681. return 0;
  1682. }
  1683. /**
  1684. * @brief Set device to bypass mode.
  1685. * @param[in] bypass_on 1 to enable bypass mode.
  1686. * @return 0 if successful.
  1687. */
  1688. int mpu_set_bypass(unsigned char bypass_on)
  1689. {
  1690. unsigned char tmp;
  1691. if (st.chip_cfg.bypass_mode == bypass_on)
  1692. return 0;
  1693. if (bypass_on) {
  1694. if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp))
  1695. return -1;
  1696. tmp &= ~BIT_AUX_IF_EN;
  1697. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp))
  1698. return -1;
  1699. delay_ms(3);
  1700. tmp = BIT_BYPASS_EN;
  1701. if (st.chip_cfg.active_low_int)
  1702. tmp |= BIT_ACTL;
  1703. if (st.chip_cfg.latched_int)
  1704. tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR;
  1705. if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp))
  1706. return -1;
  1707. } else {
  1708. /* Enable I2C master mode if compass is being used. */
  1709. if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp))
  1710. return -1;
  1711. if (st.chip_cfg.sensors & INV_XYZ_COMPASS)
  1712. tmp |= BIT_AUX_IF_EN;
  1713. else
  1714. tmp &= ~BIT_AUX_IF_EN;
  1715. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp))
  1716. return -1;
  1717. delay_ms(3);
  1718. if (st.chip_cfg.active_low_int)
  1719. tmp = BIT_ACTL;
  1720. else
  1721. tmp = 0;
  1722. if (st.chip_cfg.latched_int)
  1723. tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR;
  1724. if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp))
  1725. return -1;
  1726. }
  1727. st.chip_cfg.bypass_mode = bypass_on;
  1728. return 0;
  1729. }
  1730. /**
  1731. * @brief Set interrupt level.
  1732. * @param[in] active_low 1 for active low, 0 for active high.
  1733. * @return 0 if successful.
  1734. */
  1735. int mpu_set_int_level(unsigned char active_low)
  1736. {
  1737. st.chip_cfg.active_low_int = active_low;
  1738. return 0;
  1739. }
  1740. /**
  1741. * @brief Enable latched interrupts.
  1742. * Any MPU register will clear the interrupt.
  1743. * @param[in] enable 1 to enable, 0 to disable.
  1744. * @return 0 if successful.
  1745. */
  1746. int mpu_set_int_latched(unsigned char enable)
  1747. {
  1748. unsigned char tmp;
  1749. if (st.chip_cfg.latched_int == enable)
  1750. return 0;
  1751. if (enable)
  1752. tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR;
  1753. else
  1754. tmp = 0;
  1755. if (st.chip_cfg.bypass_mode)
  1756. tmp |= BIT_BYPASS_EN;
  1757. if (st.chip_cfg.active_low_int)
  1758. tmp |= BIT_ACTL;
  1759. if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp))
  1760. return -1;
  1761. st.chip_cfg.latched_int = enable;
  1762. return 0;
  1763. }
  1764. #ifdef MPU6050
  1765. static int get_accel_prod_shift(float *st_shift)
  1766. {
  1767. unsigned char tmp[4], shift_code[3], ii;
  1768. if (i2c_read(st.hw->addr, 0x0D, 4, tmp))
  1769. return 0x07;
  1770. shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4);
  1771. shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2);
  1772. shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03);
  1773. for (ii = 0; ii < 3; ii++) {
  1774. if (!shift_code[ii]) {
  1775. st_shift[ii] = 0.f;
  1776. continue;
  1777. }
  1778. /* Equivalent to..
  1779. * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f)
  1780. */
  1781. st_shift[ii] = 0.34f;
  1782. while (--shift_code[ii])
  1783. st_shift[ii] *= 1.034f;
  1784. }
  1785. return 0;
  1786. }
  1787. static int accel_self_test(long *bias_regular, long *bias_st)
  1788. {
  1789. int jj, result = 0;
  1790. float st_shift[3], st_shift_cust, st_shift_var;
  1791. get_accel_prod_shift(st_shift);
  1792. for(jj = 0; jj < 3; jj++) {
  1793. st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f;
  1794. if (st_shift[jj]) {
  1795. st_shift_var = st_shift_cust / st_shift[jj] - 1.f;
  1796. if (fabs(st_shift_var) > test.max_accel_var)
  1797. result |= 1 << jj;
  1798. } else if ((st_shift_cust < test.min_g) ||
  1799. (st_shift_cust > test.max_g))
  1800. result |= 1 << jj;
  1801. }
  1802. return result;
  1803. }
  1804. static int gyro_self_test(long *bias_regular, long *bias_st)
  1805. {
  1806. int jj, result = 0;
  1807. unsigned char tmp[3];
  1808. float st_shift, st_shift_cust, st_shift_var;
  1809. if (i2c_read(st.hw->addr, 0x0D, 3, tmp))
  1810. return 0x07;
  1811. tmp[0] &= 0x1F;
  1812. tmp[1] &= 0x1F;
  1813. tmp[2] &= 0x1F;
  1814. for (jj = 0; jj < 3; jj++) {
  1815. st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f;
  1816. if (tmp[jj]) {
  1817. st_shift = 3275.f / test.gyro_sens;
  1818. while (--tmp[jj])
  1819. st_shift *= 1.046f;
  1820. st_shift_var = st_shift_cust / st_shift - 1.f;
  1821. if (fabs(st_shift_var) > test.max_gyro_var)
  1822. result |= 1 << jj;
  1823. } else if ((st_shift_cust < test.min_dps) ||
  1824. (st_shift_cust > test.max_dps))
  1825. result |= 1 << jj;
  1826. }
  1827. return result;
  1828. }
  1829. #ifdef AK89xx_SECONDARY
  1830. static int compass_self_test(void)
  1831. {
  1832. unsigned char tmp[6];
  1833. unsigned char tries = 10;
  1834. int result = 0x07;
  1835. short data;
  1836. mpu_set_bypass(1);
  1837. tmp[0] = AKM_POWER_DOWN;
  1838. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp))
  1839. return 0x07;
  1840. tmp[0] = AKM_BIT_SELF_TEST;
  1841. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp))
  1842. goto AKM_restore;
  1843. tmp[0] = AKM_MODE_SELF_TEST;
  1844. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp))
  1845. goto AKM_restore;
  1846. do {
  1847. delay_ms(10);
  1848. if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp))
  1849. goto AKM_restore;
  1850. if (tmp[0] & AKM_DATA_READY)
  1851. break;
  1852. } while (tries--);
  1853. if (!(tmp[0] & AKM_DATA_READY))
  1854. goto AKM_restore;
  1855. if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp))
  1856. goto AKM_restore;
  1857. result = 0;
  1858. data = (short)(tmp[1] << 8) | tmp[0];
  1859. if ((data > 100) || (data < -100))
  1860. result |= 0x01;
  1861. data = (short)(tmp[3] << 8) | tmp[2];
  1862. if ((data > 100) || (data < -100))
  1863. result |= 0x02;
  1864. data = (short)(tmp[5] << 8) | tmp[4];
  1865. if ((data > -300) || (data < -1000))
  1866. result |= 0x04;
  1867. AKM_restore:
  1868. tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS;
  1869. i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp);
  1870. tmp[0] = SUPPORTS_AK89xx_HIGH_SENS;
  1871. i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp);
  1872. mpu_set_bypass(0);
  1873. return result;
  1874. }
  1875. #endif
  1876. #endif
  1877. static int get_st_biases(long *gyro, long *accel, unsigned char hw_test)
  1878. {
  1879. unsigned char data[MAX_PACKET_LENGTH];
  1880. unsigned char packet_count, ii;
  1881. unsigned short fifo_count;
  1882. data[0] = 0x01;
  1883. data[1] = 0;
  1884. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data))
  1885. return -1;
  1886. delay_ms(200);
  1887. data[0] = 0;
  1888. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data))
  1889. return -1;
  1890. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data))
  1891. return -1;
  1892. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data))
  1893. return -1;
  1894. if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data))
  1895. return -1;
  1896. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data))
  1897. return -1;
  1898. data[0] = BIT_FIFO_RST | BIT_DMP_RST;
  1899. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data))
  1900. return -1;
  1901. delay_ms(15);
  1902. data[0] = st.test->reg_lpf;
  1903. if (i2c_write(st.hw->addr, st.reg->lpf, 1, data))
  1904. return -1;
  1905. data[0] = st.test->reg_rate_div;
  1906. if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data))
  1907. return -1;
  1908. if (hw_test)
  1909. data[0] = st.test->reg_gyro_fsr | 0xE0;
  1910. else
  1911. data[0] = st.test->reg_gyro_fsr;
  1912. if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data))
  1913. return -1;
  1914. if (hw_test)
  1915. data[0] = st.test->reg_accel_fsr | 0xE0;
  1916. else
  1917. data[0] = test.reg_accel_fsr;
  1918. if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data))
  1919. return -1;
  1920. if (hw_test)
  1921. delay_ms(200);
  1922. /* Fill FIFO for test.wait_ms milliseconds. */
  1923. data[0] = BIT_FIFO_EN;
  1924. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data))
  1925. return -1;
  1926. data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL;
  1927. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data))
  1928. return -1;
  1929. delay_ms(test.wait_ms);
  1930. data[0] = 0;
  1931. if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data))
  1932. return -1;
  1933. if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data))
  1934. return -1;
  1935. fifo_count = (data[0] << 8) | data[1];
  1936. packet_count = fifo_count / MAX_PACKET_LENGTH;
  1937. gyro[0] = gyro[1] = gyro[2] = 0;
  1938. accel[0] = accel[1] = accel[2] = 0;
  1939. for (ii = 0; ii < packet_count; ii++) {
  1940. short accel_cur[3], gyro_cur[3];
  1941. if (i2c_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data))
  1942. return -1;
  1943. accel_cur[0] = ((short)data[0] << 8) | data[1];
  1944. accel_cur[1] = ((short)data[2] << 8) | data[3];
  1945. accel_cur[2] = ((short)data[4] << 8) | data[5];
  1946. accel[0] += (long)accel_cur[0];
  1947. accel[1] += (long)accel_cur[1];
  1948. accel[2] += (long)accel_cur[2];
  1949. gyro_cur[0] = (((short)data[6] << 8) | data[7]);
  1950. gyro_cur[1] = (((short)data[8] << 8) | data[9]);
  1951. gyro_cur[2] = (((short)data[10] << 8) | data[11]);
  1952. gyro[0] += (long)gyro_cur[0];
  1953. gyro[1] += (long)gyro_cur[1];
  1954. gyro[2] += (long)gyro_cur[2];
  1955. }
  1956. #ifdef EMPL_NO_64BIT
  1957. gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count);
  1958. gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count);
  1959. gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count);
  1960. if (has_accel) {
  1961. accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens /
  1962. packet_count);
  1963. accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens /
  1964. packet_count);
  1965. accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens /
  1966. packet_count);
  1967. /* Don't remove gravity! */
  1968. accel[2] -= 65536L;
  1969. }
  1970. #else
  1971. gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count);
  1972. gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count);
  1973. gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count);
  1974. accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens /
  1975. packet_count);
  1976. accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens /
  1977. packet_count);
  1978. accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens /
  1979. packet_count);
  1980. /* Don't remove gravity! */
  1981. if (accel[2] > 0L)
  1982. accel[2] -= 65536L;
  1983. else
  1984. accel[2] += 65536L;
  1985. #endif
  1986. return 0;
  1987. }
  1988. /**
  1989. * @brief Trigger gyro/accel/compass self-test.
  1990. * On success/error, the self-test returns a mask representing the sensor(s)
  1991. * that failed. For each bit, a one (1) represents a "pass" case; conversely,
  1992. * a zero (0) indicates a failure.
  1993. *
  1994. * \n The mask is defined as follows:
  1995. * \n Bit 0: Gyro.
  1996. * \n Bit 1: Accel.
  1997. * \n Bit 2: Compass.
  1998. *
  1999. * \n Currently, the hardware self-test is unsupported for MPU6500. However,
  2000. * this function can still be used to obtain the accel and gyro biases.
  2001. *
  2002. * \n This function must be called with the device either face-up or face-down
  2003. * (z-axis is parallel to gravity).
  2004. * @param[out] gyro Gyro biases in q16 format.
  2005. * @param[out] accel Accel biases (if applicable) in q16 format.
  2006. * @return Result mask (see above).
  2007. */
  2008. int mpu_run_self_test(long *gyro, long *accel)
  2009. {
  2010. #ifdef MPU6050
  2011. const unsigned char tries = 2;
  2012. long gyro_st[3], accel_st[3];
  2013. unsigned char accel_result, gyro_result;
  2014. #ifdef AK89xx_SECONDARY
  2015. unsigned char compass_result;
  2016. #endif
  2017. int ii;
  2018. #endif
  2019. int result;
  2020. unsigned char accel_fsr, fifo_sensors, sensors_on;
  2021. unsigned short gyro_fsr, sample_rate, lpf;
  2022. unsigned char dmp_was_on;
  2023. if (st.chip_cfg.dmp_on) {
  2024. mpu_set_dmp_state(0);
  2025. dmp_was_on = 1;
  2026. } else
  2027. dmp_was_on = 0;
  2028. /* Get initial settings. */
  2029. mpu_get_gyro_fsr(&gyro_fsr);
  2030. mpu_get_accel_fsr(&accel_fsr);
  2031. mpu_get_lpf(&lpf);
  2032. mpu_get_sample_rate(&sample_rate);
  2033. sensors_on = st.chip_cfg.sensors;
  2034. mpu_get_fifo_config(&fifo_sensors);
  2035. /* For older chips, the self-test will be different. */
  2036. #if defined MPU6050
  2037. for (ii = 0; ii < tries; ii++)
  2038. if (!get_st_biases(gyro, accel, 0))
  2039. break;
  2040. if (ii == tries) {
  2041. /* If we reach this point, we most likely encountered an I2C error.
  2042. * We'll just report an error for all three sensors.
  2043. */
  2044. result = 0;
  2045. goto restore;
  2046. }
  2047. for (ii = 0; ii < tries; ii++)
  2048. if (!get_st_biases(gyro_st, accel_st, 1))
  2049. break;
  2050. if (ii == tries) {
  2051. /* Again, probably an I2C error. */
  2052. result = 0;
  2053. goto restore;
  2054. }
  2055. accel_result = accel_self_test(accel, accel_st);
  2056. gyro_result = gyro_self_test(gyro, gyro_st);
  2057. result = 0;
  2058. if (!gyro_result)
  2059. result |= 0x01;
  2060. if (!accel_result)
  2061. result |= 0x02;
  2062. #ifdef AK89xx_SECONDARY
  2063. compass_result = compass_self_test();
  2064. if (!compass_result)
  2065. result |= 0x04;
  2066. #endif
  2067. restore:
  2068. #elif defined MPU6500
  2069. /* For now, this function will return a "pass" result for all three sensors
  2070. * for compatibility with current test applications.
  2071. */
  2072. get_st_biases(gyro, accel, 0);
  2073. result = 0x7;
  2074. #endif
  2075. /* Set to invalid values to ensure no I2C writes are skipped. */
  2076. st.chip_cfg.gyro_fsr = 0xFF;
  2077. st.chip_cfg.accel_fsr = 0xFF;
  2078. st.chip_cfg.lpf = 0xFF;
  2079. st.chip_cfg.sample_rate = 0xFFFF;
  2080. st.chip_cfg.sensors = 0xFF;
  2081. st.chip_cfg.fifo_enable = 0xFF;
  2082. st.chip_cfg.clk_src = INV_CLK_PLL;
  2083. mpu_set_gyro_fsr(gyro_fsr);
  2084. mpu_set_accel_fsr(accel_fsr);
  2085. mpu_set_lpf(lpf);
  2086. mpu_set_sample_rate(sample_rate);
  2087. mpu_set_sensors(sensors_on);
  2088. mpu_configure_fifo(fifo_sensors);
  2089. if (dmp_was_on)
  2090. mpu_set_dmp_state(1);
  2091. return result;
  2092. }
  2093. /**
  2094. * @brief Write to the DMP memory.
  2095. * This function prevents I2C writes past the bank boundaries. The DMP memory
  2096. * is only accessible when the chip is awake.
  2097. * @param[in] mem_addr Memory location (bank << 8 | start address)
  2098. * @param[in] length Number of bytes to write.
  2099. * @param[in] data Bytes to write to memory.
  2100. * @return 0 if successful.
  2101. */
  2102. int mpu_write_mem(unsigned short mem_addr, unsigned short length,
  2103. unsigned char *data)
  2104. {
  2105. unsigned char tmp[2];
  2106. if (!data)
  2107. return -1;
  2108. if (!st.chip_cfg.sensors)
  2109. return -1;
  2110. tmp[0] = (unsigned char)(mem_addr >> 8);
  2111. tmp[1] = (unsigned char)(mem_addr & 0xFF);
  2112. /* Check bank boundaries. */
  2113. if (tmp[1] + length > st.hw->bank_size)
  2114. return -1;
  2115. if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp))
  2116. return -1;
  2117. if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data))
  2118. return -1;
  2119. return 0;
  2120. }
  2121. /**
  2122. * @brief Read from the DMP memory.
  2123. * This function prevents I2C reads past the bank boundaries. The DMP memory
  2124. * is only accessible when the chip is awake.
  2125. * @param[in] mem_addr Memory location (bank << 8 | start address)
  2126. * @param[in] length Number of bytes to read.
  2127. * @param[out] data Bytes read from memory.
  2128. * @return 0 if successful.
  2129. */
  2130. int mpu_read_mem(unsigned short mem_addr, unsigned short length,
  2131. unsigned char *data)
  2132. {
  2133. unsigned char tmp[2];
  2134. if (!data)
  2135. return -1;
  2136. if (!st.chip_cfg.sensors)
  2137. return -1;
  2138. tmp[0] = (unsigned char)(mem_addr >> 8);
  2139. tmp[1] = (unsigned char)(mem_addr & 0xFF);
  2140. /* Check bank boundaries. */
  2141. if (tmp[1] + length > st.hw->bank_size)
  2142. return -1;
  2143. if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp))
  2144. return -1;
  2145. if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data))
  2146. return -1;
  2147. return 0;
  2148. }
  2149. /**
  2150. * @brief Load and verify DMP image.
  2151. * @param[in] length Length of DMP image.
  2152. * @param[in] firmware DMP code.
  2153. * @param[in] start_addr Starting address of DMP code memory.
  2154. * @param[in] sample_rate Fixed sampling rate used when DMP is enabled.
  2155. * @return 0 if successful.
  2156. */
  2157. int mpu_load_firmware(unsigned short length, const unsigned char *firmware,
  2158. unsigned short start_addr, unsigned short sample_rate)
  2159. {
  2160. unsigned short ii;
  2161. unsigned short this_write;
  2162. /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */
  2163. #define LOAD_CHUNK (16)
  2164. unsigned char cur[LOAD_CHUNK], tmp[2];
  2165. if (st.chip_cfg.dmp_loaded)
  2166. /* DMP should only be loaded once. */
  2167. return -1;
  2168. if (!firmware)
  2169. return -1;
  2170. for (ii = 0; ii < length; ii += this_write) {
  2171. this_write = min(LOAD_CHUNK, length - ii);
  2172. if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii]))
  2173. return -1;
  2174. if (mpu_read_mem(ii, this_write, cur))
  2175. return -1;
  2176. if (memcmp(firmware+ii, cur, this_write))
  2177. return -2;
  2178. }
  2179. /* Set program start address. */
  2180. tmp[0] = start_addr >> 8;
  2181. tmp[1] = start_addr & 0xFF;
  2182. if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp))
  2183. return -1;
  2184. st.chip_cfg.dmp_loaded = 1;
  2185. st.chip_cfg.dmp_sample_rate = sample_rate;
  2186. return 0;
  2187. }
  2188. /**
  2189. * @brief Enable/disable DMP support.
  2190. * @param[in] enable 1 to turn on the DMP.
  2191. * @return 0 if successful.
  2192. */
  2193. int mpu_set_dmp_state(unsigned char enable)
  2194. {
  2195. unsigned char tmp;
  2196. if (st.chip_cfg.dmp_on == enable)
  2197. return 0;
  2198. if (enable) {
  2199. if (!st.chip_cfg.dmp_loaded)
  2200. return -1;
  2201. /* Disable data ready interrupt. */
  2202. set_int_enable(0);
  2203. /* Disable bypass mode. */
  2204. mpu_set_bypass(0);
  2205. /* Keep constant sample rate, FIFO rate controlled by DMP. */
  2206. mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate);
  2207. /* Remove FIFO elements. */
  2208. tmp = 0;
  2209. i2c_write(st.hw->addr, 0x23, 1, &tmp);
  2210. st.chip_cfg.dmp_on = 1;
  2211. /* Enable DMP interrupt. */
  2212. set_int_enable(1);
  2213. mpu_reset_fifo();
  2214. } else {
  2215. /* Disable DMP interrupt. */
  2216. set_int_enable(0);
  2217. /* Restore FIFO settings. */
  2218. tmp = st.chip_cfg.fifo_enable;
  2219. i2c_write(st.hw->addr, 0x23, 1, &tmp);
  2220. st.chip_cfg.dmp_on = 0;
  2221. mpu_reset_fifo();
  2222. }
  2223. return 0;
  2224. }
  2225. /**
  2226. * @brief Get DMP state.
  2227. * @param[out] enabled 1 if enabled.
  2228. * @return 0 if successful.
  2229. */
  2230. int mpu_get_dmp_state(unsigned char *enabled)
  2231. {
  2232. enabled[0] = st.chip_cfg.dmp_on;
  2233. return 0;
  2234. }
  2235. /* This initialization is similar to the one in ak8975.c. */
  2236. int setup_compass(void)
  2237. {
  2238. #ifdef AK89xx_SECONDARY
  2239. unsigned char data[4], akm_addr;
  2240. mpu_set_bypass(1);
  2241. /* Find compass. Possible addresses range from 0x0C to 0x0F. */
  2242. for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) {
  2243. int result;
  2244. result = i2c_read(akm_addr, AKM_REG_WHOAMI, 1, data);
  2245. if (!result && (data[0] == AKM_WHOAMI))
  2246. break;
  2247. }
  2248. if (akm_addr > 0x0F) {
  2249. /* TODO: Handle this case in all compass-related functions. */
  2250. log_e("Compass not found.\n");
  2251. return -1;
  2252. }
  2253. st.chip_cfg.compass_addr = akm_addr;
  2254. data[0] = AKM_POWER_DOWN;
  2255. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data))
  2256. return -1;
  2257. delay_ms(1);
  2258. data[0] = AKM_FUSE_ROM_ACCESS;
  2259. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data))
  2260. return -1;
  2261. delay_ms(1);
  2262. /* Get sensitivity adjustment data from fuse ROM. */
  2263. if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data))
  2264. return -1;
  2265. st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128;
  2266. st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128;
  2267. st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128;
  2268. data[0] = AKM_POWER_DOWN;
  2269. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data))
  2270. return -1;
  2271. delay_ms(1);
  2272. mpu_set_bypass(0);
  2273. /* Set up master mode, master clock, and ES bit. */
  2274. data[0] = 0x40;
  2275. if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data))
  2276. return -1;
  2277. /* Slave 0 reads from AKM data registers. */
  2278. data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr;
  2279. if (i2c_write(st.hw->addr, st.reg->s0_addr, 1, data))
  2280. return -1;
  2281. /* Compass reads start at this register. */
  2282. data[0] = AKM_REG_ST1;
  2283. if (i2c_write(st.hw->addr, st.reg->s0_reg, 1, data))
  2284. return -1;
  2285. /* Enable slave 0, 8-byte reads. */
  2286. data[0] = BIT_SLAVE_EN | 8;
  2287. if (i2c_write(st.hw->addr, st.reg->s0_ctrl, 1, data))
  2288. return -1;
  2289. /* Slave 1 changes AKM measurement mode. */
  2290. data[0] = st.chip_cfg.compass_addr;
  2291. if (i2c_write(st.hw->addr, st.reg->s1_addr, 1, data))
  2292. return -1;
  2293. /* AKM measurement mode register. */
  2294. data[0] = AKM_REG_CNTL;
  2295. if (i2c_write(st.hw->addr, st.reg->s1_reg, 1, data))
  2296. return -1;
  2297. /* Enable slave 1, 1-byte writes. */
  2298. data[0] = BIT_SLAVE_EN | 1;
  2299. if (i2c_write(st.hw->addr, st.reg->s1_ctrl, 1, data))
  2300. return -1;
  2301. /* Set slave 1 data. */
  2302. data[0] = AKM_SINGLE_MEASUREMENT;
  2303. if (i2c_write(st.hw->addr, st.reg->s1_do, 1, data))
  2304. return -1;
  2305. /* Trigger slave 0 and slave 1 actions at each sample. */
  2306. data[0] = 0x03;
  2307. if (i2c_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data))
  2308. return -1;
  2309. #ifdef MPU9150
  2310. /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */
  2311. data[0] = BIT_I2C_MST_VDDIO;
  2312. if (i2c_write(st.hw->addr, st.reg->yg_offs_tc, 1, data))
  2313. return -1;
  2314. #endif
  2315. return 0;
  2316. #else
  2317. return -1;
  2318. #endif
  2319. }
  2320. /**
  2321. * @brief Read raw compass data.
  2322. * @param[out] data Raw data in hardware units.
  2323. * @param[out] timestamp Timestamp in milliseconds. Null if not needed.
  2324. * @return 0 if successful.
  2325. */
  2326. int mpu_get_compass_reg(short *data, unsigned long *timestamp)
  2327. {
  2328. #ifdef AK89xx_SECONDARY
  2329. unsigned char tmp[9];
  2330. if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS))
  2331. return -1;
  2332. #ifdef AK89xx_BYPASS
  2333. if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp))
  2334. return -1;
  2335. tmp[8] = AKM_SINGLE_MEASUREMENT;
  2336. if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8))
  2337. return -1;
  2338. #else
  2339. if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp))
  2340. return -1;
  2341. #endif
  2342. #if defined AK8975_SECONDARY
  2343. /* AK8975 doesn't have the overrun error bit. */
  2344. if (!(tmp[0] & AKM_DATA_READY))
  2345. return -2;
  2346. if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR))
  2347. return -3;
  2348. #elif defined AK8963_SECONDARY
  2349. /* AK8963 doesn't have the data read error bit. */
  2350. if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN))
  2351. return -2;
  2352. if (tmp[7] & AKM_OVERFLOW)
  2353. return -3;
  2354. #endif
  2355. data[0] = (tmp[2] << 8) | tmp[1];
  2356. data[1] = (tmp[4] << 8) | tmp[3];
  2357. data[2] = (tmp[6] << 8) | tmp[5];
  2358. data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8;
  2359. data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8;
  2360. data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8;
  2361. if (timestamp)
  2362. get_ms(timestamp);
  2363. return 0;
  2364. #else
  2365. return -1;
  2366. #endif
  2367. }
  2368. /**
  2369. * @brief Get the compass full-scale range.
  2370. * @param[out] fsr Current full-scale range.
  2371. * @return 0 if successful.
  2372. */
  2373. int mpu_get_compass_fsr(unsigned short *fsr)
  2374. {
  2375. #ifdef AK89xx_SECONDARY
  2376. fsr[0] = st.hw->compass_fsr;
  2377. return 0;
  2378. #else
  2379. return -1;
  2380. #endif
  2381. }
  2382. /**
  2383. * @brief Enters LP accel motion interrupt mode.
  2384. * The behavior of this feature is very different between the MPU6050 and the
  2385. * MPU6500. Each chip's version of this feature is explained below.
  2386. *
  2387. * \n MPU6050:
  2388. * \n When this mode is first enabled, the hardware captures a single accel
  2389. * sample, and subsequent samples are compared with this one to determine if
  2390. * the device is in motion. Therefore, whenever this "locked" sample needs to
  2391. * be changed, this function must be called again.
  2392. *
  2393. * \n The hardware motion threshold can be between 32mg and 8160mg in 32mg
  2394. * increments.
  2395. *
  2396. * \n Low-power accel mode supports the following frequencies:
  2397. * \n 1.25Hz, 5Hz, 20Hz, 40Hz
  2398. *
  2399. * \n MPU6500:
  2400. * \n Unlike the MPU6050 version, the hardware does not "lock in" a reference
  2401. * sample. The hardware monitors the accel data and detects any large change
  2402. * over a short period of time.
  2403. *
  2404. * \n The hardware motion threshold can be between 4mg and 1020mg in 4mg
  2405. * increments.
  2406. *
  2407. * \n MPU6500 Low-power accel mode supports the following frequencies:
  2408. * \n 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz
  2409. *
  2410. * \n\n NOTES:
  2411. * \n The driver will round down @e thresh to the nearest supported value if
  2412. * an unsupported threshold is selected.
  2413. * \n To select a fractional wake-up frequency, round down the value passed to
  2414. * @e lpa_freq.
  2415. * \n The MPU6500 does not support a delay parameter. If this function is used
  2416. * for the MPU6500, the value passed to @e time will be ignored.
  2417. * \n To disable this mode, set @e lpa_freq to zero. The driver will restore
  2418. * the previous configuration.
  2419. *
  2420. * @param[in] thresh Motion threshold in mg.
  2421. * @param[in] time Duration in milliseconds that the accel data must
  2422. * exceed @e thresh before motion is reported.
  2423. * @param[in] lpa_freq Minimum sampling rate, or zero to disable.
  2424. * @return 0 if successful.
  2425. */
  2426. int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time,
  2427. unsigned char lpa_freq)
  2428. {
  2429. unsigned char data[3];
  2430. if (lpa_freq) {
  2431. unsigned char thresh_hw;
  2432. #if defined MPU6050
  2433. /* TODO: Make these const/#defines. */
  2434. /* 1LSb = 32mg. */
  2435. if (thresh > 8160)
  2436. thresh_hw = 255;
  2437. else if (thresh < 32)
  2438. thresh_hw = 1;
  2439. else
  2440. thresh_hw = thresh >> 5;
  2441. #elif defined MPU6500
  2442. /* 1LSb = 4mg. */
  2443. if (thresh > 1020)
  2444. thresh_hw = 255;
  2445. else if (thresh < 4)
  2446. thresh_hw = 1;
  2447. else
  2448. thresh_hw = thresh >> 2;
  2449. #endif
  2450. if (!time)
  2451. /* Minimum duration must be 1ms. */
  2452. time = 1;
  2453. #if defined MPU6050
  2454. if (lpa_freq > 40)
  2455. #elif defined MPU6500
  2456. if (lpa_freq > 640)
  2457. #endif
  2458. /* At this point, the chip has not been re-configured, so the
  2459. * function can safely exit.
  2460. */
  2461. return -1;
  2462. if (!st.chip_cfg.int_motion_only) {
  2463. /* Store current settings for later. */
  2464. if (st.chip_cfg.dmp_on) {
  2465. mpu_set_dmp_state(0);
  2466. st.chip_cfg.cache.dmp_on = 1;
  2467. } else
  2468. st.chip_cfg.cache.dmp_on = 0;
  2469. mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr);
  2470. mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr);
  2471. mpu_get_lpf(&st.chip_cfg.cache.lpf);
  2472. mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate);
  2473. st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors;
  2474. mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors);
  2475. }
  2476. #ifdef MPU6050
  2477. /* Disable hardware interrupts for now. */
  2478. set_int_enable(0);
  2479. /* Enter full-power accel-only mode. */
  2480. mpu_lp_accel_mode(0);
  2481. /* Override current LPF (and HPF) settings to obtain a valid accel
  2482. * reading.
  2483. */
  2484. data[0] = INV_FILTER_256HZ_NOLPF2;
  2485. if (i2c_write(st.hw->addr, st.reg->lpf, 1, data))
  2486. return -1;
  2487. /* NOTE: Digital high pass filter should be configured here. Since this
  2488. * driver doesn't modify those bits anywhere, they should already be
  2489. * cleared by default.
  2490. */
  2491. /* Configure the device to send motion interrupts. */
  2492. /* Enable motion interrupt. */
  2493. data[0] = BIT_MOT_INT_EN;
  2494. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data))
  2495. goto lp_int_restore;
  2496. /* Set motion interrupt parameters. */
  2497. data[0] = thresh_hw;
  2498. data[1] = time;
  2499. if (i2c_write(st.hw->addr, st.reg->motion_thr, 2, data))
  2500. goto lp_int_restore;
  2501. /* Force hardware to "lock" current accel sample. */
  2502. delay_ms(5);
  2503. data[0] = (st.chip_cfg.accel_fsr << 3) | BITS_HPF;
  2504. if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data))
  2505. goto lp_int_restore;
  2506. /* Set up LP accel mode. */
  2507. data[0] = BIT_LPA_CYCLE;
  2508. if (lpa_freq == 1)
  2509. data[1] = INV_LPA_1_25HZ;
  2510. else if (lpa_freq <= 5)
  2511. data[1] = INV_LPA_5HZ;
  2512. else if (lpa_freq <= 20)
  2513. data[1] = INV_LPA_20HZ;
  2514. else
  2515. data[1] = INV_LPA_40HZ;
  2516. data[1] = (data[1] << 6) | BIT_STBY_XYZG;
  2517. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data))
  2518. goto lp_int_restore;
  2519. st.chip_cfg.int_motion_only = 1;
  2520. return 0;
  2521. #elif defined MPU6500
  2522. /* Disable hardware interrupts. */
  2523. set_int_enable(0);
  2524. /* Enter full-power accel-only mode, no FIFO/DMP. */
  2525. data[0] = 0;
  2526. data[1] = 0;
  2527. data[2] = BIT_STBY_XYZG;
  2528. if (i2c_write(st.hw->addr, st.reg->user_ctrl, 3, data))
  2529. goto lp_int_restore;
  2530. /* Set motion threshold. */
  2531. data[0] = thresh_hw;
  2532. if (i2c_write(st.hw->addr, st.reg->motion_thr, 1, data))
  2533. goto lp_int_restore;
  2534. /* Set wake frequency. */
  2535. if (lpa_freq == 1)
  2536. data[0] = INV_LPA_1_25HZ;
  2537. else if (lpa_freq == 2)
  2538. data[0] = INV_LPA_2_5HZ;
  2539. else if (lpa_freq <= 5)
  2540. data[0] = INV_LPA_5HZ;
  2541. else if (lpa_freq <= 10)
  2542. data[0] = INV_LPA_10HZ;
  2543. else if (lpa_freq <= 20)
  2544. data[0] = INV_LPA_20HZ;
  2545. else if (lpa_freq <= 40)
  2546. data[0] = INV_LPA_40HZ;
  2547. else if (lpa_freq <= 80)
  2548. data[0] = INV_LPA_80HZ;
  2549. else if (lpa_freq <= 160)
  2550. data[0] = INV_LPA_160HZ;
  2551. else if (lpa_freq <= 320)
  2552. data[0] = INV_LPA_320HZ;
  2553. else
  2554. data[0] = INV_LPA_640HZ;
  2555. if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, data))
  2556. goto lp_int_restore;
  2557. /* Enable motion interrupt (MPU6500 version). */
  2558. data[0] = BITS_WOM_EN;
  2559. if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data))
  2560. goto lp_int_restore;
  2561. /* Enable cycle mode. */
  2562. data[0] = BIT_LPA_CYCLE;
  2563. if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data))
  2564. goto lp_int_restore;
  2565. /* Enable interrupt. */
  2566. data[0] = BIT_MOT_INT_EN;
  2567. if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data))
  2568. goto lp_int_restore;
  2569. st.chip_cfg.int_motion_only = 1;
  2570. return 0;
  2571. #endif
  2572. } else {
  2573. /* Don't "restore" the previous state if no state has been saved. */
  2574. int ii;
  2575. char *cache_ptr = (char*)&st.chip_cfg.cache;
  2576. for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) {
  2577. if (cache_ptr[ii] != 0)
  2578. goto lp_int_restore;
  2579. }
  2580. /* If we reach this point, motion interrupt mode hasn't been used yet. */
  2581. return -1;
  2582. }
  2583. lp_int_restore:
  2584. /* Set to invalid values to ensure no I2C writes are skipped. */
  2585. st.chip_cfg.gyro_fsr = 0xFF;
  2586. st.chip_cfg.accel_fsr = 0xFF;
  2587. st.chip_cfg.lpf = 0xFF;
  2588. st.chip_cfg.sample_rate = 0xFFFF;
  2589. st.chip_cfg.sensors = 0xFF;
  2590. st.chip_cfg.fifo_enable = 0xFF;
  2591. st.chip_cfg.clk_src = INV_CLK_PLL;
  2592. mpu_set_sensors(st.chip_cfg.cache.sensors_on);
  2593. mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr);
  2594. mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr);
  2595. mpu_set_lpf(st.chip_cfg.cache.lpf);
  2596. mpu_set_sample_rate(st.chip_cfg.cache.sample_rate);
  2597. mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors);
  2598. if (st.chip_cfg.cache.dmp_on)
  2599. mpu_set_dmp_state(1);
  2600. #ifdef MPU6500
  2601. /* Disable motion interrupt (MPU6500 version). */
  2602. data[0] = 0;
  2603. if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data))
  2604. goto lp_int_restore;
  2605. #endif
  2606. st.chip_cfg.int_motion_only = 0;
  2607. return 0;
  2608. }
  2609. //
  2610. //添加的代码部分
  2611. //
  2612. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  2613. //ALIENTEK精英STM32开发板V3
  2614. //MPU6050 DMP 驱动代码
  2615. //正点原子@ALIENTEK
  2616. //技术论坛:www.openedv.com
  2617. //创建日期:2015/1/17
  2618. //版本:V1.0
  2619. //版权所有,盗版必究。
  2620. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
  2621. //All rights reserved
  2622. //
  2623. //q30格式,long转float时的除数.
  2624. #define q30 1073741824.0f
  2625. //陀螺仪方向设置
  2626. static signed char gyro_orientation[9] = { 1, 0, 0,
  2627. 0, 1, 0,
  2628. 0, 0, 1};
  2629. //MPU6050自测试
  2630. //返回值:0,正常
  2631. // 其他,失败
  2632. u8 run_self_test(void)
  2633. {
  2634. int result;
  2635. //char test_packet[4] = {0};
  2636. long gyro[3], accel[3];
  2637. result = mpu_run_self_test(gyro, accel);
  2638. if (result == 0x7)
  2639. {
  2640. /* Test passed. We can trust the gyro data here, so let's push it down
  2641. * to the DMP.
  2642. */
  2643. float sens;
  2644. unsigned short accel_sens;
  2645. mpu_get_gyro_sens(&sens);
  2646. gyro[0] = (long)(gyro[0] * sens);
  2647. gyro[1] = (long)(gyro[1] * sens);
  2648. gyro[2] = (long)(gyro[2] * sens);
  2649. dmp_set_gyro_bias(gyro);
  2650. mpu_get_accel_sens(&accel_sens);
  2651. accel[0] *= accel_sens;
  2652. accel[1] *= accel_sens;
  2653. accel[2] *= accel_sens;
  2654. dmp_set_accel_bias(accel);
  2655. return 0;
  2656. }else return 1;
  2657. }
  2658. //陀螺仪方向控制
  2659. unsigned short inv_orientation_matrix_to_scalar(
  2660. const signed char *mtx)
  2661. {
  2662. unsigned short scalar;
  2663. /*
  2664. XYZ 010_001_000 Identity Matrix
  2665. XZY 001_010_000
  2666. YXZ 010_000_001
  2667. YZX 000_010_001
  2668. ZXY 001_000_010
  2669. ZYX 000_001_010
  2670. */
  2671. scalar = inv_row_2_scale(mtx);
  2672. scalar |= inv_row_2_scale(mtx + 3) << 3;
  2673. scalar |= inv_row_2_scale(mtx + 6) << 6;
  2674. return scalar;
  2675. }
  2676. //方向转换
  2677. unsigned short inv_row_2_scale(const signed char *row)
  2678. {
  2679. unsigned short b;
  2680. if (row[0] > 0)
  2681. b = 0;
  2682. else if (row[0] < 0)
  2683. b = 4;
  2684. else if (row[1] > 0)
  2685. b = 1;
  2686. else if (row[1] < 0)
  2687. b = 5;
  2688. else if (row[2] > 0)
  2689. b = 2;
  2690. else if (row[2] < 0)
  2691. b = 6;
  2692. else
  2693. b = 7; // error
  2694. return b;
  2695. }
  2696. //空函数,未用到.
  2697. void mget_ms(unsigned long *time)
  2698. {
  2699. }
  2700. //mpu6050,dmp初始化
  2701. //返回值:0,正常
  2702. // 其他,失败
  2703. u8 mpu_dmp_init(void)
  2704. {
  2705. u8 res=0;
  2706. MPU_IIC_Init(); //初始化IIC总线
  2707. if(mpu_init()==0) //初始化MPU6050
  2708. {
  2709. res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL);//设置所需要的传感器
  2710. if(res)return 1;
  2711. res=mpu_configure_fifo(INV_XYZ_GYRO|INV_XYZ_ACCEL);//设置FIFO
  2712. if(res)return 2;
  2713. res=mpu_set_sample_rate(DEFAULT_MPU_HZ); //设置采样率
  2714. if(res)return 3;
  2715. res=dmp_load_motion_driver_firmware(); //加载dmp固件
  2716. if(res)return 4;
  2717. res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向
  2718. if(res)return 5;
  2719. res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP| //设置dmp功能
  2720. DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO|
  2721. DMP_FEATURE_GYRO_CAL);
  2722. if(res)return 6;
  2723. res=dmp_set_fifo_rate(DEFAULT_MPU_HZ); //设置DMP输出速率(最大不超过200Hz)
  2724. if(res)return 7;
  2725. res=run_self_test(); //自检
  2726. // if(res)return 8;
  2727. res=mpu_set_dmp_state(1); //使能DMP
  2728. if(res)return 9;
  2729. }else return 10;
  2730. return 0;
  2731. }
  2732. //得到dmp处理后的数据(注意,本函数需要比较多堆栈,局部变量有点多)
  2733. //pitch:俯仰角 精度:0.1° 范围:-90.0° <---> +90.0°
  2734. //roll:横滚角 精度:0.1° 范围:-180.0°<---> +180.0°
  2735. //yaw:航向角 精度:0.1° 范围:-180.0°<---> +180.0°
  2736. //返回值:0,正常
  2737. // 其他,失败
  2738. u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw)
  2739. {
  2740. float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
  2741. unsigned long sensor_timestamp;
  2742. short gyro[3], accel[3], sensors;
  2743. unsigned char more;
  2744. long quat[4];
  2745. if(dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more))return 1;
  2746. /* Gyro and accel data are written to the FIFO by the DMP in chip frame and hardware units.
  2747. * This behavior is convenient because it keeps the gyro and accel outputs of dmp_read_fifo and mpu_read_fifo consistent.
  2748. **/
  2749. /*if (sensors & INV_XYZ_GYRO )
  2750. send_packet(PACKET_TYPE_GYRO, gyro);
  2751. if (sensors & INV_XYZ_ACCEL)
  2752. send_packet(PACKET_TYPE_ACCEL, accel); */
  2753. /* Unlike gyro and accel, quaternions are written to the FIFO in the body frame, q30.
  2754. * The orientation is set by the scalar passed to dmp_set_orientation during initialization.
  2755. **/
  2756. if(sensors&INV_WXYZ_QUAT)
  2757. {
  2758. q0 = quat[0] / q30; //q30格式转换为浮点数
  2759. q1 = quat[1] / q30;
  2760. q2 = quat[2] / q30;
  2761. q3 = quat[3] / q30;
  2762. //计算得到俯仰角/横滚角/航向角
  2763. *pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch
  2764. *roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
  2765. *yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw
  2766. }else return 2;
  2767. return 0;
  2768. }

(6)inv_mpu.h

  1. /*
  2. $License:
  3. Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
  4. See included License.txt for License information.
  5. $
  6. */
  7. /**
  8. * @addtogroup DRIVERS Sensor Driver Layer
  9. * @brief Hardware drivers to communicate with sensors via I2C.
  10. *
  11. * @{
  12. * @file inv_mpu.h
  13. * @brief An I2C-based driver for Invensense gyroscopes.
  14. * @details This driver currently works for the following devices:
  15. * MPU6050
  16. * MPU6500
  17. * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus)
  18. * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus)
  19. */
  20. #ifndef _INV_MPU_H_
  21. #define _INV_MPU_H_
  22. #include "stm32f10x.h"
  23. //定义输出速度
  24. #define DEFAULT_MPU_HZ (100) //200Hz
  25. #define INV_X_GYRO (0x40)
  26. #define INV_Y_GYRO (0x20)
  27. #define INV_Z_GYRO (0x10)
  28. #define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)
  29. #define INV_XYZ_ACCEL (0x08)
  30. #define INV_XYZ_COMPASS (0x01)
  31. //移植官方MSP430 DMP驱动过来
  32. struct int_param_s {
  33. //#if defined EMPL_TARGET_MSP430 || defined MOTION_DRIVER_TARGET_MSP430
  34. void (*cb)(void);
  35. unsigned short pin;
  36. unsigned char lp_exit;
  37. unsigned char active_low;
  38. //#elif defined EMPL_TARGET_UC3L0
  39. // unsigned long pin;
  40. // void (*cb)(volatile void*);
  41. // void *arg;
  42. //#endif
  43. };
  44. #define MPU_INT_STATUS_DATA_READY (0x0001)
  45. #define MPU_INT_STATUS_DMP (0x0002)
  46. #define MPU_INT_STATUS_PLL_READY (0x0004)
  47. #define MPU_INT_STATUS_I2C_MST (0x0008)
  48. #define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010)
  49. #define MPU_INT_STATUS_ZMOT (0x0020)
  50. #define MPU_INT_STATUS_MOT (0x0040)
  51. #define MPU_INT_STATUS_FREE_FALL (0x0080)
  52. #define MPU_INT_STATUS_DMP_0 (0x0100)
  53. #define MPU_INT_STATUS_DMP_1 (0x0200)
  54. #define MPU_INT_STATUS_DMP_2 (0x0400)
  55. #define MPU_INT_STATUS_DMP_3 (0x0800)
  56. #define MPU_INT_STATUS_DMP_4 (0x1000)
  57. #define MPU_INT_STATUS_DMP_5 (0x2000)
  58. /* Set up APIs */
  59. int mpu_init(void);
  60. int mpu_init_slave(void);
  61. int mpu_set_bypass(unsigned char bypass_on);
  62. /* Configuration APIs */
  63. int mpu_lp_accel_mode(unsigned char rate);
  64. int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time,
  65. unsigned char lpa_freq);
  66. int mpu_set_int_level(unsigned char active_low);
  67. int mpu_set_int_latched(unsigned char enable);
  68. int mpu_set_dmp_state(unsigned char enable);
  69. int mpu_get_dmp_state(unsigned char *enabled);
  70. int mpu_get_lpf(unsigned short *lpf);
  71. int mpu_set_lpf(unsigned short lpf);
  72. int mpu_get_gyro_fsr(unsigned short *fsr);
  73. int mpu_set_gyro_fsr(unsigned short fsr);
  74. int mpu_get_accel_fsr(unsigned char *fsr);
  75. int mpu_set_accel_fsr(unsigned char fsr);
  76. int mpu_get_compass_fsr(unsigned short *fsr);
  77. int mpu_get_gyro_sens(float *sens);
  78. int mpu_get_accel_sens(unsigned short *sens);
  79. int mpu_get_sample_rate(unsigned short *rate);
  80. int mpu_set_sample_rate(unsigned short rate);
  81. int mpu_get_compass_sample_rate(unsigned short *rate);
  82. int mpu_set_compass_sample_rate(unsigned short rate);
  83. int mpu_get_fifo_config(unsigned char *sensors);
  84. int mpu_configure_fifo(unsigned char sensors);
  85. int mpu_get_power_state(unsigned char *power_on);
  86. int mpu_set_sensors(unsigned char sensors);
  87. int mpu_set_accel_bias(const long *accel_bias);
  88. /* Data getter/setter APIs */
  89. int mpu_get_gyro_reg(short *data, unsigned long *timestamp);
  90. int mpu_get_accel_reg(short *data, unsigned long *timestamp);
  91. int mpu_get_compass_reg(short *data, unsigned long *timestamp);
  92. int mpu_get_temperature(long *data, unsigned long *timestamp);
  93. int mpu_get_int_status(short *status);
  94. int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp,
  95. unsigned char *sensors, unsigned char *more);
  96. int mpu_read_fifo_stream(unsigned short length, unsigned char *data,
  97. unsigned char *more);
  98. int mpu_reset_fifo(void);
  99. int mpu_write_mem(unsigned short mem_addr, unsigned short length,
  100. unsigned char *data);
  101. int mpu_read_mem(unsigned short mem_addr, unsigned short length,
  102. unsigned char *data);
  103. int mpu_load_firmware(unsigned short length, const unsigned char *firmware,
  104. unsigned short start_addr, unsigned short sample_rate);
  105. int mpu_reg_dump(void);
  106. int mpu_read_reg(unsigned char reg, unsigned char *data);
  107. int mpu_run_self_test(long *gyro, long *accel);
  108. int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char));
  109. //自行添加的一些函数
  110. void mget_ms(unsigned long *time);
  111. unsigned short inv_row_2_scale(const signed char *row);
  112. unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx);
  113. u8 run_self_test(void);
  114. u8 mpu_dmp_init(void);
  115. u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw);
  116. #endif /* #ifndef _INV_MPU_H_ */

(7)inv_mpu_dmp_motion_driver.c

  1. /*
  2. $License:
  3. Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
  4. See included License.txt for License information.
  5. $
  6. */
  7. /**
  8. * @addtogroup DRIVERS Sensor Driver Layer
  9. * @brief Hardware drivers to communicate with sensors via I2C.
  10. *
  11. * @{
  12. * @file inv_mpu_dmp_motion_driver.c
  13. * @brief DMP image and interface functions.
  14. * @details All functions are preceded by the dmp_ prefix to
  15. * differentiate among MPL and general driver function calls.
  16. */
  17. #include <stdio.h>
  18. #include <stdint.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "inv_mpu.h"
  23. #include "inv_mpu_dmp_motion_driver.h"
  24. #include "dmpKey.h"
  25. #include "dmpmap.h"
  26. #include "usart.h"
  27. #include "delay.h"
  28. //定义目标板采用MSP430
  29. #define MOTION_DRIVER_TARGET_MSP430
  30. /* The following functions must be defined for this platform:
  31. * i2c_write(unsigned char slave_addr, unsigned char reg_addr,
  32. * unsigned char length, unsigned char const *data)
  33. * i2c_read(unsigned char slave_addr, unsigned char reg_addr,
  34. * unsigned char length, unsigned char *data)
  35. * delay_ms(unsigned long num_ms)
  36. * get_ms(unsigned long *count)
  37. */
  38. #if defined MOTION_DRIVER_TARGET_MSP430
  39. //#include "msp430.h"
  40. //#include "msp430_clock.h"
  41. #define delay_ms delay_ms
  42. #define get_ms mget_ms
  43. #define log_i printf
  44. #define log_e printf
  45. #elif defined EMPL_TARGET_MSP430
  46. #include "msp430.h"
  47. #include "msp430_clock.h"
  48. #include "log.h"
  49. #define delay_ms msp430_delay_ms
  50. #define get_ms msp430_get_clock_ms
  51. #define log_i MPL_LOGI
  52. #define log_e MPL_LOGE
  53. #elif defined EMPL_TARGET_UC3L0
  54. /* Instead of using the standard TWI driver from the ASF library, we're using
  55. * a TWI driver that follows the slave address + register address convention.
  56. */
  57. #include "delay.h"
  58. #include "sysclk.h"
  59. #include "log.h"
  60. #include "uc3l0_clock.h"
  61. /* delay_ms is a function already defined in ASF. */
  62. #define get_ms uc3l0_get_clock_ms
  63. #define log_i MPL_LOGI
  64. #define log_e MPL_LOGE
  65. #else
  66. #error Gyro driver is missing the system layer implementations.
  67. #endif
  68. /* These defines are copied from dmpDefaultMPU6050.c in the general MPL
  69. * releases. These defines may change for each DMP image, so be sure to modify
  70. * these values when switching to a new image.
  71. */
  72. #define CFG_LP_QUAT (2712)
  73. #define END_ORIENT_TEMP (1866)
  74. #define CFG_27 (2742)
  75. #define CFG_20 (2224)
  76. #define CFG_23 (2745)
  77. #define CFG_FIFO_ON_EVENT (2690)
  78. #define END_PREDICTION_UPDATE (1761)
  79. #define CGNOTICE_INTR (2620)
  80. #define X_GRT_Y_TMP (1358)
  81. #define CFG_DR_INT (1029)
  82. #define CFG_AUTH (1035)
  83. #define UPDATE_PROP_ROT (1835)
  84. #define END_COMPARE_Y_X_TMP2 (1455)
  85. #define SKIP_X_GRT_Y_TMP (1359)
  86. #define SKIP_END_COMPARE (1435)
  87. #define FCFG_3 (1088)
  88. #define FCFG_2 (1066)
  89. #define FCFG_1 (1062)
  90. #define END_COMPARE_Y_X_TMP3 (1434)
  91. #define FCFG_7 (1073)
  92. #define FCFG_6 (1106)
  93. #define FLAT_STATE_END (1713)
  94. #define SWING_END_4 (1616)
  95. #define SWING_END_2 (1565)
  96. #define SWING_END_3 (1587)
  97. #define SWING_END_1 (1550)
  98. #define CFG_8 (2718)
  99. #define CFG_15 (2727)
  100. #define CFG_16 (2746)
  101. #define CFG_EXT_GYRO_BIAS (1189)
  102. #define END_COMPARE_Y_X_TMP (1407)
  103. #define DO_NOT_UPDATE_PROP_ROT (1839)
  104. #define CFG_7 (1205)
  105. #define FLAT_STATE_END_TEMP (1683)
  106. #define END_COMPARE_Y_X (1484)
  107. #define SKIP_SWING_END_1 (1551)
  108. #define SKIP_SWING_END_3 (1588)
  109. #define SKIP_SWING_END_2 (1566)
  110. #define TILTG75_START (1672)
  111. #define CFG_6 (2753)
  112. #define TILTL75_END (1669)
  113. #define END_ORIENT (1884)
  114. #define CFG_FLICK_IN (2573)
  115. #define TILTL75_START (1643)
  116. #define CFG_MOTION_BIAS (1208)
  117. #define X_GRT_Y (1408)
  118. #define TEMPLABEL (2324)
  119. #define CFG_ANDROID_ORIENT_INT (1853)
  120. #define CFG_GYRO_RAW_DATA (2722)
  121. #define X_GRT_Y_TMP2 (1379)
  122. #define D_0_22 (22+512)
  123. #define D_0_24 (24+512)
  124. #define D_0_36 (36)
  125. #define D_0_52 (52)
  126. #define D_0_96 (96)
  127. #define D_0_104 (104)
  128. #define D_0_108 (108)
  129. #define D_0_163 (163)
  130. #define D_0_188 (188)
  131. #define D_0_192 (192)
  132. #define D_0_224 (224)
  133. #define D_0_228 (228)
  134. #define D_0_232 (232)
  135. #define D_0_236 (236)
  136. #define D_1_2 (256 + 2)
  137. #define D_1_4 (256 + 4)
  138. #define D_1_8 (256 + 8)
  139. #define D_1_10 (256 + 10)
  140. #define D_1_24 (256 + 24)
  141. #define D_1_28 (256 + 28)
  142. #define D_1_36 (256 + 36)
  143. #define D_1_40 (256 + 40)
  144. #define D_1_44 (256 + 44)
  145. #define D_1_72 (256 + 72)
  146. #define D_1_74 (256 + 74)
  147. #define D_1_79 (256 + 79)
  148. #define D_1_88 (256 + 88)
  149. #define D_1_90 (256 + 90)
  150. #define D_1_92 (256 + 92)
  151. #define D_1_96 (256 + 96)
  152. #define D_1_98 (256 + 98)
  153. #define D_1_106 (256 + 106)
  154. #define D_1_108 (256 + 108)
  155. #define D_1_112 (256 + 112)
  156. #define D_1_128 (256 + 144)
  157. #define D_1_152 (256 + 12)
  158. #define D_1_160 (256 + 160)
  159. #define D_1_176 (256 + 176)
  160. #define D_1_178 (256 + 178)
  161. #define D_1_218 (256 + 218)
  162. #define D_1_232 (256 + 232)
  163. #define D_1_236 (256 + 236)
  164. #define D_1_240 (256 + 240)
  165. #define D_1_244 (256 + 244)
  166. #define D_1_250 (256 + 250)
  167. #define D_1_252 (256 + 252)
  168. #define D_2_12 (512 + 12)
  169. #define D_2_96 (512 + 96)
  170. #define D_2_108 (512 + 108)
  171. #define D_2_208 (512 + 208)
  172. #define D_2_224 (512 + 224)
  173. #define D_2_236 (512 + 236)
  174. #define D_2_244 (512 + 244)
  175. #define D_2_248 (512 + 248)
  176. #define D_2_252 (512 + 252)
  177. #define CPASS_BIAS_X (35 * 16 + 4)
  178. #define CPASS_BIAS_Y (35 * 16 + 8)
  179. #define CPASS_BIAS_Z (35 * 16 + 12)
  180. #define CPASS_MTX_00 (36 * 16)
  181. #define CPASS_MTX_01 (36 * 16 + 4)
  182. #define CPASS_MTX_02 (36 * 16 + 8)
  183. #define CPASS_MTX_10 (36 * 16 + 12)
  184. #define CPASS_MTX_11 (37 * 16)
  185. #define CPASS_MTX_12 (37 * 16 + 4)
  186. #define CPASS_MTX_20 (37 * 16 + 8)
  187. #define CPASS_MTX_21 (37 * 16 + 12)
  188. #define CPASS_MTX_22 (43 * 16 + 12)
  189. #define D_EXT_GYRO_BIAS_X (61 * 16)
  190. #define D_EXT_GYRO_BIAS_Y (61 * 16) + 4
  191. #define D_EXT_GYRO_BIAS_Z (61 * 16) + 8
  192. #define D_ACT0 (40 * 16)
  193. #define D_ACSX (40 * 16 + 4)
  194. #define D_ACSY (40 * 16 + 8)
  195. #define D_ACSZ (40 * 16 + 12)
  196. #define FLICK_MSG (45 * 16 + 4)
  197. #define FLICK_COUNTER (45 * 16 + 8)
  198. #define FLICK_LOWER (45 * 16 + 12)
  199. #define FLICK_UPPER (46 * 16 + 12)
  200. #define D_AUTH_OUT (992)
  201. #define D_AUTH_IN (996)
  202. #define D_AUTH_A (1000)
  203. #define D_AUTH_B (1004)
  204. #define D_PEDSTD_BP_B (768 + 0x1C)
  205. #define D_PEDSTD_HP_A (768 + 0x78)
  206. #define D_PEDSTD_HP_B (768 + 0x7C)
  207. #define D_PEDSTD_BP_A4 (768 + 0x40)
  208. #define D_PEDSTD_BP_A3 (768 + 0x44)
  209. #define D_PEDSTD_BP_A2 (768 + 0x48)
  210. #define D_PEDSTD_BP_A1 (768 + 0x4C)
  211. #define D_PEDSTD_INT_THRSH (768 + 0x68)
  212. #define D_PEDSTD_CLIP (768 + 0x6C)
  213. #define D_PEDSTD_SB (768 + 0x28)
  214. #define D_PEDSTD_SB_TIME (768 + 0x2C)
  215. #define D_PEDSTD_PEAKTHRSH (768 + 0x98)
  216. #define D_PEDSTD_TIML (768 + 0x2A)
  217. #define D_PEDSTD_TIMH (768 + 0x2E)
  218. #define D_PEDSTD_PEAK (768 + 0X94)
  219. #define D_PEDSTD_STEPCTR (768 + 0x60)
  220. #define D_PEDSTD_TIMECTR (964)
  221. #define D_PEDSTD_DECI (768 + 0xA0)
  222. #define D_HOST_NO_MOT (976)
  223. #define D_ACCEL_BIAS (660)
  224. #define D_ORIENT_GAP (76)
  225. #define D_TILT0_H (48)
  226. #define D_TILT0_L (50)
  227. #define D_TILT1_H (52)
  228. #define D_TILT1_L (54)
  229. #define D_TILT2_H (56)
  230. #define D_TILT2_L (58)
  231. #define D_TILT3_H (60)
  232. #define D_TILT3_L (62)
  233. #define DMP_CODE_SIZE (3062)
  234. static const unsigned char dmp_memory[DMP_CODE_SIZE] = {
  235. /* bank # 0 */
  236. 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
  237. 0x00, 0x65, 0x00, 0x54, 0xff, 0xef, 0x00, 0x00, 0xfa, 0x80, 0x00, 0x0b, 0x12, 0x82, 0x00, 0x01,
  238. 0x03, 0x0c, 0x30, 0xc3, 0x0e, 0x8c, 0x8c, 0xe9, 0x14, 0xd5, 0x40, 0x02, 0x13, 0x71, 0x0f, 0x8e,
  239. 0x38, 0x83, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 0x25, 0x8e, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83,
  240. 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xa9, 0xd6, 0x24, 0x00, 0x04, 0x00, 0x1a, 0x82, 0x79, 0xa1,
  241. 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6f, 0xa2,
  242. 0x00, 0x3e, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xca, 0xe3, 0x09, 0x3e, 0x80, 0x00, 0x00,
  243. 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
  244. 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x6e, 0x00, 0x00, 0x06, 0x92, 0x0a, 0x16, 0xc0, 0xdf,
  245. 0xff, 0xff, 0x02, 0x56, 0xfd, 0x8c, 0xd3, 0x77, 0xff, 0xe1, 0xc4, 0x96, 0xe0, 0xc5, 0xbe, 0xaa,
  246. 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x2b, 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x03, 0x59,
  247. 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xfa, 0x00, 0x02, 0x6c, 0x1d, 0x00, 0x00, 0x00, 0x00,
  248. 0x3f, 0xff, 0xdf, 0xeb, 0x00, 0x3e, 0xb3, 0xb6, 0x00, 0x0d, 0x22, 0x78, 0x00, 0x00, 0x2f, 0x3c,
  249. 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x42, 0xb5, 0x00, 0x00, 0x39, 0xa2, 0x00, 0x00, 0xb3, 0x65,
  250. 0xd9, 0x0e, 0x9f, 0xc9, 0x1d, 0xcf, 0x4c, 0x34, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
  251. 0x3b, 0xb6, 0x7a, 0xe8, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  252. /* bank # 1 */
  253. 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfa, 0x92, 0x10, 0x00, 0x22, 0x5e, 0x00, 0x0d, 0x22, 0x9f,
  254. 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0x63, 0xd4, 0x00, 0x00,
  255. 0x10, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00,
  256. 0x00, 0x00, 0x10, 0x72, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  257. 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
  258. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00,
  259. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00,
  260. 0x00, 0x00, 0x00, 0x32, 0xf8, 0x98, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0x83, 0x0f, 0x00, 0x00,
  261. 0xff, 0x9b, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  262. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  263. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  264. 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb2, 0x6a, 0x00, 0x02, 0x00, 0x00,
  265. 0x00, 0x01, 0xfb, 0x83, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd9, 0xfc, 0x00, 0x7c, 0xf1, 0xff, 0x83,
  266. 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x03, 0xe8, 0x00, 0x64, 0x00, 0x28,
  267. 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  268. 0x00, 0x00, 0x10, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x10, 0x00,
  269. /* bank # 2 */
  270. 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x45, 0x81, 0xff, 0xff, 0xfa, 0x72, 0x00, 0x00, 0x00, 0x00,
  271. 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x05, 0x00, 0x05, 0xba, 0xc6, 0x00, 0x47, 0x78, 0xa2,
  272. 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14,
  273. 0x00, 0x00, 0x25, 0x4d, 0x00, 0x2f, 0x70, 0x6d, 0x00, 0x00, 0x05, 0xae, 0x00, 0x0c, 0x02, 0xd0,
  274. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  275. 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  276. 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  277. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  278. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  279. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  280. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  281. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  282. 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e,
  283. 0x00, 0x00, 0x0a, 0xc7, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0xff, 0x9c,
  284. 0x00, 0x00, 0x0b, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
  285. 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  286. /* bank # 3 */
  287. 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  288. 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xd3,
  289. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3c,
  290. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  291. 0x0c, 0x0a, 0x4e, 0x68, 0xcd, 0xcf, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xc6, 0x19, 0xce, 0x82,
  292. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  293. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00,
  294. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x93, 0x8f, 0x9d, 0x1e, 0x1b, 0x1c, 0x19,
  295. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  296. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00,
  297. 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  298. 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  299. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  300. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  301. 0x00, 0x00, 0x00, 0x00, 0x67, 0x7d, 0xdf, 0x7e, 0x72, 0x90, 0x2e, 0x55, 0x4c, 0xf6, 0xe6, 0x88,
  302. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  303. /* bank # 4 */
  304. 0xd8, 0xdc, 0xb4, 0xb8, 0xb0, 0xd8, 0xb9, 0xab, 0xf3, 0xf8, 0xfa, 0xb3, 0xb7, 0xbb, 0x8e, 0x9e,
  305. 0xae, 0xf1, 0x32, 0xf5, 0x1b, 0xf1, 0xb4, 0xb8, 0xb0, 0x80, 0x97, 0xf1, 0xa9, 0xdf, 0xdf, 0xdf,
  306. 0xaa, 0xdf, 0xdf, 0xdf, 0xf2, 0xaa, 0xc5, 0xcd, 0xc7, 0xa9, 0x0c, 0xc9, 0x2c, 0x97, 0xf1, 0xa9,
  307. 0x89, 0x26, 0x46, 0x66, 0xb2, 0x89, 0x99, 0xa9, 0x2d, 0x55, 0x7d, 0xb0, 0xb0, 0x8a, 0xa8, 0x96,
  308. 0x36, 0x56, 0x76, 0xf1, 0xba, 0xa3, 0xb4, 0xb2, 0x80, 0xc0, 0xb8, 0xa8, 0x97, 0x11, 0xb2, 0x83,
  309. 0x98, 0xba, 0xa3, 0xf0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xb2, 0xb9, 0xb4, 0x98, 0x83, 0xf1,
  310. 0xa3, 0x29, 0x55, 0x7d, 0xba, 0xb5, 0xb1, 0xa3, 0x83, 0x93, 0xf0, 0x00, 0x28, 0x50, 0xf5, 0xb2,
  311. 0xb6, 0xaa, 0x83, 0x93, 0x28, 0x54, 0x7c, 0xf1, 0xb9, 0xa3, 0x82, 0x93, 0x61, 0xba, 0xa2, 0xda,
  312. 0xde, 0xdf, 0xdb, 0x81, 0x9a, 0xb9, 0xae, 0xf5, 0x60, 0x68, 0x70, 0xf1, 0xda, 0xba, 0xa2, 0xdf,
  313. 0xd9, 0xba, 0xa2, 0xfa, 0xb9, 0xa3, 0x82, 0x92, 0xdb, 0x31, 0xba, 0xa2, 0xd9, 0xba, 0xa2, 0xf8,
  314. 0xdf, 0x85, 0xa4, 0xd0, 0xc1, 0xbb, 0xad, 0x83, 0xc2, 0xc5, 0xc7, 0xb8, 0xa2, 0xdf, 0xdf, 0xdf,
  315. 0xba, 0xa0, 0xdf, 0xdf, 0xdf, 0xd8, 0xd8, 0xf1, 0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35,
  316. 0x5d, 0xb2, 0xb6, 0xba, 0xaf, 0x8c, 0x96, 0x19, 0x8f, 0x9f, 0xa7, 0x0e, 0x16, 0x1e, 0xb4, 0x9a,
  317. 0xb8, 0xaa, 0x87, 0x2c, 0x54, 0x7c, 0xba, 0xa4, 0xb0, 0x8a, 0xb6, 0x91, 0x32, 0x56, 0x76, 0xb2,
  318. 0x84, 0x94, 0xa4, 0xc8, 0x08, 0xcd, 0xd8, 0xb8, 0xb4, 0xb0, 0xf1, 0x99, 0x82, 0xa8, 0x2d, 0x55,
  319. 0x7d, 0x98, 0xa8, 0x0e, 0x16, 0x1e, 0xa2, 0x2c, 0x54, 0x7c, 0x92, 0xa4, 0xf0, 0x2c, 0x50, 0x78,
  320. /* bank # 5 */
  321. 0xf1, 0x84, 0xa8, 0x98, 0xc4, 0xcd, 0xfc, 0xd8, 0x0d, 0xdb, 0xa8, 0xfc, 0x2d, 0xf3, 0xd9, 0xba,
  322. 0xa6, 0xf8, 0xda, 0xba, 0xa6, 0xde, 0xd8, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xf3, 0xc8,
  323. 0x41, 0xda, 0xa6, 0xc8, 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0x82, 0xa8, 0x92, 0xf5, 0x2c, 0x54, 0x88,
  324. 0x98, 0xf1, 0x35, 0xd9, 0xf4, 0x18, 0xd8, 0xf1, 0xa2, 0xd0, 0xf8, 0xf9, 0xa8, 0x84, 0xd9, 0xc7,
  325. 0xdf, 0xf8, 0xf8, 0x83, 0xc5, 0xda, 0xdf, 0x69, 0xdf, 0x83, 0xc1, 0xd8, 0xf4, 0x01, 0x14, 0xf1,
  326. 0xa8, 0x82, 0x4e, 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x28, 0x97, 0x88, 0xf1,
  327. 0x09, 0xf4, 0x1c, 0x1c, 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x29,
  328. 0xf4, 0x0d, 0xd8, 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc2, 0x03, 0xd8, 0xde, 0xdf, 0x1a,
  329. 0xd8, 0xf1, 0xa2, 0xfa, 0xf9, 0xa8, 0x84, 0x98, 0xd9, 0xc7, 0xdf, 0xf8, 0xf8, 0xf8, 0x83, 0xc7,
  330. 0xda, 0xdf, 0x69, 0xdf, 0xf8, 0x83, 0xc3, 0xd8, 0xf4, 0x01, 0x14, 0xf1, 0x98, 0xa8, 0x82, 0x2e,
  331. 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x50, 0x97, 0x88, 0xf1, 0x09, 0xf4, 0x1c,
  332. 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf8, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x49, 0xf4, 0x0d, 0xd8,
  333. 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc4, 0x03, 0xd8, 0xde, 0xdf, 0xd8, 0xf1, 0xad, 0x88,
  334. 0x98, 0xcc, 0xa8, 0x09, 0xf9, 0xd9, 0x82, 0x92, 0xa8, 0xf5, 0x7c, 0xf1, 0x88, 0x3a, 0xcf, 0x94,
  335. 0x4a, 0x6e, 0x98, 0xdb, 0x69, 0x31, 0xda, 0xad, 0xf2, 0xde, 0xf9, 0xd8, 0x87, 0x95, 0xa8, 0xf2,
  336. 0x21, 0xd1, 0xda, 0xa5, 0xf9, 0xf4, 0x17, 0xd9, 0xf1, 0xae, 0x8e, 0xd0, 0xc0, 0xc3, 0xae, 0x82,
  337. /* bank # 6 */
  338. 0xc6, 0x84, 0xc3, 0xa8, 0x85, 0x95, 0xc8, 0xa5, 0x88, 0xf2, 0xc0, 0xf1, 0xf4, 0x01, 0x0e, 0xf1,
  339. 0x8e, 0x9e, 0xa8, 0xc6, 0x3e, 0x56, 0xf5, 0x54, 0xf1, 0x88, 0x72, 0xf4, 0x01, 0x15, 0xf1, 0x98,
  340. 0x45, 0x85, 0x6e, 0xf5, 0x8e, 0x9e, 0x04, 0x88, 0xf1, 0x42, 0x98, 0x5a, 0x8e, 0x9e, 0x06, 0x88,
  341. 0x69, 0xf4, 0x01, 0x1c, 0xf1, 0x98, 0x1e, 0x11, 0x08, 0xd0, 0xf5, 0x04, 0xf1, 0x1e, 0x97, 0x02,
  342. 0x02, 0x98, 0x36, 0x25, 0xdb, 0xf9, 0xd9, 0x85, 0xa5, 0xf3, 0xc1, 0xda, 0x85, 0xa5, 0xf3, 0xdf,
  343. 0xd8, 0x85, 0x95, 0xa8, 0xf3, 0x09, 0xda, 0xa5, 0xfa, 0xd8, 0x82, 0x92, 0xa8, 0xf5, 0x78, 0xf1,
  344. 0x88, 0x1a, 0x84, 0x9f, 0x26, 0x88, 0x98, 0x21, 0xda, 0xf4, 0x1d, 0xf3, 0xd8, 0x87, 0x9f, 0x39,
  345. 0xd1, 0xaf, 0xd9, 0xdf, 0xdf, 0xfb, 0xf9, 0xf4, 0x0c, 0xf3, 0xd8, 0xfa, 0xd0, 0xf8, 0xda, 0xf9,
  346. 0xf9, 0xd0, 0xdf, 0xd9, 0xf9, 0xd8, 0xf4, 0x0b, 0xd8, 0xf3, 0x87, 0x9f, 0x39, 0xd1, 0xaf, 0xd9,
  347. 0xdf, 0xdf, 0xf4, 0x1d, 0xf3, 0xd8, 0xfa, 0xfc, 0xa8, 0x69, 0xf9, 0xf9, 0xaf, 0xd0, 0xda, 0xde,
  348. 0xfa, 0xd9, 0xf8, 0x8f, 0x9f, 0xa8, 0xf1, 0xcc, 0xf3, 0x98, 0xdb, 0x45, 0xd9, 0xaf, 0xdf, 0xd0,
  349. 0xf8, 0xd8, 0xf1, 0x8f, 0x9f, 0xa8, 0xca, 0xf3, 0x88, 0x09, 0xda, 0xaf, 0x8f, 0xcb, 0xf8, 0xd8,
  350. 0xf2, 0xad, 0x97, 0x8d, 0x0c, 0xd9, 0xa5, 0xdf, 0xf9, 0xba, 0xa6, 0xf3, 0xfa, 0xf4, 0x12, 0xf2,
  351. 0xd8, 0x95, 0x0d, 0xd1, 0xd9, 0xba, 0xa6, 0xf3, 0xfa, 0xda, 0xa5, 0xf2, 0xc1, 0xba, 0xa6, 0xf3,
  352. 0xdf, 0xd8, 0xf1, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xca, 0xf3, 0x49, 0xda, 0xa6, 0xcb,
  353. 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0xd8, 0xad, 0x84, 0xf2, 0xc0, 0xdf, 0xf1, 0x8f, 0xcb, 0xc3, 0xa8,
  354. /* bank # 7 */
  355. 0xb2, 0xb6, 0x86, 0x96, 0xc8, 0xc1, 0xcb, 0xc3, 0xf3, 0xb0, 0xb4, 0x88, 0x98, 0xa8, 0x21, 0xdb,
  356. 0x71, 0x8d, 0x9d, 0x71, 0x85, 0x95, 0x21, 0xd9, 0xad, 0xf2, 0xfa, 0xd8, 0x85, 0x97, 0xa8, 0x28,
  357. 0xd9, 0xf4, 0x08, 0xd8, 0xf2, 0x8d, 0x29, 0xda, 0xf4, 0x05, 0xd9, 0xf2, 0x85, 0xa4, 0xc2, 0xf2,
  358. 0xd8, 0xa8, 0x8d, 0x94, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xf2, 0xd8, 0x87, 0x21, 0xd8, 0xf4, 0x0a,
  359. 0xd8, 0xf2, 0x84, 0x98, 0xa8, 0xc8, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xd8, 0xf3, 0xa4, 0xc8, 0xbb,
  360. 0xaf, 0xd0, 0xf2, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xd8, 0xf1, 0xb8, 0xf6,
  361. 0xb5, 0xb9, 0xb0, 0x8a, 0x95, 0xa3, 0xde, 0x3c, 0xa3, 0xd9, 0xf8, 0xd8, 0x5c, 0xa3, 0xd9, 0xf8,
  362. 0xd8, 0x7c, 0xa3, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa5, 0xd9, 0xdf, 0xda, 0xfa, 0xd8, 0xb1,
  363. 0x85, 0x30, 0xf7, 0xd9, 0xde, 0xd8, 0xf8, 0x30, 0xad, 0xda, 0xde, 0xd8, 0xf2, 0xb4, 0x8c, 0x99,
  364. 0xa3, 0x2d, 0x55, 0x7d, 0xa0, 0x83, 0xdf, 0xdf, 0xdf, 0xb5, 0x91, 0xa0, 0xf6, 0x29, 0xd9, 0xfb,
  365. 0xd8, 0xa0, 0xfc, 0x29, 0xd9, 0xfa, 0xd8, 0xa0, 0xd0, 0x51, 0xd9, 0xf8, 0xd8, 0xfc, 0x51, 0xd9,
  366. 0xf9, 0xd8, 0x79, 0xd9, 0xfb, 0xd8, 0xa0, 0xd0, 0xfc, 0x79, 0xd9, 0xfa, 0xd8, 0xa1, 0xf9, 0xf9,
  367. 0xf9, 0xf9, 0xf9, 0xa0, 0xda, 0xdf, 0xdf, 0xdf, 0xd8, 0xa1, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xac,
  368. 0xde, 0xf8, 0xad, 0xde, 0x83, 0x93, 0xac, 0x2c, 0x54, 0x7c, 0xf1, 0xa8, 0xdf, 0xdf, 0xdf, 0xf6,
  369. 0x9d, 0x2c, 0xda, 0xa0, 0xdf, 0xd9, 0xfa, 0xdb, 0x2d, 0xf8, 0xd8, 0xa8, 0x50, 0xda, 0xa0, 0xd0,
  370. 0xde, 0xd9, 0xd0, 0xf8, 0xf8, 0xf8, 0xdb, 0x55, 0xf8, 0xd8, 0xa8, 0x78, 0xda, 0xa0, 0xd0, 0xdf,
  371. /* bank # 8 */
  372. 0xd9, 0xd0, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xdb, 0x7d, 0xf8, 0xd8, 0x9c, 0xa8, 0x8c, 0xf5, 0x30,
  373. 0xdb, 0x38, 0xd9, 0xd0, 0xde, 0xdf, 0xa0, 0xd0, 0xde, 0xdf, 0xd8, 0xa8, 0x48, 0xdb, 0x58, 0xd9,
  374. 0xdf, 0xd0, 0xde, 0xa0, 0xdf, 0xd0, 0xde, 0xd8, 0xa8, 0x68, 0xdb, 0x70, 0xd9, 0xdf, 0xdf, 0xa0,
  375. 0xdf, 0xdf, 0xd8, 0xf1, 0xa8, 0x88, 0x90, 0x2c, 0x54, 0x7c, 0x98, 0xa8, 0xd0, 0x5c, 0x38, 0xd1,
  376. 0xda, 0xf2, 0xae, 0x8c, 0xdf, 0xf9, 0xd8, 0xb0, 0x87, 0xa8, 0xc1, 0xc1, 0xb1, 0x88, 0xa8, 0xc6,
  377. 0xf9, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8,
  378. 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xf7, 0x8d, 0x9d, 0xad, 0xf8, 0x18, 0xda,
  379. 0xf2, 0xae, 0xdf, 0xd8, 0xf7, 0xad, 0xfa, 0x30, 0xd9, 0xa4, 0xde, 0xf9, 0xd8, 0xf2, 0xae, 0xde,
  380. 0xfa, 0xf9, 0x83, 0xa7, 0xd9, 0xc3, 0xc5, 0xc7, 0xf1, 0x88, 0x9b, 0xa7, 0x7a, 0xad, 0xf7, 0xde,
  381. 0xdf, 0xa4, 0xf8, 0x84, 0x94, 0x08, 0xa7, 0x97, 0xf3, 0x00, 0xae, 0xf2, 0x98, 0x19, 0xa4, 0x88,
  382. 0xc6, 0xa3, 0x94, 0x88, 0xf6, 0x32, 0xdf, 0xf2, 0x83, 0x93, 0xdb, 0x09, 0xd9, 0xf2, 0xaa, 0xdf,
  383. 0xd8, 0xd8, 0xae, 0xf8, 0xf9, 0xd1, 0xda, 0xf3, 0xa4, 0xde, 0xa7, 0xf1, 0x88, 0x9b, 0x7a, 0xd8,
  384. 0xf3, 0x84, 0x94, 0xae, 0x19, 0xf9, 0xda, 0xaa, 0xf1, 0xdf, 0xd8, 0xa8, 0x81, 0xc0, 0xc3, 0xc5,
  385. 0xc7, 0xa3, 0x92, 0x83, 0xf6, 0x28, 0xad, 0xde, 0xd9, 0xf8, 0xd8, 0xa3, 0x50, 0xad, 0xd9, 0xf8,
  386. 0xd8, 0xa3, 0x78, 0xad, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa1, 0xda, 0xde, 0xc3, 0xc5, 0xc7,
  387. 0xd8, 0xa1, 0x81, 0x94, 0xf8, 0x18, 0xf2, 0xb0, 0x89, 0xac, 0xc3, 0xc5, 0xc7, 0xf1, 0xd8, 0xb8,
  388. /* bank # 9 */
  389. 0xb4, 0xb0, 0x97, 0x86, 0xa8, 0x31, 0x9b, 0x06, 0x99, 0x07, 0xab, 0x97, 0x28, 0x88, 0x9b, 0xf0,
  390. 0x0c, 0x20, 0x14, 0x40, 0xb0, 0xb4, 0xb8, 0xf0, 0xa8, 0x8a, 0x9a, 0x28, 0x50, 0x78, 0xb7, 0x9b,
  391. 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xf1, 0xbb, 0xab,
  392. 0x88, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0xb3, 0x8b, 0xb8, 0xa8, 0x04, 0x28, 0x50, 0x78, 0xf1, 0xb0,
  393. 0x88, 0xb4, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xbb, 0xab, 0xb3, 0x8b, 0x02, 0x26, 0x46, 0x66, 0xb0,
  394. 0xb8, 0xf0, 0x8a, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x8b, 0x29, 0x51, 0x79, 0x8a, 0x24, 0x70, 0x59,
  395. 0x8b, 0x20, 0x58, 0x71, 0x8a, 0x44, 0x69, 0x38, 0x8b, 0x39, 0x40, 0x68, 0x8a, 0x64, 0x48, 0x31,
  396. 0x8b, 0x30, 0x49, 0x60, 0x88, 0xf1, 0xac, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0x8c, 0xa8, 0x04, 0x28,
  397. 0x50, 0x78, 0xf1, 0x88, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xac, 0x8c, 0x02, 0x26, 0x46, 0x66, 0xf0,
  398. 0x89, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xa9,
  399. 0x88, 0x09, 0x20, 0x59, 0x70, 0xab, 0x11, 0x38, 0x40, 0x69, 0xa8, 0x19, 0x31, 0x48, 0x60, 0x8c,
  400. 0xa8, 0x3c, 0x41, 0x5c, 0x20, 0x7c, 0x00, 0xf1, 0x87, 0x98, 0x19, 0x86, 0xa8, 0x6e, 0x76, 0x7e,
  401. 0xa9, 0x99, 0x88, 0x2d, 0x55, 0x7d, 0xd8, 0xb1, 0xb5, 0xb9, 0xa3, 0xdf, 0xdf, 0xdf, 0xae, 0xd0,
  402. 0xdf, 0xaa, 0xd0, 0xde, 0xf2, 0xab, 0xf8, 0xf9, 0xd9, 0xb0, 0x87, 0xc4, 0xaa, 0xf1, 0xdf, 0xdf,
  403. 0xbb, 0xaf, 0xdf, 0xdf, 0xb9, 0xd8, 0xb1, 0xf1, 0xa3, 0x97, 0x8e, 0x60, 0xdf, 0xb0, 0x84, 0xf2,
  404. 0xc8, 0xf8, 0xf9, 0xd9, 0xde, 0xd8, 0x93, 0x85, 0xf1, 0x4a, 0xb1, 0x83, 0xa3, 0x08, 0xb5, 0x83,
  405. /* bank # 10 */
  406. 0x9a, 0x08, 0x10, 0xb7, 0x9f, 0x10, 0xd8, 0xf1, 0xb0, 0xba, 0xae, 0xb0, 0x8a, 0xc2, 0xb2, 0xb6,
  407. 0x8e, 0x9e, 0xf1, 0xfb, 0xd9, 0xf4, 0x1d, 0xd8, 0xf9, 0xd9, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad,
  408. 0x61, 0xd9, 0xae, 0xfb, 0xd8, 0xf4, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, 0x19, 0xd9, 0xae, 0xfb,
  409. 0xdf, 0xd8, 0xf4, 0x16, 0xf1, 0xd8, 0xf8, 0xad, 0x8d, 0x61, 0xd9, 0xf4, 0xf4, 0xac, 0xf5, 0x9c,
  410. 0x9c, 0x8d, 0xdf, 0x2b, 0xba, 0xb6, 0xae, 0xfa, 0xf8, 0xf4, 0x0b, 0xd8, 0xf1, 0xae, 0xd0, 0xf8,
  411. 0xad, 0x51, 0xda, 0xae, 0xfa, 0xf8, 0xf1, 0xd8, 0xb9, 0xb1, 0xb6, 0xa3, 0x83, 0x9c, 0x08, 0xb9,
  412. 0xb1, 0x83, 0x9a, 0xb5, 0xaa, 0xc0, 0xfd, 0x30, 0x83, 0xb7, 0x9f, 0x10, 0xb5, 0x8b, 0x93, 0xf2,
  413. 0x02, 0x02, 0xd1, 0xab, 0xda, 0xde, 0xd8, 0xf1, 0xb0, 0x80, 0xba, 0xab, 0xc0, 0xc3, 0xb2, 0x84,
  414. 0xc1, 0xc3, 0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9, 0xab, 0xde, 0xb0,
  415. 0x87, 0x9c, 0xb9, 0xa3, 0xdd, 0xf1, 0xb3, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0xb0, 0x87, 0xa3, 0xa3,
  416. 0xa3, 0xa3, 0xb2, 0x8b, 0xb6, 0x9b, 0xf2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
  417. 0xa3, 0xf1, 0xb0, 0x87, 0xb5, 0x9a, 0xa3, 0xf3, 0x9b, 0xa3, 0xa3, 0xdc, 0xba, 0xac, 0xdf, 0xb9,
  418. 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
  419. 0xd8, 0xd8, 0xd8, 0xbb, 0xb3, 0xb7, 0xf1, 0xaa, 0xf9, 0xda, 0xff, 0xd9, 0x80, 0x9a, 0xaa, 0x28,
  420. 0xb4, 0x80, 0x98, 0xa7, 0x20, 0xb7, 0x97, 0x87, 0xa8, 0x66, 0x88, 0xf0, 0x79, 0x51, 0xf1, 0x90,
  421. 0x2c, 0x87, 0x0c, 0xa7, 0x81, 0x97, 0x62, 0x93, 0xf0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29,
  422. /* bank # 11 */
  423. 0x51, 0x79, 0x90, 0xa5, 0xf1, 0x28, 0x4c, 0x6c, 0x87, 0x0c, 0x95, 0x18, 0x85, 0x78, 0xa3, 0x83,
  424. 0x90, 0x28, 0x4c, 0x6c, 0x88, 0x6c, 0xd8, 0xf3, 0xa2, 0x82, 0x00, 0xf2, 0x10, 0xa8, 0x92, 0x19,
  425. 0x80, 0xa2, 0xf2, 0xd9, 0x26, 0xd8, 0xf1, 0x88, 0xa8, 0x4d, 0xd9, 0x48, 0xd8, 0x96, 0xa8, 0x39,
  426. 0x80, 0xd9, 0x3c, 0xd8, 0x95, 0x80, 0xa8, 0x39, 0xa6, 0x86, 0x98, 0xd9, 0x2c, 0xda, 0x87, 0xa7,
  427. 0x2c, 0xd8, 0xa8, 0x89, 0x95, 0x19, 0xa9, 0x80, 0xd9, 0x38, 0xd8, 0xa8, 0x89, 0x39, 0xa9, 0x80,
  428. 0xda, 0x3c, 0xd8, 0xa8, 0x2e, 0xa8, 0x39, 0x90, 0xd9, 0x0c, 0xd8, 0xa8, 0x95, 0x31, 0x98, 0xd9,
  429. 0x0c, 0xd8, 0xa8, 0x09, 0xd9, 0xff, 0xd8, 0x01, 0xda, 0xff, 0xd8, 0x95, 0x39, 0xa9, 0xda, 0x26,
  430. 0xff, 0xd8, 0x90, 0xa8, 0x0d, 0x89, 0x99, 0xa8, 0x10, 0x80, 0x98, 0x21, 0xda, 0x2e, 0xd8, 0x89,
  431. 0x99, 0xa8, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x86, 0x96, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8,
  432. 0x87, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x82, 0x92, 0xf3, 0x41, 0x80, 0xf1, 0xd9, 0x2e, 0xd8,
  433. 0xa8, 0x82, 0xf3, 0x19, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, 0x82, 0xac, 0xf3, 0xc0, 0xa2, 0x80, 0x22,
  434. 0xf1, 0xa6, 0x2e, 0xa7, 0x2e, 0xa9, 0x22, 0x98, 0xa8, 0x29, 0xda, 0xac, 0xde, 0xff, 0xd8, 0xa2,
  435. 0xf2, 0x2a, 0xf1, 0xa9, 0x2e, 0x82, 0x92, 0xa8, 0xf2, 0x31, 0x80, 0xa6, 0x96, 0xf1, 0xd9, 0x00,
  436. 0xac, 0x8c, 0x9c, 0x0c, 0x30, 0xac, 0xde, 0xd0, 0xde, 0xff, 0xd8, 0x8c, 0x9c, 0xac, 0xd0, 0x10,
  437. 0xac, 0xde, 0x80, 0x92, 0xa2, 0xf2, 0x4c, 0x82, 0xa8, 0xf1, 0xca, 0xf2, 0x35, 0xf1, 0x96, 0x88,
  438. 0xa6, 0xd9, 0x00, 0xd8, 0xf1, 0xff
  439. };
  440. static const unsigned short sStartAddress = 0x0400;
  441. /* END OF SECTION COPIED FROM dmpDefaultMPU6050.c */
  442. #define INT_SRC_TAP (0x01)
  443. #define INT_SRC_ANDROID_ORIENT (0x08)
  444. #define DMP_FEATURE_SEND_ANY_GYRO (DMP_FEATURE_SEND_RAW_GYRO | \
  445. DMP_FEATURE_SEND_CAL_GYRO)
  446. #define MAX_PACKET_LENGTH (32)
  447. #define DMP_SAMPLE_RATE (200)
  448. #define GYRO_SF (46850825LL * 200 / DMP_SAMPLE_RATE)
  449. #define FIFO_CORRUPTION_CHECK
  450. #ifdef FIFO_CORRUPTION_CHECK
  451. #define QUAT_ERROR_THRESH (1L<<24)
  452. #define QUAT_MAG_SQ_NORMALIZED (1L<<28)
  453. #define QUAT_MAG_SQ_MIN (QUAT_MAG_SQ_NORMALIZED - QUAT_ERROR_THRESH)
  454. #define QUAT_MAG_SQ_MAX (QUAT_MAG_SQ_NORMALIZED + QUAT_ERROR_THRESH)
  455. #endif
  456. struct dmp_s {
  457. void (*tap_cb)(unsigned char count, unsigned char direction);
  458. void (*android_orient_cb)(unsigned char orientation);
  459. unsigned short orient;
  460. unsigned short feature_mask;
  461. unsigned short fifo_rate;
  462. unsigned char packet_length;
  463. };
  464. //static struct dmp_s dmp = {
  465. // .tap_cb = NULL,
  466. // .android_orient_cb = NULL,
  467. // .orient = 0,
  468. // .feature_mask = 0,
  469. // .fifo_rate = 0,
  470. // .packet_length = 0
  471. //};
  472. static struct dmp_s dmp={
  473. NULL,
  474. NULL,
  475. 0,
  476. 0,
  477. 0,
  478. 0
  479. };
  480. /**
  481. * @brief Load the DMP with this image.
  482. * @return 0 if successful.
  483. */
  484. int dmp_load_motion_driver_firmware(void)
  485. {
  486. return mpu_load_firmware(DMP_CODE_SIZE, dmp_memory, sStartAddress,
  487. DMP_SAMPLE_RATE);
  488. }
  489. /**
  490. * @brief Push gyro and accel orientation to the DMP.
  491. * The orientation is represented here as the output of
  492. * @e inv_orientation_matrix_to_scalar.
  493. * @param[in] orient Gyro and accel orientation in body frame.
  494. * @return 0 if successful.
  495. */
  496. int dmp_set_orientation(unsigned short orient)
  497. {
  498. unsigned char gyro_regs[3], accel_regs[3];
  499. const unsigned char gyro_axes[3] = {DINA4C, DINACD, DINA6C};
  500. const unsigned char accel_axes[3] = {DINA0C, DINAC9, DINA2C};
  501. const unsigned char gyro_sign[3] = {DINA36, DINA56, DINA76};
  502. const unsigned char accel_sign[3] = {DINA26, DINA46, DINA66};
  503. gyro_regs[0] = gyro_axes[orient & 3];
  504. gyro_regs[1] = gyro_axes[(orient >> 3) & 3];
  505. gyro_regs[2] = gyro_axes[(orient >> 6) & 3];
  506. accel_regs[0] = accel_axes[orient & 3];
  507. accel_regs[1] = accel_axes[(orient >> 3) & 3];
  508. accel_regs[2] = accel_axes[(orient >> 6) & 3];
  509. /* Chip-to-body, axes only. */
  510. if (mpu_write_mem(FCFG_1, 3, gyro_regs))
  511. return -1;
  512. if (mpu_write_mem(FCFG_2, 3, accel_regs))
  513. return -1;
  514. memcpy(gyro_regs, gyro_sign, 3);
  515. memcpy(accel_regs, accel_sign, 3);
  516. if (orient & 4) {
  517. gyro_regs[0] |= 1;
  518. accel_regs[0] |= 1;
  519. }
  520. if (orient & 0x20) {
  521. gyro_regs[1] |= 1;
  522. accel_regs[1] |= 1;
  523. }
  524. if (orient & 0x100) {
  525. gyro_regs[2] |= 1;
  526. accel_regs[2] |= 1;
  527. }
  528. /* Chip-to-body, sign only. */
  529. if (mpu_write_mem(FCFG_3, 3, gyro_regs))
  530. return -1;
  531. if (mpu_write_mem(FCFG_7, 3, accel_regs))
  532. return -1;
  533. dmp.orient = orient;
  534. return 0;
  535. }
  536. /**
  537. * @brief Push gyro biases to the DMP.
  538. * Because the gyro integration is handled in the DMP, any gyro biases
  539. * calculated by the MPL should be pushed down to DMP memory to remove
  540. * 3-axis quaternion drift.
  541. * \n NOTE: If the DMP-based gyro calibration is enabled, the DMP will
  542. * overwrite the biases written to this location once a new one is computed.
  543. * @param[in] bias Gyro biases in q16.
  544. * @return 0 if successful.
  545. */
  546. int dmp_set_gyro_bias(long *bias)
  547. {
  548. long gyro_bias_body[3];
  549. unsigned char regs[4];
  550. gyro_bias_body[0] = bias[dmp.orient & 3];
  551. if (dmp.orient & 4)
  552. gyro_bias_body[0] *= -1;
  553. gyro_bias_body[1] = bias[(dmp.orient >> 3) & 3];
  554. if (dmp.orient & 0x20)
  555. gyro_bias_body[1] *= -1;
  556. gyro_bias_body[2] = bias[(dmp.orient >> 6) & 3];
  557. if (dmp.orient & 0x100)
  558. gyro_bias_body[2] *= -1;
  559. #ifdef EMPL_NO_64BIT
  560. gyro_bias_body[0] = (long)(((float)gyro_bias_body[0] * GYRO_SF) / 1073741824.f);
  561. gyro_bias_body[1] = (long)(((float)gyro_bias_body[1] * GYRO_SF) / 1073741824.f);
  562. gyro_bias_body[2] = (long)(((float)gyro_bias_body[2] * GYRO_SF) / 1073741824.f);
  563. #else
  564. gyro_bias_body[0] = (long)(((long long)gyro_bias_body[0] * GYRO_SF) >> 30);
  565. gyro_bias_body[1] = (long)(((long long)gyro_bias_body[1] * GYRO_SF) >> 30);
  566. gyro_bias_body[2] = (long)(((long long)gyro_bias_body[2] * GYRO_SF) >> 30);
  567. #endif
  568. regs[0] = (unsigned char)((gyro_bias_body[0] >> 24) & 0xFF);
  569. regs[1] = (unsigned char)((gyro_bias_body[0] >> 16) & 0xFF);
  570. regs[2] = (unsigned char)((gyro_bias_body[0] >> 8) & 0xFF);
  571. regs[3] = (unsigned char)(gyro_bias_body[0] & 0xFF);
  572. if (mpu_write_mem(D_EXT_GYRO_BIAS_X, 4, regs))
  573. return -1;
  574. regs[0] = (unsigned char)((gyro_bias_body[1] >> 24) & 0xFF);
  575. regs[1] = (unsigned char)((gyro_bias_body[1] >> 16) & 0xFF);
  576. regs[2] = (unsigned char)((gyro_bias_body[1] >> 8) & 0xFF);
  577. regs[3] = (unsigned char)(gyro_bias_body[1] & 0xFF);
  578. if (mpu_write_mem(D_EXT_GYRO_BIAS_Y, 4, regs))
  579. return -1;
  580. regs[0] = (unsigned char)((gyro_bias_body[2] >> 24) & 0xFF);
  581. regs[1] = (unsigned char)((gyro_bias_body[2] >> 16) & 0xFF);
  582. regs[2] = (unsigned char)((gyro_bias_body[2] >> 8) & 0xFF);
  583. regs[3] = (unsigned char)(gyro_bias_body[2] & 0xFF);
  584. return mpu_write_mem(D_EXT_GYRO_BIAS_Z, 4, regs);
  585. }
  586. /**
  587. * @brief Push accel biases to the DMP.
  588. * These biases will be removed from the DMP 6-axis quaternion.
  589. * @param[in] bias Accel biases in q16.
  590. * @return 0 if successful.
  591. */
  592. int dmp_set_accel_bias(long *bias)
  593. {
  594. long accel_bias_body[3];
  595. unsigned char regs[12];
  596. long long accel_sf;
  597. unsigned short accel_sens;
  598. mpu_get_accel_sens(&accel_sens);
  599. accel_sf = (long long)accel_sens << 15;
  600. //__no_operation();
  601. accel_bias_body[0] = bias[dmp.orient & 3];
  602. if (dmp.orient & 4)
  603. accel_bias_body[0] *= -1;
  604. accel_bias_body[1] = bias[(dmp.orient >> 3) & 3];
  605. if (dmp.orient & 0x20)
  606. accel_bias_body[1] *= -1;
  607. accel_bias_body[2] = bias[(dmp.orient >> 6) & 3];
  608. if (dmp.orient & 0x100)
  609. accel_bias_body[2] *= -1;
  610. #ifdef EMPL_NO_64BIT
  611. accel_bias_body[0] = (long)(((float)accel_bias_body[0] * accel_sf) / 1073741824.f);
  612. accel_bias_body[1] = (long)(((float)accel_bias_body[1] * accel_sf) / 1073741824.f);
  613. accel_bias_body[2] = (long)(((float)accel_bias_body[2] * accel_sf) / 1073741824.f);
  614. #else
  615. accel_bias_body[0] = (long)(((long long)accel_bias_body[0] * accel_sf) >> 30);
  616. accel_bias_body[1] = (long)(((long long)accel_bias_body[1] * accel_sf) >> 30);
  617. accel_bias_body[2] = (long)(((long long)accel_bias_body[2] * accel_sf) >> 30);
  618. #endif
  619. regs[0] = (unsigned char)((accel_bias_body[0] >> 24) & 0xFF);
  620. regs[1] = (unsigned char)((accel_bias_body[0] >> 16) & 0xFF);
  621. regs[2] = (unsigned char)((accel_bias_body[0] >> 8) & 0xFF);
  622. regs[3] = (unsigned char)(accel_bias_body[0] & 0xFF);
  623. regs[4] = (unsigned char)((accel_bias_body[1] >> 24) & 0xFF);
  624. regs[5] = (unsigned char)((accel_bias_body[1] >> 16) & 0xFF);
  625. regs[6] = (unsigned char)((accel_bias_body[1] >> 8) & 0xFF);
  626. regs[7] = (unsigned char)(accel_bias_body[1] & 0xFF);
  627. regs[8] = (unsigned char)((accel_bias_body[2] >> 24) & 0xFF);
  628. regs[9] = (unsigned char)((accel_bias_body[2] >> 16) & 0xFF);
  629. regs[10] = (unsigned char)((accel_bias_body[2] >> 8) & 0xFF);
  630. regs[11] = (unsigned char)(accel_bias_body[2] & 0xFF);
  631. return mpu_write_mem(D_ACCEL_BIAS, 12, regs);
  632. }
  633. /**
  634. * @brief Set DMP output rate.
  635. * Only used when DMP is on.
  636. * @param[in] rate Desired fifo rate (Hz).
  637. * @return 0 if successful.
  638. */
  639. int dmp_set_fifo_rate(unsigned short rate)
  640. {
  641. const unsigned char regs_end[12] = {DINAFE, DINAF2, DINAAB,
  642. 0xc4, DINAAA, DINAF1, DINADF, DINADF, 0xBB, 0xAF, DINADF, DINADF};
  643. unsigned short div;
  644. unsigned char tmp[8];
  645. if (rate > DMP_SAMPLE_RATE)
  646. return -1;
  647. div = DMP_SAMPLE_RATE / rate - 1;
  648. tmp[0] = (unsigned char)((div >> 8) & 0xFF);
  649. tmp[1] = (unsigned char)(div & 0xFF);
  650. if (mpu_write_mem(D_0_22, 2, tmp))
  651. return -1;
  652. if (mpu_write_mem(CFG_6, 12, (unsigned char*)regs_end))
  653. return -1;
  654. dmp.fifo_rate = rate;
  655. return 0;
  656. }
  657. /**
  658. * @brief Get DMP output rate.
  659. * @param[out] rate Current fifo rate (Hz).
  660. * @return 0 if successful.
  661. */
  662. int dmp_get_fifo_rate(unsigned short *rate)
  663. {
  664. rate[0] = dmp.fifo_rate;
  665. return 0;
  666. }
  667. /**
  668. * @brief Set tap threshold for a specific axis.
  669. * @param[in] axis 1, 2, and 4 for XYZ accel, respectively.
  670. * @param[in] thresh Tap threshold, in mg/ms.
  671. * @return 0 if successful.
  672. */
  673. int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh)
  674. {
  675. unsigned char tmp[4], accel_fsr;
  676. float scaled_thresh;
  677. unsigned short dmp_thresh, dmp_thresh_2;
  678. if (!(axis & TAP_XYZ) || thresh > 1600)
  679. return -1;
  680. scaled_thresh = (float)thresh / DMP_SAMPLE_RATE;
  681. mpu_get_accel_fsr(&accel_fsr);
  682. switch (accel_fsr) {
  683. case 2:
  684. dmp_thresh = (unsigned short)(scaled_thresh * 16384);
  685. /* dmp_thresh * 0.75 */
  686. dmp_thresh_2 = (unsigned short)(scaled_thresh * 12288);
  687. break;
  688. case 4:
  689. dmp_thresh = (unsigned short)(scaled_thresh * 8192);
  690. /* dmp_thresh * 0.75 */
  691. dmp_thresh_2 = (unsigned short)(scaled_thresh * 6144);
  692. break;
  693. case 8:
  694. dmp_thresh = (unsigned short)(scaled_thresh * 4096);
  695. /* dmp_thresh * 0.75 */
  696. dmp_thresh_2 = (unsigned short)(scaled_thresh * 3072);
  697. break;
  698. case 16:
  699. dmp_thresh = (unsigned short)(scaled_thresh * 2048);
  700. /* dmp_thresh * 0.75 */
  701. dmp_thresh_2 = (unsigned short)(scaled_thresh * 1536);
  702. break;
  703. default:
  704. return -1;
  705. }
  706. tmp[0] = (unsigned char)(dmp_thresh >> 8);
  707. tmp[1] = (unsigned char)(dmp_thresh & 0xFF);
  708. tmp[2] = (unsigned char)(dmp_thresh_2 >> 8);
  709. tmp[3] = (unsigned char)(dmp_thresh_2 & 0xFF);
  710. if (axis & TAP_X) {
  711. if (mpu_write_mem(DMP_TAP_THX, 2, tmp))
  712. return -1;
  713. if (mpu_write_mem(D_1_36, 2, tmp+2))
  714. return -1;
  715. }
  716. if (axis & TAP_Y) {
  717. if (mpu_write_mem(DMP_TAP_THY, 2, tmp))
  718. return -1;
  719. if (mpu_write_mem(D_1_40, 2, tmp+2))
  720. return -1;
  721. }
  722. if (axis & TAP_Z) {
  723. if (mpu_write_mem(DMP_TAP_THZ, 2, tmp))
  724. return -1;
  725. if (mpu_write_mem(D_1_44, 2, tmp+2))
  726. return -1;
  727. }
  728. return 0;
  729. }
  730. /**
  731. * @brief Set which axes will register a tap.
  732. * @param[in] axis 1, 2, and 4 for XYZ, respectively.
  733. * @return 0 if successful.
  734. */
  735. int dmp_set_tap_axes(unsigned char axis)
  736. {
  737. unsigned char tmp = 0;
  738. if (axis & TAP_X)
  739. tmp |= 0x30;
  740. if (axis & TAP_Y)
  741. tmp |= 0x0C;
  742. if (axis & TAP_Z)
  743. tmp |= 0x03;
  744. return mpu_write_mem(D_1_72, 1, &tmp);
  745. }
  746. /**
  747. * @brief Set minimum number of taps needed for an interrupt.
  748. * @param[in] min_taps Minimum consecutive taps (1-4).
  749. * @return 0 if successful.
  750. */
  751. int dmp_set_tap_count(unsigned char min_taps)
  752. {
  753. unsigned char tmp;
  754. if (min_taps < 1)
  755. min_taps = 1;
  756. else if (min_taps > 4)
  757. min_taps = 4;
  758. tmp = min_taps - 1;
  759. return mpu_write_mem(D_1_79, 1, &tmp);
  760. }
  761. /**
  762. * @brief Set length between valid taps.
  763. * @param[in] time Milliseconds between taps.
  764. * @return 0 if successful.
  765. */
  766. int dmp_set_tap_time(unsigned short time)
  767. {
  768. unsigned short dmp_time;
  769. unsigned char tmp[2];
  770. dmp_time = time / (1000 / DMP_SAMPLE_RATE);
  771. tmp[0] = (unsigned char)(dmp_time >> 8);
  772. tmp[1] = (unsigned char)(dmp_time & 0xFF);
  773. return mpu_write_mem(DMP_TAPW_MIN, 2, tmp);
  774. }
  775. /**
  776. * @brief Set max time between taps to register as a multi-tap.
  777. * @param[in] time Max milliseconds between taps.
  778. * @return 0 if successful.
  779. */
  780. int dmp_set_tap_time_multi(unsigned short time)
  781. {
  782. unsigned short dmp_time;
  783. unsigned char tmp[2];
  784. dmp_time = time / (1000 / DMP_SAMPLE_RATE);
  785. tmp[0] = (unsigned char)(dmp_time >> 8);
  786. tmp[1] = (unsigned char)(dmp_time & 0xFF);
  787. return mpu_write_mem(D_1_218, 2, tmp);
  788. }
  789. /**
  790. * @brief Set shake rejection threshold.
  791. * If the DMP detects a gyro sample larger than @e thresh, taps are rejected.
  792. * @param[in] sf Gyro scale factor.
  793. * @param[in] thresh Gyro threshold in dps.
  794. * @return 0 if successful.
  795. */
  796. int dmp_set_shake_reject_thresh(long sf, unsigned short thresh)
  797. {
  798. unsigned char tmp[4];
  799. long thresh_scaled = sf / 1000 * thresh;
  800. tmp[0] = (unsigned char)(((long)thresh_scaled >> 24) & 0xFF);
  801. tmp[1] = (unsigned char)(((long)thresh_scaled >> 16) & 0xFF);
  802. tmp[2] = (unsigned char)(((long)thresh_scaled >> 8) & 0xFF);
  803. tmp[3] = (unsigned char)((long)thresh_scaled & 0xFF);
  804. return mpu_write_mem(D_1_92, 4, tmp);
  805. }
  806. /**
  807. * @brief Set shake rejection time.
  808. * Sets the length of time that the gyro must be outside of the threshold set
  809. * by @e gyro_set_shake_reject_thresh before taps are rejected. A mandatory
  810. * 60 ms is added to this parameter.
  811. * @param[in] time Time in milliseconds.
  812. * @return 0 if successful.
  813. */
  814. int dmp_set_shake_reject_time(unsigned short time)
  815. {
  816. unsigned char tmp[2];
  817. time /= (1000 / DMP_SAMPLE_RATE);
  818. tmp[0] = time >> 8;
  819. tmp[1] = time & 0xFF;
  820. return mpu_write_mem(D_1_90,2,tmp);
  821. }
  822. /**
  823. * @brief Set shake rejection timeout.
  824. * Sets the length of time after a shake rejection that the gyro must stay
  825. * inside of the threshold before taps can be detected again. A mandatory
  826. * 60 ms is added to this parameter.
  827. * @param[in] time Time in milliseconds.
  828. * @return 0 if successful.
  829. */
  830. int dmp_set_shake_reject_timeout(unsigned short time)
  831. {
  832. unsigned char tmp[2];
  833. time /= (1000 / DMP_SAMPLE_RATE);
  834. tmp[0] = time >> 8;
  835. tmp[1] = time & 0xFF;
  836. return mpu_write_mem(D_1_88,2,tmp);
  837. }
  838. /**
  839. * @brief Get current step count.
  840. * @param[out] count Number of steps detected.
  841. * @return 0 if successful.
  842. */
  843. int dmp_get_pedometer_step_count(unsigned long *count)
  844. {
  845. unsigned char tmp[4];
  846. if (!count)
  847. return -1;
  848. if (mpu_read_mem(D_PEDSTD_STEPCTR, 4, tmp))
  849. return -1;
  850. count[0] = ((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) |
  851. ((unsigned long)tmp[2] << 8) | tmp[3];
  852. return 0;
  853. }
  854. /**
  855. * @brief Overwrite current step count.
  856. * WARNING: This function writes to DMP memory and could potentially encounter
  857. * a race condition if called while the pedometer is enabled.
  858. * @param[in] count New step count.
  859. * @return 0 if successful.
  860. */
  861. int dmp_set_pedometer_step_count(unsigned long count)
  862. {
  863. unsigned char tmp[4];
  864. tmp[0] = (unsigned char)((count >> 24) & 0xFF);
  865. tmp[1] = (unsigned char)((count >> 16) & 0xFF);
  866. tmp[2] = (unsigned char)((count >> 8) & 0xFF);
  867. tmp[3] = (unsigned char)(count & 0xFF);
  868. return mpu_write_mem(D_PEDSTD_STEPCTR, 4, tmp);
  869. }
  870. /**
  871. * @brief Get duration of walking time.
  872. * @param[in] time Walk time in milliseconds.
  873. * @return 0 if successful.
  874. */
  875. int dmp_get_pedometer_walk_time(unsigned long *time)
  876. {
  877. unsigned char tmp[4];
  878. if (!time)
  879. return -1;
  880. if (mpu_read_mem(D_PEDSTD_TIMECTR, 4, tmp))
  881. return -1;
  882. time[0] = (((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) |
  883. ((unsigned long)tmp[2] << 8) | tmp[3]) * 20;
  884. return 0;
  885. }
  886. /**
  887. * @brief Overwrite current walk time.
  888. * WARNING: This function writes to DMP memory and could potentially encounter
  889. * a race condition if called while the pedometer is enabled.
  890. * @param[in] time New walk time in milliseconds.
  891. */
  892. int dmp_set_pedometer_walk_time(unsigned long time)
  893. {
  894. unsigned char tmp[4];
  895. time /= 20;
  896. tmp[0] = (unsigned char)((time >> 24) & 0xFF);
  897. tmp[1] = (unsigned char)((time >> 16) & 0xFF);
  898. tmp[2] = (unsigned char)((time >> 8) & 0xFF);
  899. tmp[3] = (unsigned char)(time & 0xFF);
  900. return mpu_write_mem(D_PEDSTD_TIMECTR, 4, tmp);
  901. }
  902. /**
  903. * @brief Enable DMP features.
  904. * The following \#define's are used in the input mask:
  905. * \n DMP_FEATURE_TAP
  906. * \n DMP_FEATURE_ANDROID_ORIENT
  907. * \n DMP_FEATURE_LP_QUAT
  908. * \n DMP_FEATURE_6X_LP_QUAT
  909. * \n DMP_FEATURE_GYRO_CAL
  910. * \n DMP_FEATURE_SEND_RAW_ACCEL
  911. * \n DMP_FEATURE_SEND_RAW_GYRO
  912. * \n NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually
  913. * exclusive.
  914. * \n NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also
  915. * mutually exclusive.
  916. * @param[in] mask Mask of features to enable.
  917. * @return 0 if successful.
  918. */
  919. int dmp_enable_feature(unsigned short mask)
  920. {
  921. unsigned char tmp[10];
  922. /* TODO: All of these settings can probably be integrated into the default
  923. * DMP image.
  924. */
  925. /* Set integration scale factor. */
  926. tmp[0] = (unsigned char)((GYRO_SF >> 24) & 0xFF);
  927. tmp[1] = (unsigned char)((GYRO_SF >> 16) & 0xFF);
  928. tmp[2] = (unsigned char)((GYRO_SF >> 8) & 0xFF);
  929. tmp[3] = (unsigned char)(GYRO_SF & 0xFF);
  930. mpu_write_mem(D_0_104, 4, tmp);
  931. /* Send sensor data to the FIFO. */
  932. tmp[0] = 0xA3;
  933. if (mask & DMP_FEATURE_SEND_RAW_ACCEL) {
  934. tmp[1] = 0xC0;
  935. tmp[2] = 0xC8;
  936. tmp[3] = 0xC2;
  937. } else {
  938. tmp[1] = 0xA3;
  939. tmp[2] = 0xA3;
  940. tmp[3] = 0xA3;
  941. }
  942. if (mask & DMP_FEATURE_SEND_ANY_GYRO) {
  943. tmp[4] = 0xC4;
  944. tmp[5] = 0xCC;
  945. tmp[6] = 0xC6;
  946. } else {
  947. tmp[4] = 0xA3;
  948. tmp[5] = 0xA3;
  949. tmp[6] = 0xA3;
  950. }
  951. tmp[7] = 0xA3;
  952. tmp[8] = 0xA3;
  953. tmp[9] = 0xA3;
  954. mpu_write_mem(CFG_15,10,tmp);
  955. /* Send gesture data to the FIFO. */
  956. if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT))
  957. tmp[0] = DINA20;
  958. else
  959. tmp[0] = 0xD8;
  960. mpu_write_mem(CFG_27,1,tmp);
  961. if (mask & DMP_FEATURE_GYRO_CAL)
  962. dmp_enable_gyro_cal(1);
  963. else
  964. dmp_enable_gyro_cal(0);
  965. if (mask & DMP_FEATURE_SEND_ANY_GYRO) {
  966. if (mask & DMP_FEATURE_SEND_CAL_GYRO) {
  967. tmp[0] = 0xB2;
  968. tmp[1] = 0x8B;
  969. tmp[2] = 0xB6;
  970. tmp[3] = 0x9B;
  971. } else {
  972. tmp[0] = DINAC0;
  973. tmp[1] = DINA80;
  974. tmp[2] = DINAC2;
  975. tmp[3] = DINA90;
  976. }
  977. mpu_write_mem(CFG_GYRO_RAW_DATA, 4, tmp);
  978. }
  979. if (mask & DMP_FEATURE_TAP) {
  980. /* Enable tap. */
  981. tmp[0] = 0xF8;
  982. mpu_write_mem(CFG_20, 1, tmp);
  983. dmp_set_tap_thresh(TAP_XYZ, 250);
  984. dmp_set_tap_axes(TAP_XYZ);
  985. dmp_set_tap_count(1);
  986. dmp_set_tap_time(100);
  987. dmp_set_tap_time_multi(500);
  988. dmp_set_shake_reject_thresh(GYRO_SF, 200);
  989. dmp_set_shake_reject_time(40);
  990. dmp_set_shake_reject_timeout(10);
  991. } else {
  992. tmp[0] = 0xD8;
  993. mpu_write_mem(CFG_20, 1, tmp);
  994. }
  995. if (mask & DMP_FEATURE_ANDROID_ORIENT) {
  996. tmp[0] = 0xD9;
  997. } else
  998. tmp[0] = 0xD8;
  999. mpu_write_mem(CFG_ANDROID_ORIENT_INT, 1, tmp);
  1000. if (mask & DMP_FEATURE_LP_QUAT)
  1001. dmp_enable_lp_quat(1);
  1002. else
  1003. dmp_enable_lp_quat(0);
  1004. if (mask & DMP_FEATURE_6X_LP_QUAT)
  1005. dmp_enable_6x_lp_quat(1);
  1006. else
  1007. dmp_enable_6x_lp_quat(0);
  1008. /* Pedometer is always enabled. */
  1009. dmp.feature_mask = mask | DMP_FEATURE_PEDOMETER;
  1010. mpu_reset_fifo();
  1011. dmp.packet_length = 0;
  1012. if (mask & DMP_FEATURE_SEND_RAW_ACCEL)
  1013. dmp.packet_length += 6;
  1014. if (mask & DMP_FEATURE_SEND_ANY_GYRO)
  1015. dmp.packet_length += 6;
  1016. if (mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT))
  1017. dmp.packet_length += 16;
  1018. if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT))
  1019. dmp.packet_length += 4;
  1020. return 0;
  1021. }
  1022. /**
  1023. * @brief Get list of currently enabled DMP features.
  1024. * @param[out] Mask of enabled features.
  1025. * @return 0 if successful.
  1026. */
  1027. int dmp_get_enabled_features(unsigned short *mask)
  1028. {
  1029. mask[0] = dmp.feature_mask;
  1030. return 0;
  1031. }
  1032. /**
  1033. * @brief Calibrate the gyro data in the DMP.
  1034. * After eight seconds of no motion, the DMP will compute gyro biases and
  1035. * subtract them from the quaternion output. If @e dmp_enable_feature is
  1036. * called with @e DMP_FEATURE_SEND_CAL_GYRO, the biases will also be
  1037. * subtracted from the gyro output.
  1038. * @param[in] enable 1 to enable gyro calibration.
  1039. * @return 0 if successful.
  1040. */
  1041. int dmp_enable_gyro_cal(unsigned char enable)
  1042. {
  1043. if (enable) {
  1044. unsigned char regs[9] = {0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 0x5d};
  1045. return mpu_write_mem(CFG_MOTION_BIAS, 9, regs);
  1046. } else {
  1047. unsigned char regs[9] = {0xb8, 0xaa, 0xaa, 0xaa, 0xb0, 0x88, 0xc3, 0xc5, 0xc7};
  1048. return mpu_write_mem(CFG_MOTION_BIAS, 9, regs);
  1049. }
  1050. }
  1051. /**
  1052. * @brief Generate 3-axis quaternions from the DMP.
  1053. * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually
  1054. * exclusive.
  1055. * @param[in] enable 1 to enable 3-axis quaternion.
  1056. * @return 0 if successful.
  1057. */
  1058. int dmp_enable_lp_quat(unsigned char enable)
  1059. {
  1060. unsigned char regs[4];
  1061. if (enable) {
  1062. regs[0] = DINBC0;
  1063. regs[1] = DINBC2;
  1064. regs[2] = DINBC4;
  1065. regs[3] = DINBC6;
  1066. }
  1067. else
  1068. memset(regs, 0x8B, 4);
  1069. mpu_write_mem(CFG_LP_QUAT, 4, regs);
  1070. return mpu_reset_fifo();
  1071. }
  1072. /**
  1073. * @brief Generate 6-axis quaternions from the DMP.
  1074. * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually
  1075. * exclusive.
  1076. * @param[in] enable 1 to enable 6-axis quaternion.
  1077. * @return 0 if successful.
  1078. */
  1079. int dmp_enable_6x_lp_quat(unsigned char enable)
  1080. {
  1081. unsigned char regs[4];
  1082. if (enable) {
  1083. regs[0] = DINA20;
  1084. regs[1] = DINA28;
  1085. regs[2] = DINA30;
  1086. regs[3] = DINA38;
  1087. } else
  1088. memset(regs, 0xA3, 4);
  1089. mpu_write_mem(CFG_8, 4, regs);
  1090. return mpu_reset_fifo();
  1091. }
  1092. /**
  1093. * @brief Decode the four-byte gesture data and execute any callbacks.
  1094. * @param[in] gesture Gesture data from DMP packet.
  1095. * @return 0 if successful.
  1096. */
  1097. static int decode_gesture(unsigned char *gesture)
  1098. {
  1099. unsigned char tap, android_orient;
  1100. android_orient = gesture[3] & 0xC0;
  1101. tap = 0x3F & gesture[3];
  1102. if (gesture[1] & INT_SRC_TAP) {
  1103. unsigned char direction, count;
  1104. direction = tap >> 3;
  1105. count = (tap % 8) + 1;
  1106. if (dmp.tap_cb)
  1107. dmp.tap_cb(direction, count);
  1108. }
  1109. if (gesture[1] & INT_SRC_ANDROID_ORIENT) {
  1110. if (dmp.android_orient_cb)
  1111. dmp.android_orient_cb(android_orient >> 6);
  1112. }
  1113. return 0;
  1114. }
  1115. /**
  1116. * @brief Specify when a DMP interrupt should occur.
  1117. * A DMP interrupt can be configured to trigger on either of the two
  1118. * conditions below:
  1119. * \n a. One FIFO period has elapsed (set by @e mpu_set_sample_rate).
  1120. * \n b. A tap event has been detected.
  1121. * @param[in] mode DMP_INT_GESTURE or DMP_INT_CONTINUOUS.
  1122. * @return 0 if successful.
  1123. */
  1124. int dmp_set_interrupt_mode(unsigned char mode)
  1125. {
  1126. const unsigned char regs_continuous[11] =
  1127. {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9};
  1128. const unsigned char regs_gesture[11] =
  1129. {0xda, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0xda, 0xb4, 0xda};
  1130. switch (mode) {
  1131. case DMP_INT_CONTINUOUS:
  1132. return mpu_write_mem(CFG_FIFO_ON_EVENT, 11,
  1133. (unsigned char*)regs_continuous);
  1134. case DMP_INT_GESTURE:
  1135. return mpu_write_mem(CFG_FIFO_ON_EVENT, 11,
  1136. (unsigned char*)regs_gesture);
  1137. default:
  1138. return -1;
  1139. }
  1140. }
  1141. /**
  1142. * @brief Get one packet from the FIFO.
  1143. * If @e sensors does not contain a particular sensor, disregard the data
  1144. * returned to that pointer.
  1145. * \n @e sensors can contain a combination of the following flags:
  1146. * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO
  1147. * \n INV_XYZ_GYRO
  1148. * \n INV_XYZ_ACCEL
  1149. * \n INV_WXYZ_QUAT
  1150. * \n If the FIFO has no new data, @e sensors will be zero.
  1151. * \n If the FIFO is disabled, @e sensors will be zero and this function will
  1152. * return a non-zero error code.
  1153. * @param[out] gyro Gyro data in hardware units.
  1154. * @param[out] accel Accel data in hardware units.
  1155. * @param[out] quat 3-axis quaternion data in hardware units.
  1156. * @param[out] timestamp Timestamp in milliseconds.
  1157. * @param[out] sensors Mask of sensors read from FIFO.
  1158. * @param[out] more Number of remaining packets.
  1159. * @return 0 if successful.
  1160. */
  1161. int dmp_read_fifo(short *gyro, short *accel, long *quat,
  1162. unsigned long *timestamp, short *sensors, unsigned char *more)
  1163. {
  1164. unsigned char fifo_data[MAX_PACKET_LENGTH];
  1165. unsigned char ii = 0;
  1166. /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can
  1167. * cache this value and save some cycles.
  1168. */
  1169. sensors[0] = 0;
  1170. /* Get a packet. */
  1171. if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more))
  1172. return -1;
  1173. /* Parse DMP packet. */
  1174. if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) {
  1175. #ifdef FIFO_CORRUPTION_CHECK
  1176. long quat_q14[4], quat_mag_sq;
  1177. #endif
  1178. quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) |
  1179. ((long)fifo_data[2] << 8) | fifo_data[3];
  1180. quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) |
  1181. ((long)fifo_data[6] << 8) | fifo_data[7];
  1182. quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) |
  1183. ((long)fifo_data[10] << 8) | fifo_data[11];
  1184. quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) |
  1185. ((long)fifo_data[14] << 8) | fifo_data[15];
  1186. ii += 16;
  1187. #ifdef FIFO_CORRUPTION_CHECK
  1188. /* We can detect a corrupted FIFO by monitoring the quaternion data and
  1189. * ensuring that the magnitude is always normalized to one. This
  1190. * shouldn't happen in normal operation, but if an I2C error occurs,
  1191. * the FIFO reads might become misaligned.
  1192. *
  1193. * Let's start by scaling down the quaternion data to avoid long long
  1194. * math.
  1195. */
  1196. quat_q14[0] = quat[0] >> 16;
  1197. quat_q14[1] = quat[1] >> 16;
  1198. quat_q14[2] = quat[2] >> 16;
  1199. quat_q14[3] = quat[3] >> 16;
  1200. quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] +
  1201. quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3];
  1202. if ((quat_mag_sq < QUAT_MAG_SQ_MIN) ||
  1203. (quat_mag_sq > QUAT_MAG_SQ_MAX)) {
  1204. /* Quaternion is outside of the acceptable threshold. */
  1205. mpu_reset_fifo();
  1206. sensors[0] = 0;
  1207. return -1;
  1208. }
  1209. sensors[0] |= INV_WXYZ_QUAT;
  1210. #endif
  1211. }
  1212. if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) {
  1213. accel[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1];
  1214. accel[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3];
  1215. accel[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5];
  1216. ii += 6;
  1217. sensors[0] |= INV_XYZ_ACCEL;
  1218. }
  1219. if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) {
  1220. gyro[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1];
  1221. gyro[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3];
  1222. gyro[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5];
  1223. ii += 6;
  1224. sensors[0] |= INV_XYZ_GYRO;
  1225. }
  1226. /* Gesture data is at the end of the DMP packet. Parse it and call
  1227. * the gesture callbacks (if registered).
  1228. */
  1229. if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT))
  1230. decode_gesture(fifo_data + ii);
  1231. get_ms(timestamp);
  1232. return 0;
  1233. }
  1234. /**
  1235. * @brief Register a function to be executed on a tap event.
  1236. * The tap direction is represented by one of the following:
  1237. * \n TAP_X_UP
  1238. * \n TAP_X_DOWN
  1239. * \n TAP_Y_UP
  1240. * \n TAP_Y_DOWN
  1241. * \n TAP_Z_UP
  1242. * \n TAP_Z_DOWN
  1243. * @param[in] func Callback function.
  1244. * @return 0 if successful.
  1245. */
  1246. int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char))
  1247. {
  1248. dmp.tap_cb = func;
  1249. return 0;
  1250. }
  1251. /**
  1252. * @brief Register a function to be executed on a android orientation event.
  1253. * @param[in] func Callback function.
  1254. * @return 0 if successful.
  1255. */
  1256. int dmp_register_android_orient_cb(void (*func)(unsigned char))
  1257. {
  1258. dmp.android_orient_cb = func;
  1259. return 0;
  1260. }
  1261. /**
  1262. * @}
  1263. */

(8)inv_mpu_dmp_motion_driver.h

  1. /*
  2. $License:
  3. Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
  4. See included License.txt for License information.
  5. $
  6. */
  7. /**
  8. * @addtogroup DRIVERS Sensor Driver Layer
  9. * @brief Hardware drivers to communicate with sensors via I2C.
  10. *
  11. * @{
  12. * @file inv_mpu_dmp_motion_driver.h
  13. * @brief DMP image and interface functions.
  14. * @details All functions are preceded by the dmp_ prefix to
  15. * differentiate among MPL and general driver function calls.
  16. */
  17. #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_
  18. #define _INV_MPU_DMP_MOTION_DRIVER_H_
  19. #define TAP_X (0x01)
  20. #define TAP_Y (0x02)
  21. #define TAP_Z (0x04)
  22. #define TAP_XYZ (0x07)
  23. #define TAP_X_UP (0x01)
  24. #define TAP_X_DOWN (0x02)
  25. #define TAP_Y_UP (0x03)
  26. #define TAP_Y_DOWN (0x04)
  27. #define TAP_Z_UP (0x05)
  28. #define TAP_Z_DOWN (0x06)
  29. #define ANDROID_ORIENT_PORTRAIT (0x00)
  30. #define ANDROID_ORIENT_LANDSCAPE (0x01)
  31. #define ANDROID_ORIENT_REVERSE_PORTRAIT (0x02)
  32. #define ANDROID_ORIENT_REVERSE_LANDSCAPE (0x03)
  33. #define DMP_INT_GESTURE (0x01)
  34. #define DMP_INT_CONTINUOUS (0x02)
  35. #define DMP_FEATURE_TAP (0x001)
  36. #define DMP_FEATURE_ANDROID_ORIENT (0x002)
  37. #define DMP_FEATURE_LP_QUAT (0x004)
  38. #define DMP_FEATURE_PEDOMETER (0x008)
  39. #define DMP_FEATURE_6X_LP_QUAT (0x010)
  40. #define DMP_FEATURE_GYRO_CAL (0x020)
  41. #define DMP_FEATURE_SEND_RAW_ACCEL (0x040)
  42. #define DMP_FEATURE_SEND_RAW_GYRO (0x080)
  43. #define DMP_FEATURE_SEND_CAL_GYRO (0x100)
  44. #define INV_WXYZ_QUAT (0x100)
  45. /* Set up functions. */
  46. int dmp_load_motion_driver_firmware(void);
  47. int dmp_set_fifo_rate(unsigned short rate);
  48. int dmp_get_fifo_rate(unsigned short *rate);
  49. int dmp_enable_feature(unsigned short mask);
  50. int dmp_get_enabled_features(unsigned short *mask);
  51. int dmp_set_interrupt_mode(unsigned char mode);
  52. int dmp_set_orientation(unsigned short orient);
  53. int dmp_set_gyro_bias(long *bias);
  54. int dmp_set_accel_bias(long *bias);
  55. /* Tap functions. */
  56. int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char));
  57. int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh);
  58. int dmp_set_tap_axes(unsigned char axis);
  59. int dmp_set_tap_count(unsigned char min_taps);
  60. int dmp_set_tap_time(unsigned short time);
  61. int dmp_set_tap_time_multi(unsigned short time);
  62. int dmp_set_shake_reject_thresh(long sf, unsigned short thresh);
  63. int dmp_set_shake_reject_time(unsigned short time);
  64. int dmp_set_shake_reject_timeout(unsigned short time);
  65. /* Android orientation functions. */
  66. int dmp_register_android_orient_cb(void (*func)(unsigned char));
  67. /* LP quaternion functions. */
  68. int dmp_enable_lp_quat(unsigned char enable);
  69. int dmp_enable_6x_lp_quat(unsigned char enable);
  70. /* Pedometer functions. */
  71. int dmp_get_pedometer_step_count(unsigned long *count);
  72. int dmp_set_pedometer_step_count(unsigned long count);
  73. int dmp_get_pedometer_walk_time(unsigned long *time);
  74. int dmp_set_pedometer_walk_time(unsigned long time);
  75. /* DMP gyro calibration functions. */
  76. int dmp_enable_gyro_cal(unsigned char enable);
  77. /* Read function. This function should be called whenever the MPU interrupt is
  78. * detected.
  79. */
  80. int dmp_read_fifo(short *gyro, short *accel, long *quat,
  81. unsigned long *timestamp, short *sensors, unsigned char *more);
  82. #endif /* #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ */

五、STM32驱动MPU6050开源工程

链接:https://pan.baidu.com/s/14AMqZV39YNEWqqx0ESKJvw?pwd=zxf1 
提取码:zxf1 
--来自百度网盘超级会员V2的分享

链接:https://pan.baidu.com/s/1b8bJiqHlFljnCREeMtJT6g?pwd=zxf1 
提取码:zxf1 
--来自百度网盘超级会员V2的分享

六、MPU6050资料

需要的读者可以下方留言或者私信我,收到后会第一时间回复。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/900054
推荐阅读
相关标签
  

闽ICP备14008679号