Merge pull request #11297 from SteveCEvans/baro_state
[betaflight.git] / src / main / drivers / accgyro_legacy / accgyro_mma845x.c
blob1b51e7adab90b710da60581d0d23aa558a5c7a66
1 /*
2 * This file is part of Cleanflight and Betaflight.
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)
8 * any later version.
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/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #ifdef USE_ACC_MMA8452
28 #include "drivers/io.h"
29 #include "drivers/bus_i2c.h"
31 #include "drivers/sensor.h"
32 #include "drivers/accgyro/accgyro.h"
33 #include "accgyro_mma845x.h"
35 #ifndef MMA8452_I2C_INSTANCE
36 #define MMA8452_I2C_INSTANCE I2CDEV_1
37 #endif
39 // MMA8452QT, Standard address 0x1C
40 // ACC_INT2 routed to PA5
42 #define MMA8452_ADDRESS 0x1C
44 #define MMA8452_DEVICE_SIGNATURE 0x2A
45 #define MMA8451_DEVICE_SIGNATURE 0x1A
47 #define MMA8452_STATUS 0x00
48 #define MMA8452_OUT_X_MSB 0x01
49 #define MMA8452_WHO_AM_I 0x0D
50 #define MMA8452_XYZ_DATA_CFG 0x0E
51 #define MMA8452_HP_FILTER_CUTOFF 0x0F
52 #define MMA8452_CTRL_REG1 0x2A
53 #define MMA8452_CTRL_REG2 0x2B
54 #define MMA8452_CTRL_REG3 0x2C
55 #define MMA8452_CTRL_REG4 0x2D
56 #define MMA8452_CTRL_REG5 0x2E
58 #define MMA8452_FS_RANGE_8G 0x02
59 #define MMA8452_FS_RANGE_4G 0x01
60 #define MMA8452_FS_RANGE_2G 0x00
62 #define MMA8452_HPF_CUTOFF_LV1 0x00
63 #define MMA8452_HPF_CUTOFF_LV2 0x01
64 #define MMA8452_HPF_CUTOFF_LV3 0x02
65 #define MMA8452_HPF_CUTOFF_LV4 0x03
67 #define MMA8452_CTRL_REG2_B7_ST 0x80
68 #define MMA8452_CTRL_REG2_B6_RST 0x40
69 #define MMA8452_CTRL_REG2_B4_SMODS1 0x10
70 #define MMA8452_CTRL_REG2_B3_SMODS0 0x08
71 #define MMA8452_CTRL_REG2_B2_SLPE 0x04
72 #define MMA8452_CTRL_REG2_B1_MODS1 0x02
73 #define MMA8452_CTRL_REG2_B0_MODS0 0x01
75 #define MMA8452_CTRL_REG2_MODS_LP 0x03
76 #define MMA8452_CTRL_REG2_MODS_HR 0x02
77 #define MMA8452_CTRL_REG2_MODS_LNLP 0x01
78 #define MMA8452_CTRL_REG2_MODS_NOR 0x00
80 #define MMA8452_CTRL_REG3_IPOL 0x02
81 #define MMA8452_CTRL_REG4_INT_EN_DRDY 0x01
83 #define MMA8452_CTRL_REG1_LNOISE 0x04
84 #define MMA8452_CTRL_REG1_ACTIVE 0x01
86 static uint8_t device_id;
88 static inline void mma8451ConfigureInterrupt(void)
90 #ifdef MMA8451_INT_PIN
91 IOInit(IOGetByTag(IO_TAG(MMA8451_INT_PIN)), OWNER_GYRO_EXTI, 0);
92 // TODO - maybe pullup / pulldown ?
93 IOConfigGPIO(IOGetByTag(IO_TAG(MMA8451_INT_PIN)), IOCFG_IN_FLOATING);
94 #endif
96 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG3, MMA8452_CTRL_REG3_IPOL); // Interrupt polarity (active HIGH)
97 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG4, MMA8452_CTRL_REG4_INT_EN_DRDY); // Enable DRDY interrupt (unused by this driver)
98 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG5, 0); // DRDY routed to INT2
101 static void mma8452Init(accDev_t *acc)
104 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG1, 0); // Put device in standby to configure stuff
105 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_XYZ_DATA_CFG, MMA8452_FS_RANGE_8G);
106 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_HP_FILTER_CUTOFF, MMA8452_HPF_CUTOFF_LV4);
107 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG2, MMA8452_CTRL_REG2_MODS_HR | MMA8452_CTRL_REG2_MODS_HR << 3); // High resolution measurement in both sleep and active modes
109 mma8451ConfigureInterrupt();
111 i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG1, MMA8452_CTRL_REG1_LNOISE | MMA8452_CTRL_REG1_ACTIVE); // Turn on measurements, low noise at max scale mode, Data Rate 800Hz. LNoise mode makes range +-4G.
113 acc->acc_1G = 256;
116 static bool mma8452Read(accDev_t *acc)
118 uint8_t buf[6];
120 if (!i2cRead(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_OUT_X_MSB, 6, buf)) {
121 return false;
124 acc->ADCRaw[0] = ((int16_t)((buf[0] << 8) | buf[1]) >> 2) / 4;
125 acc->ADCRaw[1] = ((int16_t)((buf[2] << 8) | buf[3]) >> 2) / 4;
126 acc->ADCRaw[2] = ((int16_t)((buf[4] << 8) | buf[5]) >> 2) / 4;
128 return true;
131 bool mma8452Detect(accDev_t *acc)
133 uint8_t sig = 0;
134 bool ack = i2cRead(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_WHO_AM_I, 1, &sig);
136 if (!ack || (sig != MMA8452_DEVICE_SIGNATURE && sig != MMA8451_DEVICE_SIGNATURE))
137 return false;
139 acc->initFn = mma8452Init;
140 acc->readFn = mma8452Read;
141 device_id = sig;
142 return true;
144 #endif