Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / accgyro / accgyro_mpu6500.c
blob5a2207a498b6f32e6a05ccf06c9c4e61ac1165de
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_mpu6500.h"
35 #if defined(USE_IMU_MPU6500)
37 #define MPU6500_BIT_RESET (0x80)
38 #define MPU6500_BIT_INT_ANYRD_2CLEAR (1 << 4)
39 #define MPU6500_BIT_BYPASS_EN (1 << 0)
40 #define MPU6500_BIT_I2C_IF_DIS (1 << 4)
41 #define MPU6500_BIT_RAW_RDY_EN (0x01)
43 static void mpu6500AccInit(accDev_t *acc)
45 acc->acc_1G = 512 * 4;
48 bool mpu6500AccDetect(accDev_t *acc)
50 acc->busDev = busDeviceOpen(BUSTYPE_ANY, DEVHW_MPU6500, acc->imuSensorToUse);
51 if (acc->busDev == NULL) {
52 return false;
55 mpuContextData_t * ctx = busDeviceGetScratchpadMemory(acc->busDev);
56 if (ctx->chipMagicNumber != 0x6500) {
57 return false;
60 acc->initFn = mpu6500AccInit;
61 acc->readFn = mpuAccReadScratchpad;
62 acc->accAlign = acc->busDev->param;
64 return true;
67 static void mpu6500AccAndGyroInit(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, MPU6500_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 mpu6500DeviceDetect(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, MPU6500_BIT_RESET);
111 do {
112 delay(150);
114 busRead(dev, MPU_RA_WHO_AM_I, &tmp);
116 switch (tmp) {
117 case MPU6500_WHO_AM_I_CONST:
118 case ICM20608G_WHO_AM_I_CONST:
119 case ICM20601_WHO_AM_I_CONST:
120 case ICM20602_WHO_AM_I_CONST:
121 case ICM20689_WHO_AM_I_CONST:
122 // Compatible chip detected
123 return true;
125 default:
126 // Retry detection
127 break;
129 } while (attemptsRemaining--);
131 return false;
134 bool mpu6500GyroDetect(gyroDev_t *gyro)
136 gyro->busDev = busDeviceInit(BUSTYPE_ANY, DEVHW_MPU6500, gyro->imuSensorToUse, OWNER_MPU);
137 if (gyro->busDev == NULL) {
138 return false;
141 if (!mpu6500DeviceDetect(gyro->busDev)) {
142 busDeviceDeInit(gyro->busDev);
143 return false;
146 // Magic number for ACC detection to indicate that we have detected MPU6500 gyro
147 mpuContextData_t * ctx = busDeviceGetScratchpadMemory(gyro->busDev);
148 ctx->chipMagicNumber = 0x6500;
150 gyro->initFn = mpu6500AccAndGyroInit;
151 gyro->readFn = mpuGyroReadScratchpad;
152 gyro->intStatusFn = gyroCheckDataReady;
153 gyro->temperatureFn = mpuTemperatureReadScratchpad;
154 gyro->scale = 1.0f / 16.4f; // 16.4 dps/lsb scalefactor
155 gyro->gyroAlign = gyro->busDev->param;
157 return true;
160 #endif