2 * This file is part of Cleanflight.
4 * Cleanflight 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 * Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
25 #include "build/atomic.h"
26 #include "build/build_config.h"
27 #include "build/debug.h"
29 #include "common/maths.h"
30 #include "common/utils.h"
32 #include "drivers/bus.h"
33 #include "drivers/io.h"
34 #include "drivers/nvic.h"
35 #include "drivers/sensor.h"
36 #include "drivers/system.h"
37 #include "drivers/time.h"
39 #include "drivers/sensor.h"
40 #include "drivers/accgyro/accgyro.h"
41 #include "drivers/accgyro/accgyro_mpu.h"
43 // Check busDevice scratchpad memory size
44 STATIC_ASSERT(sizeof(mpuContextData_t
) < BUS_SCRATCHPAD_MEMORY_SIZE
, busDevice_scratchpad_memory_too_small
);
46 static const gyroFilterAndRateConfig_t mpuGyroConfigs
[] = {
47 { GYRO_LPF_256HZ
, 8000, { MPU_DLPF_256HZ
, 0 } },
48 { GYRO_LPF_256HZ
, 4000, { MPU_DLPF_256HZ
, 1 } },
49 { GYRO_LPF_256HZ
, 2000, { MPU_DLPF_256HZ
, 3 } },
50 { GYRO_LPF_256HZ
, 1000, { MPU_DLPF_256HZ
, 7 } },
51 { GYRO_LPF_256HZ
, 666, { MPU_DLPF_256HZ
, 11 } },
52 { GYRO_LPF_256HZ
, 500, { MPU_DLPF_256HZ
, 15 } },
55 const gyroFilterAndRateConfig_t
* mpuChooseGyroConfig(uint8_t desiredLpf
, uint16_t desiredRateHz
)
57 return chooseGyroConfig(desiredLpf
, desiredRateHz
, &mpuGyroConfigs
[0], ARRAYLEN(mpuGyroConfigs
));
60 bool mpuGyroRead(gyroDev_t
*gyro
)
64 const bool ack
= busReadBuf(gyro
->busDev
, MPU_RA_GYRO_XOUT_H
, data
, 6);
69 gyro
->gyroADCRaw
[X
] = (float) int16_val_big_endian(data
, 0);
70 gyro
->gyroADCRaw
[Y
] = (float) int16_val_big_endian(data
, 1);
71 gyro
->gyroADCRaw
[Z
] = (float) int16_val_big_endian(data
, 2);
76 static bool mpuUpdateSensorContext(busDevice_t
* busDev
, mpuContextData_t
* ctx
)
78 ctx
->lastReadStatus
= busReadBuf(busDev
, MPU_RA_ACCEL_XOUT_H
, ctx
->accRaw
, 6 + 2 + 6);
79 return ctx
->lastReadStatus
;
82 bool mpuGyroReadScratchpad(gyroDev_t
*gyro
)
84 busDevice_t
* busDev
= gyro
->busDev
;
85 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(busDev
);
87 if (mpuUpdateSensorContext(busDev
, ctx
)) {
88 gyro
->gyroADCRaw
[X
] = (float) int16_val_big_endian(ctx
->gyroRaw
, 0);
89 gyro
->gyroADCRaw
[Y
] = (float) int16_val_big_endian(ctx
->gyroRaw
, 1);
90 gyro
->gyroADCRaw
[Z
] = (float) int16_val_big_endian(ctx
->gyroRaw
, 2);
97 bool mpuAccReadScratchpad(accDev_t
*acc
)
99 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(acc
->busDev
);
101 if (ctx
->lastReadStatus
) {
102 acc
->ADCRaw
[X
] = (float) int16_val_big_endian(ctx
->accRaw
, 0);
103 acc
->ADCRaw
[Y
] = (float) int16_val_big_endian(ctx
->accRaw
, 1);
104 acc
->ADCRaw
[Z
] = (float) int16_val_big_endian(ctx
->accRaw
, 2);
111 bool mpuTemperatureReadScratchpad(gyroDev_t
*gyro
, int16_t * data
)
113 mpuContextData_t
* ctx
= busDeviceGetScratchpadMemory(gyro
->busDev
);
115 if (ctx
->lastReadStatus
) {
116 // Convert to degC*10: degC = raw / 340 + 36.53
117 *data
= int16_val_big_endian(ctx
->tempRaw
, 0) / 34 + 365;