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/>.
28 #include "accgyro_adxl345.h"
30 // ADXL345, Alternative address mode 0x53
31 #define ADXL345_ADDRESS 0x53
34 #define ADXL345_BW_RATE 0x2C
35 #define ADXL345_POWER_CTL 0x2D
36 #define ADXL345_INT_ENABLE 0x2E
37 #define ADXL345_DATA_FORMAT 0x31
38 #define ADXL345_DATA_OUT 0x32
39 #define ADXL345_FIFO_CTL 0x38
42 #define ADXL345_RATE_50 0x09
43 #define ADXL345_RATE_100 0x0A
44 #define ADXL345_RATE_200 0x0B
45 #define ADXL345_RATE_400 0x0C
46 #define ADXL345_RATE_800 0x0D
47 #define ADXL345_RATE_1600 0x0E
48 #define ADXL345_RATE_3200 0x0F
50 // various register values
51 #define ADXL345_POWER_MEAS 0x08
52 #define ADXL345_FULL_RANGE 0x08
53 #define ADXL345_RANGE_2G 0x00
54 #define ADXL345_RANGE_4G 0x01
55 #define ADXL345_RANGE_8G 0x02
56 #define ADXL345_RANGE_16G 0x03
57 #define ADXL345_FIFO_STREAM 0x80
59 static void adxl345Init(void);
60 static bool adxl345Read(int16_t *accelData
);
62 static bool useFifo
= false;
64 bool adxl345Detect(drv_adxl345_config_t
*init
, acc_t
*acc
)
69 ack
= i2cRead(ADXL345_ADDRESS
, 0x00, 1, &sig
);
70 if (!ack
|| sig
!= 0xE5)
73 // use ADXL345's fifo to filter data or not
74 useFifo
= init
->useFifo
;
76 acc
->init
= adxl345Init
;
77 acc
->read
= adxl345Read
;
81 static void adxl345Init(void)
84 uint8_t fifoDepth
= 16;
85 i2cWrite(ADXL345_ADDRESS
, ADXL345_POWER_CTL
, ADXL345_POWER_MEAS
);
86 i2cWrite(ADXL345_ADDRESS
, ADXL345_DATA_FORMAT
, ADXL345_FULL_RANGE
| ADXL345_RANGE_8G
);
87 i2cWrite(ADXL345_ADDRESS
, ADXL345_BW_RATE
, ADXL345_RATE_400
);
88 i2cWrite(ADXL345_ADDRESS
, ADXL345_FIFO_CTL
, (fifoDepth
& 0x1F) | ADXL345_FIFO_STREAM
);
90 i2cWrite(ADXL345_ADDRESS
, ADXL345_POWER_CTL
, ADXL345_POWER_MEAS
);
91 i2cWrite(ADXL345_ADDRESS
, ADXL345_DATA_FORMAT
, ADXL345_FULL_RANGE
| ADXL345_RANGE_8G
);
92 i2cWrite(ADXL345_ADDRESS
, ADXL345_BW_RATE
, ADXL345_RATE_100
);
94 acc_1G
= 265; // 3.3V operation // FIXME verify this is supposed to be 265, not 256. Typo?
97 uint8_t acc_samples
= 0;
99 static bool adxl345Read(int16_t *accelData
)
108 uint8_t samples_remaining
;
113 if (!i2cRead(ADXL345_ADDRESS
, ADXL345_DATA_OUT
, 8, buf
)) {
117 x
+= (int16_t)(buf
[0] + (buf
[1] << 8));
118 y
+= (int16_t)(buf
[2] + (buf
[3] << 8));
119 z
+= (int16_t)(buf
[4] + (buf
[5] << 8));
120 samples_remaining
= buf
[7] & 0x7F;
121 } while ((i
< 32) && (samples_remaining
> 0));
122 accelData
[0] = x
/ i
;
123 accelData
[1] = y
/ i
;
124 accelData
[2] = z
/ i
;
128 if (!i2cRead(ADXL345_ADDRESS
, ADXL345_DATA_OUT
, 6, buf
)) {
132 accelData
[0] = buf
[0] + (buf
[1] << 8);
133 accelData
[1] = buf
[2] + (buf
[3] << 8);
134 accelData
[2] = buf
[4] + (buf
[5] << 8);