2 * This file is part of INAV.
4 * INAV is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * INAV is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with INAV. If not, see <http://www.gnu.org/licenses/>.
24 #include "common/axis.h"
25 #include "common/maths.h"
27 #include "drivers/system.h"
28 #include "drivers/time.h"
30 #include "drivers/sensor.h"
31 #include "drivers/accgyro/accgyro.h"
32 #include "drivers/accgyro/accgyro_mpu.h"
33 #include "drivers/accgyro/accgyro_mpu9250.h"
35 #if defined(USE_IMU_MPU9250)
37 #define MPU9250_BIT_RESET (0x80)
38 #define MPU9250_BIT_INT_ANYRD_2CLEAR (1 << 4)
39 #define MPU9250_BIT_BYPASS_EN (1 << 0)
40 #define MPU9250_BIT_I2C_IF_DIS (1 << 4)
41 #define MPU9250_BIT_RAW_RDY_EN (0x01)
43 static void mpu9250AccInit(accDev_t
*acc
)
45 acc
->acc_1G
= 512 * 4;
48 bool mpu9250AccDetect(accDev_t
*acc
)
50 acc
->busDev
= busDeviceOpen(BUSTYPE_ANY
, DEVHW_MPU9250
, acc
->imuSensorToUse
);
51 if (acc
->busDev
== NULL
) {
55 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(acc
->busDev
);
56 if (ctx
->chipMagicNumber
!= 0x9250) {
60 acc
->initFn
= mpu9250AccInit
;
61 acc
->readFn
= mpuAccReadScratchpad
;
62 acc
->accAlign
= acc
->busDev
->param
;
67 static void mpu9250AccAndGyroInit(gyroDev_t
*gyro
)
69 busDevice_t
* dev
= gyro
->busDev
;
70 const gyroFilterAndRateConfig_t
* config
= mpuChooseGyroConfig(gyro
->lpf
, 1000000 / gyro
->requestedSampleIntervalUs
);
71 gyro
->sampleRateIntervalUs
= 1000000 / config
->gyroRateHz
;
73 busSetSpeed(dev
, BUS_SPEED_INITIALIZATION
);
75 busWrite(dev
, MPU_RA_PWR_MGMT_1
, MPU9250_BIT_RESET
);
78 busWrite(dev
, MPU_RA_SIGNAL_PATH_RESET
, 0x07); // BIT_GYRO | BIT_ACC | BIT_TEMP
81 busWrite(dev
, MPU_RA_PWR_MGMT_1
, 0);
84 busWrite(dev
, MPU_RA_PWR_MGMT_1
, INV_CLK_PLL
);
87 busWrite(dev
, MPU_RA_GYRO_CONFIG
, INV_FSR_2000DPS
<< 3 | FCB_DISABLED
);
90 busWrite(dev
, MPU_RA_ACCEL_CONFIG
, INV_FSR_16G
<< 3);
93 busWrite(dev
, MPU_RA_CONFIG
, config
->gyroConfigValues
[0]);
96 busWrite(dev
, MPU_RA_SMPLRT_DIV
, config
->gyroConfigValues
[1]);
99 busSetSpeed(dev
, BUS_SPEED_FAST
);
102 static bool mpu9250DeviceDetect(busDevice_t
* dev
)
105 uint8_t attemptsRemaining
= 5;
107 busSetSpeed(dev
, BUS_SPEED_INITIALIZATION
);
109 busWrite(dev
, MPU_RA_PWR_MGMT_1
, MPU9250_BIT_RESET
);
114 busRead(dev
, MPU_RA_WHO_AM_I
, &tmp
);
117 case MPU9250_WHO_AM_I_CONST
:
118 case MPU9255_WHO_AM_I_CONST
:
119 // Compatible chip detected
127 if (!attemptsRemaining
) {
130 } while (attemptsRemaining
--);
135 bool mpu9250GyroDetect(gyroDev_t
*gyro
)
137 gyro
->busDev
= busDeviceInit(BUSTYPE_ANY
, DEVHW_MPU9250
, gyro
->imuSensorToUse
, OWNER_MPU
);
138 if (gyro
->busDev
== NULL
) {
142 if (!mpu9250DeviceDetect(gyro
->busDev
)) {
143 busDeviceDeInit(gyro
->busDev
);
147 // Magic number for ACC detection to indicate that we have detected MPU6000 gyro
148 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(gyro
->busDev
);
149 ctx
->chipMagicNumber
= 0x9250;
151 gyro
->initFn
= mpu9250AccAndGyroInit
;
152 gyro
->readFn
= mpuGyroReadScratchpad
;
153 gyro
->intStatusFn
= gyroCheckDataReady
;
154 gyro
->temperatureFn
= mpuTemperatureReadScratchpad
;
155 gyro
->scale
= 1.0f
/ 16.4f
; // 16.4 dps/lsb scalefactor
156 gyro
->gyroAlign
= gyro
->busDev
->param
;