Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / accgyro / accgyro_mpu9250.c
blob1e9360f4b36175ce78253ba61e61d56d4b4e2c1e
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
22 #include "platform.h"
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) {
52 return false;
55 mpuContextData_t * ctx = busDeviceGetScratchpadMemory(acc->busDev);
56 if (ctx->chipMagicNumber != 0x9250) {
57 return false;
60 acc->initFn = mpu9250AccInit;
61 acc->readFn = mpuAccReadScratchpad;
62 acc->accAlign = acc->busDev->param;
64 return true;
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);
76 delay(100);
78 busWrite(dev, MPU_RA_SIGNAL_PATH_RESET, 0x07); // BIT_GYRO | BIT_ACC | BIT_TEMP
79 delay(100);
81 busWrite(dev, MPU_RA_PWR_MGMT_1, 0);
82 delay(100);
84 busWrite(dev, MPU_RA_PWR_MGMT_1, INV_CLK_PLL);
85 delay(15);
87 busWrite(dev, MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3 | FCB_DISABLED);
88 delay(15);
90 busWrite(dev, MPU_RA_ACCEL_CONFIG, INV_FSR_16G << 3);
91 delay(15);
93 busWrite(dev, MPU_RA_CONFIG, config->gyroConfigValues[0]);
94 delay(15);
96 busWrite(dev, MPU_RA_SMPLRT_DIV, config->gyroConfigValues[1]);
97 delay(100);
99 busSetSpeed(dev, BUS_SPEED_FAST);
102 static bool mpu9250DeviceDetect(busDevice_t * dev)
104 uint8_t tmp;
105 uint8_t attemptsRemaining = 5;
107 busSetSpeed(dev, BUS_SPEED_INITIALIZATION);
109 busWrite(dev, MPU_RA_PWR_MGMT_1, MPU9250_BIT_RESET);
111 do {
112 delay(150);
114 busRead(dev, MPU_RA_WHO_AM_I, &tmp);
116 switch (tmp) {
117 case MPU9250_WHO_AM_I_CONST:
118 case MPU9255_WHO_AM_I_CONST:
119 // Compatible chip detected
120 return true;
122 default:
123 // Retry detection
124 break;
127 if (!attemptsRemaining) {
128 return false;
130 } while (attemptsRemaining--);
132 return false;
135 bool mpu9250GyroDetect(gyroDev_t *gyro)
137 gyro->busDev = busDeviceInit(BUSTYPE_ANY, DEVHW_MPU9250, gyro->imuSensorToUse, OWNER_MPU);
138 if (gyro->busDev == NULL) {
139 return false;
142 if (!mpu9250DeviceDetect(gyro->busDev)) {
143 busDeviceDeInit(gyro->busDev);
144 return false;
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;
158 return true;
161 #endif