2 * This file is part of iNavFlight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
26 #include "build/debug.h"
28 #include "common/axis.h"
29 #include "common/maths.h"
31 #include "drivers/system.h"
32 #include "drivers/time.h"
33 #include "drivers/io.h"
34 #include "drivers/bus.h"
36 #include "drivers/accgyro/accgyro.h"
37 #include "drivers/accgyro/accgyro_mpu.h"
38 #include "drivers/accgyro/accgyro_icm20689.h"
40 #if defined(USE_IMU_ICM20689)
42 static uint8_t icm20689DeviceDetect(const busDevice_t
*busDev
)
44 busSetSpeed(busDev
, BUS_SPEED_INITIALIZATION
);
46 busWrite(busDev
, MPU_RA_PWR_MGMT_1
, ICM20689_BIT_RESET
);
48 uint8_t attemptsRemaining
= 20;
52 busRead(busDev
, MPU_RA_WHO_AM_I
, &in
);
54 case ICM20601_WHO_AM_I_CONST
:
55 case ICM20602_WHO_AM_I_CONST
:
56 case ICM20608G_WHO_AM_I_CONST
:
57 case ICM20689_WHO_AM_I_CONST
:
60 } while (attemptsRemaining
--);
65 static void icm20689AccInit(accDev_t
*acc
)
67 acc
->acc_1G
= 512 * 4;
70 bool icm20689AccDetect(accDev_t
*acc
)
72 acc
->busDev
= busDeviceOpen(BUSTYPE_ANY
, DEVHW_ICM20689
, acc
->imuSensorToUse
);
73 if (acc
->busDev
== NULL
) {
77 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(acc
->busDev
);
78 if (ctx
->chipMagicNumber
!= 0x50D1) {
82 acc
->initFn
= icm20689AccInit
;
83 acc
->readFn
= mpuAccReadScratchpad
;
84 acc
->accAlign
= acc
->busDev
->param
;
89 static void icm20689AccAndGyroInit(gyroDev_t
*gyro
)
91 busDevice_t
* busDev
= gyro
->busDev
;
92 const gyroFilterAndRateConfig_t
* config
= mpuChooseGyroConfig(gyro
->lpf
, 1000000 / gyro
->requestedSampleIntervalUs
);
93 gyro
->sampleRateIntervalUs
= 1000000 / config
->gyroRateHz
;
95 busSetSpeed(busDev
, BUS_SPEED_INITIALIZATION
);
97 busWrite(busDev
, MPU_RA_PWR_MGMT_1
, ICM20689_BIT_RESET
);
99 busWrite(busDev
, MPU_RA_SIGNAL_PATH_RESET
, 0x03);
101 busWrite(busDev
, MPU_RA_PWR_MGMT_1
, INV_CLK_PLL
);
103 busWrite(busDev
, MPU_RA_GYRO_CONFIG
, INV_FSR_2000DPS
<< 3); // XXX
105 busWrite(busDev
, MPU_RA_ACCEL_CONFIG
, INV_FSR_16G
<< 3);
107 busWrite(busDev
, MPU_RA_CONFIG
, config
->gyroConfigValues
[0]);
109 busWrite(busDev
, MPU_RA_SMPLRT_DIV
, config
->gyroConfigValues
[1]); // Get Divider Drops
112 // Switch SPI to fast speed
113 busSetSpeed(busDev
, BUS_SPEED_FAST
);
116 bool icm20689GyroDetect(gyroDev_t
*gyro
)
118 gyro
->busDev
= busDeviceInit(BUSTYPE_ANY
, DEVHW_ICM20689
, gyro
->imuSensorToUse
, OWNER_MPU
);
119 if (gyro
->busDev
== NULL
) {
123 if (!icm20689DeviceDetect(gyro
->busDev
)) {
124 busDeviceDeInit(gyro
->busDev
);
128 // Magic number for ACC detection to indicate that we have detected MPU6000 gyro
129 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(gyro
->busDev
);
130 ctx
->chipMagicNumber
= 0x50D1;
132 gyro
->initFn
= icm20689AccAndGyroInit
;
133 gyro
->readFn
= mpuGyroReadScratchpad
;
134 gyro
->intStatusFn
= gyroCheckDataReady
;
135 gyro
->temperatureFn
= mpuTemperatureReadScratchpad
;
136 gyro
->scale
= 1.0f
/ 16.4f
; // 16.4 dps/lsb scalefactor
137 gyro
->gyroAlign
= gyro
->busDev
->param
;