Create set-home.md
[u360gts.git] / src / main / drivers / accgyro_mma845x.c
blobbf39f41b046594455547bfab9a0e1081e22c5213
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #include "system.h"
24 #include "gpio.h"
25 #include "bus_i2c.h"
27 #include "sensor.h"
28 #include "accgyro.h"
29 #include "accgyro_mma845x.h"
31 // MMA8452QT, Standard address 0x1C
32 // ACC_INT2 routed to PA5
34 #define MMA8452_ADDRESS 0x1C
36 #define MMA8452_DEVICE_SIGNATURE 0x2A
37 #define MMA8451_DEVICE_SIGNATURE 0x1A
39 #define MMA8452_STATUS 0x00
40 #define MMA8452_OUT_X_MSB 0x01
41 #define MMA8452_WHO_AM_I 0x0D
42 #define MMA8452_XYZ_DATA_CFG 0x0E
43 #define MMA8452_HP_FILTER_CUTOFF 0x0F
44 #define MMA8452_CTRL_REG1 0x2A
45 #define MMA8452_CTRL_REG2 0x2B
46 #define MMA8452_CTRL_REG3 0x2C
47 #define MMA8452_CTRL_REG4 0x2D
48 #define MMA8452_CTRL_REG5 0x2E
50 #define MMA8452_FS_RANGE_8G 0x02
51 #define MMA8452_FS_RANGE_4G 0x01
52 #define MMA8452_FS_RANGE_2G 0x00
54 #define MMA8452_HPF_CUTOFF_LV1 0x00
55 #define MMA8452_HPF_CUTOFF_LV2 0x01
56 #define MMA8452_HPF_CUTOFF_LV3 0x02
57 #define MMA8452_HPF_CUTOFF_LV4 0x03
59 #define MMA8452_CTRL_REG2_B7_ST 0x80
60 #define MMA8452_CTRL_REG2_B6_RST 0x40
61 #define MMA8452_CTRL_REG2_B4_SMODS1 0x10
62 #define MMA8452_CTRL_REG2_B3_SMODS0 0x08
63 #define MMA8452_CTRL_REG2_B2_SLPE 0x04
64 #define MMA8452_CTRL_REG2_B1_MODS1 0x02
65 #define MMA8452_CTRL_REG2_B0_MODS0 0x01
67 #define MMA8452_CTRL_REG2_MODS_LP 0x03
68 #define MMA8452_CTRL_REG2_MODS_HR 0x02
69 #define MMA8452_CTRL_REG2_MODS_LNLP 0x01
70 #define MMA8452_CTRL_REG2_MODS_NOR 0x00
72 #define MMA8452_CTRL_REG3_IPOL 0x02
73 #define MMA8452_CTRL_REG4_INT_EN_DRDY 0x01
75 #define MMA8452_CTRL_REG1_LNOISE 0x04
76 #define MMA8452_CTRL_REG1_ACTIVE 0x01
78 static uint8_t device_id;
80 static void mma8452Init(void);
81 static bool mma8452Read(int16_t *accelData);
83 bool mma8452Detect(acc_t *acc)
85 bool ack = false;
86 uint8_t sig = 0;
88 ack = i2cRead(MMA8452_ADDRESS, MMA8452_WHO_AM_I, 1, &sig);
89 if (!ack || (sig != MMA8452_DEVICE_SIGNATURE && sig != MMA8451_DEVICE_SIGNATURE))
90 return false;
92 acc->init = mma8452Init;
93 acc->read = mma8452Read;
94 device_id = sig;
95 return true;
98 static inline void mma8451ConfigureInterrupt(void)
100 #ifdef NAZE
101 // PA5 - ACC_INT2 output on NAZE rev3/4 hardware
102 // NAZE rev.5 hardware has PA5 (ADC1_IN5) on breakout pad on bottom of board
103 // OLIMEXINO - The PA5 pin is wired up to LED1, if you need to use an mma8452 on an Olimexino use a different pin and provide support in code.
105 gpio_config_t gpio;
107 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
109 gpio.pin = Pin_5;
110 gpio.speed = Speed_2MHz;
111 gpio.mode = Mode_IN_FLOATING;
112 gpioInit(GPIOA, &gpio);
113 #endif
115 i2cWrite(MMA8452_ADDRESS, MMA8452_CTRL_REG3, MMA8452_CTRL_REG3_IPOL); // Interrupt polarity (active HIGH)
116 i2cWrite(MMA8452_ADDRESS, MMA8452_CTRL_REG4, MMA8452_CTRL_REG4_INT_EN_DRDY); // Enable DRDY interrupt (unused by this driver)
117 i2cWrite(MMA8452_ADDRESS, MMA8452_CTRL_REG5, 0); // DRDY routed to INT2
120 static void mma8452Init(void)
123 i2cWrite(MMA8452_ADDRESS, MMA8452_CTRL_REG1, 0); // Put device in standby to configure stuff
124 i2cWrite(MMA8452_ADDRESS, MMA8452_XYZ_DATA_CFG, MMA8452_FS_RANGE_8G);
125 i2cWrite(MMA8452_ADDRESS, MMA8452_HP_FILTER_CUTOFF, MMA8452_HPF_CUTOFF_LV4);
126 i2cWrite(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
128 mma8451ConfigureInterrupt();
130 i2cWrite(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.
132 acc_1G = 256;
135 static bool mma8452Read(int16_t *accelData)
137 uint8_t buf[6];
139 if (!i2cRead(MMA8452_ADDRESS, MMA8452_OUT_X_MSB, 6, buf)) {
140 return false;
143 accelData[0] = ((int16_t)((buf[0] << 8) | buf[1]) >> 2) / 4;
144 accelData[1] = ((int16_t)((buf[2] << 8) | buf[3]) >> 2) / 4;
145 accelData[2] = ((int16_t)((buf[4] << 8) | buf[5]) >> 2) / 4;
147 return true;