2 * This file is part of Betaflight.
4 * Betaflight is free software. You can redistribute this software
5 * and/or modify this software under the terms of the GNU General
6 * Public License as published by the Free Software Foundation,
7 * either version 3 of the License, or (at your option) any later
10 * Betaflight is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this software.
19 * If not, see <http://www.gnu.org/licenses/>.
27 #if defined(USE_ACCGYRO_LSM6DSV16X)
29 #include "accgyro_spi_lsm6dsv16x.h"
31 #include "sensors/gyro.h"
35 * https://www.st.com/content/ccc/resource/technical/document/datasheet/group3/47/03/b2/44/47/32/4b/76/DM00741844/files/DM00741844.pdf/jcr:content/translations/en.DM00741844.pdf
39 // 10 MHz max SPI frequency
40 #define LSM6DSV16X_MAX_SPI_CLK_HZ 10000000
42 // Need to see at least this many interrupts during initialisation to confirm EXTI connectivity
43 #define GYRO_EXTI_DETECT_THRESHOLD 1000
45 // Macros to encode/decode multi-bit values
46 #define LSM6DSV_ENCODE_BITS(val, mask, shift) ((val << shift) & mask)
47 #define LSM6DSV_DECODE_BITS(val, mask, shift) ((val & mask) >> shift)
49 // Enable embedded functions register (R/W)
50 #define LSM6DSV_FUNC_CFG_ACCESS 0x01
51 #define LSM6DSV_EMB_FUNC_REG_ACCESS_EMB_FUNC_REG_ACCESS 0x80
52 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SHUB_REG_ACCESS 0x40
53 #define LSM6DSV_EMB_FUNC_REG_ACCESS_FSM_WR_CTRL_EN 0x08
54 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SW_POR 0x04
55 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SPI2_RESET 0x02
56 #define LSM6DSV_EMB_FUNC_REG_ACCESS_OIS_CTRL_FROM_UI 0x01
58 // SDO, OCS_Aux, SDO_Aux pins pull-up register (R/W)
59 #define LSM6DSV_PIN_CTRL 0x02
60 #define LSM6DSV_PIN_CTRL_OIRS_PU_DIS 0x80
61 #define LSM6DSV_PIN_CTRL_DSO_PU_EN 0x40
62 #define LSM6DSV_PIN_CTRL_IBHR_POR_EN 0x20
63 #define LSM6DSV_PIN_CTRL_RESDV 0x03
65 // Interface configuration register (R/W)
66 #define LSM6DSV_IF_CFG 0x03
67 #define LSM6DSV_IF_CFG_SDA_PU_EN 0x80
68 #define LSM6DSV_IF_CFG_SHUB_PU_EN 0x40
69 #define LSM6DSV_IF_CFG_ASF_CTRL 0x20
70 #define LSM6DSV_IF_CFG_H_LACTIVE 0x10
71 #define LSM6DSV_IF_CFG_PP_OD 0x08
72 #define LSM6DSV_IF_CFG_SIM 0x04
73 #define LSM6DSV_IF_CFG_I2C_I3C_DISABLE 0x01
75 // ODR-triggered mode configuration register (R/W)
76 #define LSM6DSV_ODR_TRIG_CFG 0x06
78 // FIFO control register 1 (R/W)
79 #define LSM6DSV_FIFO_CTRL1 0x07
81 // FIFO control register 2 (R/W)
82 #define LSM6DSV_FIFO_CTRL2 0x08
83 #define LSM6DSV_FIFO_CTRL2_STOP_ON_WTM 0x80
84 #define LSM6DSV_FIFO_CTRL2_FIFO_COMPR_RT_EN 0x40
85 #define LSM6DSV_FIFO_CTRL2_ODR_CHG_EN 0x10
86 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_MASK 0x06
87 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_SHIFT 1
88 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_NOT_FORCED 0
89 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_8 1
90 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_16 2
91 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_32 3
92 #define LSM6DSV_FIFO_CTRL2_XL_DUALC_BATCH_FROM_FS 0x01
94 // FIFO control register 3 (R/W)
95 #define LSM6DSV_FIFO_CTRL3 0x09
96 #define LSM6DSV_FIFO_CTRL3_BDR_GY_MASK 0xf0
97 #define LSM6DSV_FIFO_CTRL3_BDR_GY_SHIFT 4
98 #define LSM6DSV_FIFO_CTRL3_BDR_GY_1875HZ 0x01
99 #define LSM6DSV_FIFO_CTRL3_BDR_GY_7_5HZ 0x02
100 #define LSM6DSV_FIFO_CTRL3_BDR_GY_15HZ 0x03
101 #define LSM6DSV_FIFO_CTRL3_BDR_GY_30HZ 0x04
102 #define LSM6DSV_FIFO_CTRL3_BDR_GY_60HZ 0x05
103 #define LSM6DSV_FIFO_CTRL3_BDR_GY_120HZ 0x06
104 #define LSM6DSV_FIFO_CTRL3_BDR_GY_240HZ 0x07
105 #define LSM6DSV_FIFO_CTRL3_BDR_GY_480HZ 0x08
106 #define LSM6DSV_FIFO_CTRL3_BDR_GY_960HZ 0x09
107 #define LSM6DSV_FIFO_CTRL3_BDR_GY_1920HZ 0x0a
108 #define LSM6DSV_FIFO_CTRL3_BDR_GY_3840HZ 0x0b
109 #define LSM6DSV_FIFO_CTRL3_BDR_GY_7680HZ 0x0c
110 #define LSM6DSV_FIFO_CTRL3_BDR_XL_MASK 0xff
111 #define LSM6DSV_FIFO_CTRL3_BDR_XL_SHIFT 0
112 #define LSM6DSV_FIFO_CTRL3_BDR_XL_1875HZ 0x01
113 #define LSM6DSV_FIFO_CTRL3_BDR_XL_7_5HZ 0x02
114 #define LSM6DSV_FIFO_CTRL3_BDR_XL_15HZ 0x03
115 #define LSM6DSV_FIFO_CTRL3_BDR_XL_30HZ 0x04
116 #define LSM6DSV_FIFO_CTRL3_BDR_XL_60HZ 0x05
117 #define LSM6DSV_FIFO_CTRL3_BDR_XL_120HZ 0x06
118 #define LSM6DSV_FIFO_CTRL3_BDR_XL_240HZ 0x07
119 #define LSM6DSV_FIFO_CTRL3_BDR_XL_480HZ 0x08
120 #define LSM6DSV_FIFO_CTRL3_BDR_XL_960HZ 0x09
121 #define LSM6DSV_FIFO_CTRL3_BDR_XL_1920HZ 0x0a
122 #define LSM6DSV_FIFO_CTRL3_BDR_XL_3840HZ 0x0b
123 #define LSM6DSV_FIFO_CTRL3_BDR_XL_7680HZ 0x0c
125 // FIFO control register 4 (R/W)
126 #define LSM6DSV_FIFO_CTRL4 0x0A
127 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_MASK 0xc0
128 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_SHIFT 6
129 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_NONE 0
130 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_1 1
131 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_8 2
132 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_32 3
133 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_MASK 0x30
134 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_SHIFT 4
135 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_NONE 0
136 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_1875HZ 1
137 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_15HZ 2
138 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_60HZ 3
139 #define LSM6DSV_FIFO_CTRL4_G_EIS_FIFO_EN 0x08
140 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_MASK 0x07
141 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_SHIFT 0
142 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS 0
143 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_FIFO_MODE 1
144 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT_WTM 2
145 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT_FIFO 3
146 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS_CONT 4
147 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT 6
148 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS_FIFO 7
150 // Counter batch data rate register 1 (R/W)
151 #define LSM6DSV_COUNTER_BDR_REG1 0x0B
152 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_MASK 0x60
153 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_SHIFT 5
154 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_ACC 0
155 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_GYRO 1
156 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_GYRO_EIS 2
157 #define LSM6DSV_COUNTER_BDR_REG2_CNT_BDR_TH_HI_MASK 0x03
158 #define LSM6DSV_COUNTER_BDR_REG2_CNT_BDR_TH_HI_SHIFT 0
160 // Counter batch data rate register 2 (R/W)
161 #define LSM6DSV_COUNTER_BDR_REG2 0x0C
163 // INT1 pin control register (R/W)
164 #define LSM6DSV_INT1_CTRL 0x0D
165 #define LSM6DSV_INT1_CTRL_INT1_CNT_BDR 0x40
166 #define LSM6DSV_INT1_CTRL_INT1_FIFO_FULL 0x20
167 #define LSM6DSV_INT1_CTRL_INT1_FIFO_OVR 0x10
168 #define LSM6DSV_INT1_CTRL_INT1_FIFO_TH 0x08
169 #define LSM6DSV_INT1_CTRL_INT1_DRDY_G 0x02
170 #define LSM6DSV_INT1_CTRL_INT1_DRDY_XL 0x01
172 // INT2 pin control register (R/W)
173 #define LSM6DSV_INT2_CTRL 0x0E
174 #define LSM6DSV_INT2_CTRL_INT2_EMB_FUNC_ENDOP 0x80
175 #define LSM6DSV_INT2_CTRL_INT2_CNT_BDR 0x40
176 #define LSM6DSV_INT2_CTRL_INT2_FIFO_FULL 0x20
177 #define LSM6DSV_INT2_CTRL_INT2_FIFO_OVR 0x10
178 #define LSM6DSV_INT2_CTRL_INT2_FIFO_TH 0x08
179 #define LSM6DSV_INT2_CTRL_INT2_DRDY_G_EIS 0x04
180 #define LSM6DSV_INT2_CTRL_INT2_DRDY_G 0x02
181 #define LSM6DSV_INT2_CTRL_INT2_DRDY_XL 0x01
183 // WHO_AM_I register (R)
184 #define LSM6DSV_WHO_AM_I 0x0F
186 // Accelerometer control register 1 (R/W)
187 #define LSM6DSV_CTRL1 0x10
188 #define LSM6DSV_CTRL1_OP_MODE_XL_MASK 0x70
189 #define LSM6DSV_CTRL1_OP_MODE_XL_SHIFT 4
190 #define LSM6DSV_CTRL1_OP_MODE_XL_HIGH_PERF 0
191 #define LSM6DSV_CTRL1_OP_MODE_XL_HIGH_ACCURACY 1
192 #define LSM6DSV_CTRL1_OP_MODE_XL_ODR_TRIG 3
193 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE1 4
194 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE2 5
195 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE3 6
196 #define LSM6DSV_CTRL1_OP_MODE_XL_NORMAL 7
197 #define LSM6DSV_CTRL1_ODR_XL_MASK 0x0f
198 #define LSM6DSV_CTRL1_ODR_XL_SHIFT 0
199 #define LSM6DSV_CTRL1_ODR_XL_POWERDOWN 0
200 #define LSM6DSV_CTRL1_ODR_XL_1875HZ 1
201 #define LSM6DSV_CTRL1_ODR_XL_7_5HZ 2
203 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 00
204 // or in high-performance mode mode
205 #define LSM6DSV_CTRL1_ODR_XL_15HZ 3
206 #define LSM6DSV_CTRL1_ODR_XL_30HZ 4
207 #define LSM6DSV_CTRL1_ODR_XL_60HZ 5
208 #define LSM6DSV_CTRL1_ODR_XL_120HZ 6
209 #define LSM6DSV_CTRL1_ODR_XL_240HZ 7
210 #define LSM6DSV_CTRL1_ODR_XL_480HZ 8
211 #define LSM6DSV_CTRL1_ODR_XL_960HZ 9
212 #define LSM6DSV_CTRL1_ODR_XL_1920HZ 10
213 #define LSM6DSV_CTRL1_ODR_XL_3840HZ 11
214 #define LSM6DSV_CTRL1_ODR_XL_7680HZ 12
216 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 01
217 #define LSM6DSV_CTRL1_ODR_XL_15_625HZ 3
218 #define LSM6DSV_CTRL1_ODR_XL_31_25HZ 4
219 #define LSM6DSV_CTRL1_ODR_XL_62_5HZ 5
220 #define LSM6DSV_CTRL1_ODR_XL_125HZ 6
221 #define LSM6DSV_CTRL1_ODR_XL_250HZ 7
222 #define LSM6DSV_CTRL1_ODR_XL_500HZ 8
223 #define LSM6DSV_CTRL1_ODR_XL_1000HZ 9
224 #define LSM6DSV_CTRL1_ODR_XL_2000HZ 10
225 #define LSM6DSV_CTRL1_ODR_XL_4000HZ 11
226 #define LSM6DSV_CTRL1_ODR_XL_8000HZ 12
228 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 10
229 #define LSM6DSV_CTRL1_ODR_XL_12_5HZ 3
230 #define LSM6DSV_CTRL1_ODR_XL_25HZ 4
231 #define LSM6DSV_CTRL1_ODR_XL_50HZ 5
232 #define LSM6DSV_CTRL1_ODR_XL_100HZ 6
233 #define LSM6DSV_CTRL1_ODR_XL_200HZ 7
234 #define LSM6DSV_CTRL1_ODR_XL_400HZ 8
235 #define LSM6DSV_CTRL1_ODR_XL_800HZ 9
236 #define LSM6DSV_CTRL1_ODR_XL_1600HZ 10
237 #define LSM6DSV_CTRL1_ODR_XL_3200HZ 11
238 #define LSM6DSV_CTRL1_ODR_XL_6400HZ 12
240 // Gyroscope control register 2 (R/W)
241 #define LSM6DSV_CTRL2 0x11
242 #define LSM6DSV_CTRL2_OP_MODE_G_MASK 0x70
243 #define LSM6DSV_CTRL2_OP_MODE_G_SHIFT 4
244 #define LSM6DSV_CTRL2_OP_MODE_G_HIGH_PERF 0
245 #define LSM6DSV_CTRL2_OP_MODE_G_HIGH_ACCURACY 1
246 #define LSM6DSV_CTRL2_OP_MODE_G_ODR_TRIG 3
247 #define LSM6DSV_CTRL2_OP_MODE_G_SLEEP 4
248 #define LSM6DSV_CTRL2_OP_MODE_G_LOW_PWR_MODE 5
249 #define LSM6DSV_CTRL2_ODR_G_MASK 0x0f
250 #define LSM6DSV_CTRL2_ODR_G_SHIFT 0
251 #define LSM6DSV_CTRL2_ODR_G_POWERDOWN 0
252 #define LSM6DSV_CTRL2_ODR_G_1875HZ 1
253 #define LSM6DSV_CTRL2_ODR_G_7_5HZ 2
255 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 00
256 // or in high-performance mode mode
257 #define LSM6DSV_CTRL2_ODR_G_15HZ 3
258 #define LSM6DSV_CTRL2_ODR_G_30HZ 4
259 #define LSM6DSV_CTRL2_ODR_G_60HZ 5
260 #define LSM6DSV_CTRL2_ODR_G_120HZ 6
261 #define LSM6DSV_CTRL2_ODR_G_240HZ 7
262 #define LSM6DSV_CTRL2_ODR_G_480HZ 8
263 #define LSM6DSV_CTRL2_ODR_G_960HZ 9
264 #define LSM6DSV_CTRL2_ODR_G_1920HZ 10
265 #define LSM6DSV_CTRL2_ODR_G_3840HZ 11
266 #define LSM6DSV_CTRL2_ODR_G_7680HZ 12
268 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 01
269 #define LSM6DSV_CTRL2_ODR_G_15_625HZ 3
270 #define LSM6DSV_CTRL2_ODR_G_31_25HZ 4
271 #define LSM6DSV_CTRL2_ODR_G_62_5HZ 5
272 #define LSM6DSV_CTRL2_ODR_G_125HZ 6
273 #define LSM6DSV_CTRL2_ODR_G_250HZ 7
274 #define LSM6DSV_CTRL2_ODR_G_500HZ 8
275 #define LSM6DSV_CTRL2_ODR_G_1000HZ 9
276 #define LSM6DSV_CTRL2_ODR_G_2000HZ 10
277 #define LSM6DSV_CTRL2_ODR_G_4000HZ 11
278 #define LSM6DSV_CTRL2_ODR_G_8000HZ 12
280 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 10
281 #define LSM6DSV_CTRL2_ODR_G_12_5HZ 3
282 #define LSM6DSV_CTRL2_ODR_G_25HZ 4
283 #define LSM6DSV_CTRL2_ODR_G_50HZ 5
284 #define LSM6DSV_CTRL2_ODR_G_100HZ 6
285 #define LSM6DSV_CTRL2_ODR_G_200HZ 7
286 #define LSM6DSV_CTRL2_ODR_G_400HZ 8
287 #define LSM6DSV_CTRL2_ODR_G_800HZ 9
288 #define LSM6DSV_CTRL2_ODR_G_1600HZ 10
289 #define LSM6DSV_CTRL2_ODR_G_3200HZ 11
290 #define LSM6DSV_CTRL2_ODR_G_6400HZ 12
292 // Control register 3 (R/W)
293 #define LSM6DSV_CTRL3 0x12
294 #define LSM6DSV_CTRL3_BOOT 0x80
295 #define LSM6DSV_CTRL3_BDU 0x40
296 #define LSM6DSV_CTRL3_IF_INC 0x04
297 #define LSM6DSV_CTRL3_SW_RESET 0x01
299 // Control register 4 (R/W)
300 #define LSM6DSV_CTRL4 0x13
301 #define LSM6DSV_CTRL4_INT2_ON_INT1 0x10
302 #define LSM6DSV_CTRL4_DRDY_MASK 0x08
303 #define LSM6DSV_CTRL4_INT2_DRDY_TEMP 0x04
304 #define LSM6DSV_CTRL4_DRDY_PULSED 0x02
305 #define LSM6DSV_CTRL4_INT2_IN_LH 0x01
307 // Control register 5 (R/W)
308 #define LSM6DSV_CTRL5 0x14
309 #define LSM6DSV_CTRL5_BUS_ACT_SEL_MASK 0x06
310 #define LSM6DSV_CTRL5_BUS_ACT_SEL_SHIFT 1
311 #define LSM6DSV_CTRL5_BUS_ACT_SEL_2US 0
312 #define LSM6DSV_CTRL5_BUS_ACT_SEL_50US 1
313 #define LSM6DSV_CTRL5_BUS_ACT_SEL_1US 2
314 #define LSM6DSV_CTRL5_BUS_ACT_SEL_25US 3
315 #define LSM6DSV_CTRL5_INT_EN_I3C 0x01
317 // Control register 6 (R/W)
318 #define LSM6DSV_CTRL6 0x15
319 #define LSM6DSV_CTRL6_LPF1_G_BW_MASK 0x70 // See table 64
320 #define LSM6DSV_CTRL6_LPF1_G_BW_SHIFT 4
322 // Gyro LPF1 + LPF2 bandwidth selection when ODR=7.68kHz
323 // Note that these figures were advised by STmicro tech support and differ from the datasheet
324 #define LSM6DSV_CTRL6_FS_G_BW_288HZ 0
325 #define LSM6DSV_CTRL6_FS_G_BW_215HZ 1
326 #define LSM6DSV_CTRL6_FS_G_BW_157HZ 2
327 #define LSM6DSV_CTRL6_FS_G_BW_455HZ 3
328 #define LSM6DSV_CTRL6_FS_G_BW_102HZ 4
329 #define LSM6DSV_CTRL6_FS_G_BW_58HZ 5
330 #define LSM6DSV_CTRL6_FS_G_BW_28_8HZ 6
331 #define LSM6DSV_CTRL6_FS_G_BW_14_4HZ 7
333 #define LSM6DSV_CTRL6_FS_G_MASK 0x0f
334 #define LSM6DSV_CTRL6_FS_G_SHIFT 0
335 #define LSM6DSV_CTRL6_FS_G_125DPS 0x00
336 #define LSM6DSV_CTRL6_FS_G_250DPS 0x01
337 #define LSM6DSV_CTRL6_FS_G_500DPS 0x02
338 #define LSM6DSV_CTRL6_FS_G_1000DPS 0x03
339 #define LSM6DSV_CTRL6_FS_G_2000DPS 0x04
340 #define LSM6DSV_CTRL6_FS_G_4000DPS 0xc0
342 // Control register 7 (R/W)
343 #define LSM6DSV_CTRL7 0x16
344 #define LSM6DSV_CTRL7_AH_QVAR_EN 0x80
345 #define LSM6DSV_CTRL7_INT2_DRDY_AH_QVAR 0x40
346 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_MASK 0x30
347 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_SHIFT 4
348 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_2_4G 0
349 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_730M 1
350 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_300M 2
351 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_235M 3
352 #define LSM6DSV_CTRL7_LPF1_G_EN 0x01
354 // Control register 8 (R/W)
355 #define LSM6DSV_CTRL8 0x17
356 #define LSM6DSV_CTRL8_HP_LPF2_XL_BW_2_MASK 0xe0 // See table 69
357 #define LSM6DSV_CTRL8_HP_LPF2_XL_BW_2_SHIFT 5
358 #define LSM6DSV_CTRL8_XL_DUALC_EN 0x08
359 #define LSM6DSV_CTRL8_FS_XL_MASK 0x03
360 #define LSM6DSV_CTRL8_FS_XL_SHIFT 0
361 #define LSM6DSV_CTRL8_FS_XL_2G 0
362 #define LSM6DSV_CTRL8_FS_XL_4G 1
363 #define LSM6DSV_CTRL8_FS_XL_8G 2
364 #define LSM6DSV_CTRL8_FS_XL_16G 3
366 // Control register 9 (R/W)
367 #define LSM6DSV_CTRL9 0x18
368 #define LSM6DSV_CTRL9_HP_REF_MODE_XL 0x40
369 #define LSM6DSV_CTRL9_XL_FASTSETTL_MODE 0x20
370 #define LSM6DSV_CTRL9_HP_SLOPE_XL_EN 0x10
371 #define LSM6DSV_CTRL9_LPF2_XL_EN 0x08
372 #define LSM6DSV_CTRL9_USR_OFF_W 0x02
373 #define LSM6DSV_CTRL9_USR_OFF_ON_OUT 0x01
375 // Control register 10 (R/W)
376 #define LSM6DSV_CTRL10 0x19
377 #define LSM6DSV_CTRL10_EMB_FUNC_DEBUG 0x40
378 #define LSM6DSV_CTRL10_ST_G_MASK 0x0c
379 #define LSM6DSV_CTRL10_ST_G_SHIFT 2
380 #define LSM6DSV_CTRL10_ST_G_NORMAL 0
381 #define LSM6DSV_CTRL10_ST_G_POS_SELFTEST 1
382 #define LSM6DSV_CTRL10_ST_G_NEG_SELFTEST 2
383 #define LSM6DSV_CTRL10_ST_XL_MASK 0x03
384 #define LSM6DSV_CTRL10_ST_XL_SHIFT 0
385 #define LSM6DSV_CTRL10_ST_XL_NORMAL 0
386 #define LSM6DSV_CTRL10_ST_XL_POS_SELFTEST 1
387 #define LSM6DSV_CTRL10_ST_XL_NEG_SELFTEST 2
389 // Control Status (R)
390 #define LSM6DSV_CTRL_STATUS 0x1A
391 #define LSM6DSV_CTRL_STATUS_FSM_WR_CTRL_STATUS 0x04
393 // FIFO status register 1 (R)
394 #define LSM6DSV_FIFO_STATUS1 0x1B
396 // FIFO status register 2 (R)
397 #define LSM6DSV_FIFO_STATUS2 0x1C
398 #define LSM6DSV_FIFO_STATUS2_FIFO_WTM_IA 0x80
399 #define LSM6DSV_FIFO_STATUS2_FIFO_OVR_IA 0x40
400 #define LSM6DSV_FIFO_STATUS2_FIFO_FULL_IA 0x20
401 #define LSM6DSV_FIFO_STATUS2_COUNTER_BDR_IA 0x10
402 #define LSM6DSV_FIFO_STATUS2_FIFO_OVR_LATCHED 0x08
403 #define LSM6DSV_FIFO_STATUS2_DIFF_FIFO_8 0x01
405 // Source register for all interrupts (R)
406 #define LSM6DSV_ALL_INT_SRC 0x1D
407 #define LSM6DSV_ALL_INT_SRC_EMB_FUNC_IA 0x80
408 #define LSM6DSV_ALL_INT_SRC_SHUB_IA 0x40
409 #define LSM6DSV_ALL_INT_SRC_SLEEP_CHANGE_IA 0x20
410 #define LSM6DSV_ALL_INT_SRC_D6D_IA 0x10
411 #define LSM6DSV_ALL_INT_SRC_TAP_IA 0x04
412 #define LSM6DSV_ALL_INT_SRC_WU_IA 0x02
413 #define LSM6DSV_ALL_INT_SRC_FF_IA 0x01
415 // The STATUS_REG register is read by the primary interface SPI/I²C & MIPI I3C® (R)
416 #define LSM6DSV_STATUS_REG 0x1E
417 #define LSM6DSV_STATUS_REG_TIMESTAMP_ENDCOUNT 0x80
418 #define LSM6DSV_STATUS_REG_OIS_DRDY 0x20
419 #define LSM6DSV_STATUS_REG_GDA_EIS 0x10
420 #define LSM6DSV_STATUS_REG_AH_QVARDA 0x80
421 #define LSM6DSV_STATUS_REG_TDA 0x40
422 #define LSM6DSV_STATUS_REG_GDA 0x20
423 #define LSM6DSV_STATUS_REG_XLDA 0x10
427 // Temperature data output register (R)
428 #define LSM6DSV_OUT_TEMP_L 0x20
429 #define LSM6DSV_OUT_TEMP_H 0x21
431 // Angular rate sensor pitch axis (X) angular rate output register (R)
432 #define LSM6DSV_OUTX_L_G 0x22
433 #define LSM6DSV_OUTX_H_G 0x23
435 // Angular rate sensor roll axis (Y) angular rate output register (R)
436 #define LSM6DSV_OUTY_L_G 0x24
437 #define LSM6DSV_OUTY_H_G 0x25
439 // Angular rate sensor yaw axis (Z) angular rate output register (R)
440 #define LSM6DSV_OUTZ_L_G 0x26
441 #define LSM6DSV_OUTZ_H_G 0x27
443 // Linear acceleration sensor X-axis output register (R)
444 #define LSM6DSV_OUTX_L_A 0x28
445 #define LSM6DSV_OUTX_H_A 0x29
447 // Linear acceleration sensor Y-axis output register (R)
448 #define LSM6DSV_OUTY_L_A 0x2A
449 #define LSM6DSV_OUTY_H_A 0x2B
451 // Linear acceleration sensor Z-axis output register (R)
452 #define LSM6DSV_OUTZ_L_A 0x2C
453 #define LSM6DSV_OUTZ_H_A 0x2D
455 // Angular rate sensor pitch axis (X) angular rate output register (R)
456 #define LSM6DSV_UI_OUTX_L_G_OIS_EIS 0x2E
457 #define LSM6DSV_UI_OUTX_H_G_OIS_EIS 0x2F
459 // Angular rate sensor roll axis (Y) angular rate output register (R)
460 #define LSM6DSV_UI_OUTY_L_G_OIS_EIS 0x30
461 #define LSM6DSV_UI_OUTY_H_G_OIS_EIS 0x31
463 // Angular rate sensor yaw axis (Z) angular rate output register (R)
464 #define LSM6DSV_UI_OUTZ_L_G_OIS_EIS 0x32
465 #define LSM6DSV_UI_OUTZ_H_G_OIS_EIS 0x33
467 // Linear acceleration sensor X-axis output register (R)
468 #define UI_OUTX_L_A_OIS_DualC 0x34
469 #define UI_OUTX_H_A_OIS_DualC 0x35
471 // Linear acceleration sensor Y-axis output register (R)
472 #define UI_OUTY_L_A_OIS_DualC 0x36
473 #define UI_OUTY_H_A_OIS_DualC 0x37
475 // Linear acceleration sensor Z-axis output register (R)
476 #define UI_OUTZ_L_A_OIS_DualC 0x38
477 #define UI_OUTZ_H_A_OIS_DualC 0x39
479 // Analog hub and Qvar data output register (R)
480 #define LSM6DSV_AH_QVAR_OUT_L 0x3A
481 #define LSM6DSV_AH_QVAR_OUT_H 0x3B
485 // Timestamp first data output register (R)
486 #define LSM6DSV_TIMESTAMP0 0x40
487 #define LSM6DSV_TIMESTAMP1 0x41
488 #define LSM6DSV_TIMESTAMP2 0x42
489 #define LSM6DSV_TIMESTAMP3 0x43
492 #define LSM6DSV_UI_STATUS_REG_OIS 0x44
493 #define LSM6DSV_UI_STATUS_REG_OIS_GYRO_SETTLING 0x04
494 #define LSM6DSV_UI_STATUS_REG_OIS_GDA_OIS 0x02
495 #define LSM6DSV_UI_STATUS_REG_OIS_XLDA_OIS 0x01
497 // Wake-up interrupt source register (R)
498 #define LSM6DSV_WAKE_UP_SRC 0x45
499 #define LSM6DSV_WAKE_UP_SRC_SLEEP_CHANGE_IA 0x40
500 #define LSM6DSV_WAKE_UP_SRC_FF_IA 0x20
501 #define LSM6DSV_WAKE_UP_SRC_SLEEP_STATE 0x10
502 #define LSM6DSV_WAKE_UP_SRC_WU_IA 0x08
503 #define LSM6DSV_WAKE_UP_SRC_X_WU 0x04
504 #define LSM6DSV_WAKE_UP_SRC_Y_WU 0x02
505 #define LSM6DSV_WAKE_UP_SRC_Z_WU 0x01
507 //Tap source register (R)
508 #define LSM6DSV_TAP_SRC 0x46
509 #define LSM6DSV_TAP_SRC_TAP_IA 0x40
510 #define LSM6DSV_TAP_SRC_SINGLE_TAP 0x20
511 #define LSM6DSV_TAP_SRC_DOUBLE_TAP 0x10
512 #define LSM6DSV_TAP_SRC_TAP_SIGN 0x08
513 #define LSM6DSV_TAP_SRC_X_TAP 0x04
514 #define LSM6DSV_TAP_SRC_Y_TAP 0x02
515 #define LSM6DSV_TAP_SRC_Z_TAP 0x01
517 // Portrait, landscape, face-up and face-down source register (R)
518 #define LSM6DSV_D6D_SRC 0x47
519 #define LSM6DSV_D6D_SRC_D6D_IA 0x40
520 #define LSM6DSV_D6D_SRC_ZH 0x20
521 #define LSM6DSV_D6D_SRC_ZL 0x10
522 #define LSM6DSV_D6D_SRC_YH 0x08
523 #define LSM6DSV_D6D_SRC_YL 0x04
524 #define LSM6DSV_D6D_SRC_XH 0x02
525 #define LSM6DSV_D6D_SRC_XL 0x01
527 // Sensor hub source register (R)
528 #define LSM6DSV_STATUS_MASTER_MAINPAGE 0x48
529 #define LSM6DSV_STATUS_MASTER_MAINPAGE_WR_ONCE_DONE 0x80
530 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE3_NACK 0x40
531 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE2_NACK 0x20
532 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE1_NACK 0x10
533 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE0_NACK 0x08
534 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SENS_HUB_ENDOP 0x01
536 // Embedded function status register (R)
537 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE 0x49
538 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_FSM_LC 0x80
539 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_SIGMOT 0x20
540 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_TILT 0x10
541 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_STEP_DET 0x08
543 // Finite state machine status register (R)
544 #define LSM6DSV_FSM_STATUS_MAINPAGE 0x4A
545 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM8 0x80
546 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM7 0x40
547 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM6 0x20
548 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM5 0x10
549 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM4 0x08
550 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM3 0x04
551 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM2 0x02
552 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM1 0x01
554 // Embedded function status register (R)
555 #define LSM6DSV_MLC_STATUS_MAINPAGE 0x4B
556 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC4 0x08
557 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC3 0x04
558 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC2 0x02
559 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC1 0x01
563 // Internal frequency register (R)
564 #define LSM6DSV_INTERNAL_FREQ_FINE 0x4F
566 // Enable interrupt functions register (R/W)
567 #define LSM6DSV_FUNCTIONS_ENABLE 0x50
568 #define LSM6DSV_FUNCTIONS_ENABLE_INTERRUPTS_ENABLE 0x80
569 #define LSM6DSV_FUNCTIONS_ENABLE_TIMESTAMP_EN 0x40
570 #define LSM6DSV_FUNCTIONS_ENABLE_DIS_RST_LIR_ALL_INT 0x08
571 #define LSM6DSV_FUNCTIONS_ENABLE_INACT_EN_MASK 0x03
572 #define LSM6DSV_FUNCTIONS_ENABLE_INACT_EN_SHIFT 0
574 // DEN configuration register (R/W)
575 #define LSM6DSV_DEN 0x51
576 #define LSM6DSV_DEN_LVL1_EN 0x40
577 #define LSM6DSV_DEN_LVL2_EN 0x20
578 #define LSM6DSV_DEN_DEN_XL_EN 0x10
579 #define LSM6DSV_DEN_DEN_X 0x08
580 #define LSM6DSV_DEN_DEN_Y 0x04
581 #define LSM6DSV_DEN_DEN_Z 0x02
582 #define LSM6DSV_DEN_DEN_XL_G 0x01
584 // Activity/inactivity configuration register (R/W)
585 #define LSM6DSV_INACTIVITY_DUR 0x54
586 #define LSM6DSV_INACTIVITY_DUR_SLEEP_STATUS_ON_INT 0x80
587 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_MASK 0x70
588 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_SHIFT 4
589 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_7_8125MG_LSB 0
590 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_15_625MG_LSB 1
591 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_31_25MG_LSB 2
592 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_62_5MG_LSB 3
593 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_125MG_LSB 4
594 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_250MG_LSB 5
595 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_MASK 0x0c
596 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_SHIFT 2
597 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_1_875HZ 0
598 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_15HZ 1
599 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_30HZ 2
600 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_60HZ 3
601 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_MASK 0x03
602 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_SHIFT 0
603 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_1 0
604 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_2 1
605 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_3 2
606 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_4 3
608 // Activity/inactivity threshold setting register (R/W)
609 #define LSM6DSV_INACTIVITY_THS 0x55
610 #define LSM6DSV_INACTIVITY_THS_MASK 0x3f
612 // Tap configuration register 0 (R/W)
613 #define LSM6DSV_TAP_CFG0 0x56
614 #define LSM6DSV_TAP_CFG0_LOW_PASS_ON_6D 0x40
615 #define LSM6DSV_TAP_CFG0_HW_FUNC_MASK_XL_SETTL 0x20
616 #define LSM6DSV_TAP_CFG0_SLOPE_FDS 0x10
617 #define LSM6DSV_TAP_CFG0_TAP_X_EN 0x08
618 #define LSM6DSV_TAP_CFG0_TAP_Y_EN 0x04
619 #define LSM6DSV_TAP_CFG0_TAP_Z_EN 0x02
620 #define LSM6DSV_TAP_CFG0_LIR 0x01
622 // Tap configuration register 1 (R/W)
623 #define LSM6DSV_TAP_CFG1 0x57
624 #define LSM6DSV_TAP_CFG1_TAP_PRIORITY_MASK 0xe0
625 #define LSM6DSV_TAP_CFG1_TAP_PRIORITY_SHIFT 5
626 #define LSM6DSV_TAP_CFG1_TAP_THS_X_MASK 0x1f
627 #define LSM6DSV_TAP_CFG1_TAP_THS_X_SHIFT 0
629 // Tap configuration register 2 (R/W)
630 #define LSM6DSV_TAP_CFG2 0x58
631 #define LSM6DSV_TAP_CFG2_TAP_THS_X_MASK 0x1f
632 #define LSM6DSV_TAP_CFG2_TAP_THS_X_SHIFT 0
634 // Portrait/landscape position and tap function threshold register (R/W)
635 #define LSM6DSV_TAP_THS_6D 0x59
636 #define LSM6DSV_TAP_THS_6D_D4D_EN 0x80
637 #define LSM6DSV_TAP_THS_6D_SIXD_THS_MASK 0x60
638 #define LSM6DSV_TAP_THS_6D_SIXD_THS_SHIFT 5
639 #define LSM6DSV_TAP_THS_6D_TAP_THS_Z_MASK 0x1f
640 #define LSM6DSV_TAP_THS_6D_TAP_THS_Z_SHIFT 0
642 // Tap recognition function setting register (R/W)
643 #define LSM6DSV_TAP_DUR 0x5A
644 #define LSM6DSV_TAP_DUR_DUR_MASK 0xf0
645 #define LSM6DSV_TAP_DUR_DUR_SHIFT 4
646 #define LSM6DSV_TAP_DUR_QUIET_MASK 0x0c
647 #define LSM6DSV_TAP_DUR_QUIET_SHIFT 2
648 #define LSM6DSV_TAP_DUR_SHOCK_MASK 0x03
649 #define LSM6DSV_TAP_DUR_SHOCK_SHIFT 0
651 // Single/double-tap selection and wake-up configuration (R/W)
652 #define LSM6DSV_WAKE_UP_THS 0x5B
653 #define LSM6DSV_WAKE_UP_THS_SINGLE_DOUBLE_TAP 0x80
654 #define LSM6DSV_WAKE_UP_THS_USR_OFF_ON_WU 0x40
655 #define LSM6DSV_WAKE_UP_THS_WK_THS_MASK 0x3f
656 #define LSM6DSV_WAKE_UP_THS_WK_THS_SHIFT 6
658 // Free-fall, wake-up, and sleep mode functions duration setting register (R/W)
659 #define LSM6DSV_WAKE_UP_DUR 0x5C
660 #define LSM6DSV_WAKE_UP_DUR_FF_DUR_5 0x80
661 #define LSM6DSV_WAKE_UP_DUR_WAKE_DUR_MASK 0x60
662 #define LSM6DSV_WAKE_UP_DUR_WAKE_DUR_SHIFT 5
663 #define LSM6DSV_WAKE_UP_DUR_SLEEP_DUR_MASK 0x0f
664 #define LSM6DSV_WAKE_UP_DUR_SLEEP_DUR_SHIFT 0
666 // Free-fall function duration setting register (R/W)
667 #define LSM6DSV_FREE_FALL 0x5D
668 #define LSM6DSV_FREE_FALL_FF_DUR_MASK 0xf8
669 #define LSM6DSV_FREE_FALL_FF_DUR_SHIFT 3
670 #define LSM6DSV_FREE_FALL_FF_THS_MASK 0x07
671 #define LSM6DSV_FREE_FALL_FF_THS_SHIFT 0
673 // Functions routing to INT1 pin register (R/W)
674 #define LSM6DSV_MD1_CFG 0x5E
675 #define LSM6DSV_MD1_CFG_INT1_SLEEP_CHANG 0x80
676 #define LSM6DSV_MD1_CFG_INT1_SINGLE_TAP 0x40
677 #define LSM6DSV_MD1_CFG_INT1_WU 0x20
678 #define LSM6DSV_MD1_CFG_INT1_FF 0x10
679 #define LSM6DSV_MD1_CFG_INT1_DOUBLE_TAP 0x08
680 #define LSM6DSV_MD1_CFG_INT1_6D 0x04
681 #define LSM6DSV_MD1_CFG_INT1_EMB_FUNC 0x02
682 #define LSM6DSV_MD1_CFG_INT1_SHUB 0x01
684 // Functions routing to INT2 pin register (R/W)
685 #define LSM6DSV_MD2_CFG 0x5F
686 #define LSM6DSV_MD2_CFG_INT2_SLEEP_CHANG 0x80
687 #define LSM6DSV_MD2_CFG_INT2_SINGLE_TAP 0x40
688 #define LSM6DSV_MD2_CFG_INT2_WU 0x20
689 #define LSM6DSV_MD2_CFG_INT2_FF 0x10
690 #define LSM6DSV_MD2_CFG_INT2_DOUBLE_TAP 0x08
691 #define LSM6DSV_MD2_CFG_INT2_6D 0x04
692 #define LSM6DSV_MD2_CFG_INT2_EMB_FUNC 0x02
693 #define LSM6DSV_MD2_CFG_INT2_TIMESTAMP 0x01
697 // HAODR data rate configuration register (R/W)
698 #define LSM6DSV_HAODR_CFG 0x62
699 #define LSM6DSV_HAODR_CFG_HAODR_SEL_MASK 0x03
700 #define LSM6DSV_HAODR_CFG_HAODR_SEL_SHIFT 0
701 #define LSM6DSV_HAODR_MODE0 0
702 #define LSM6DSV_HAODR_MODE1 1
703 #define LSM6DSV_HAODR_MODE2 2
705 // Embedded functions configuration register (R/W)
706 #define LSM6DSV_EMB_FUNC_CFG 0x63
707 #define LSM6DSV_EMB_FUNC_CFG_XL_DUALC_BATCH_FROM_IF 0x80
708 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_IRQ_MASK_G_SETTL 0x20
709 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_IRQ_MASK_XL_SETTL 0x10
710 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_DISABLE 0x08
712 // Control register (UI side) for UI / SPI2 shared registers (R/W)
713 #define LSM6DSV_UI_HANDSHAKE_CTRL 0x64
714 #define LSM6DSV_UI_HANDSHAKE_CTRL_UI_SHARED_ACK 0x02
715 #define LSM6DSV_UI_HANDSHAKE_CTRL_UI_SHARED_REQ 0x01
717 // UI / SPI2 shared register 0 (R/W)
718 #define LSM6DSV_UI_SPI2_SHARED_0 0x65
720 // UI / SPI2 shared register 1 (R/W)
721 #define LSM6DSV_UI_SPI2_SHARED_1 0x66
723 // UI / SPI2 shared register 2 (R/W)
724 #define LSM6DSV_UI_SPI2_SHARED_2 0x67
726 // UI / SPI2 shared register 3 (R/W)
727 #define LSM6DSV_UI_SPI2_SHARED_3 0x68
729 // UI / SPI2 shared register 4 (R/W)
730 #define LSM6DSV_UI_SPI2_SHARED_4 0x69
732 // UI / SPI2 shared register 5 (R/W)
733 #define LSM6DSV_UI_SPI2_SHARED_5 0x6A
735 // Gyroscope EIS channel control register (R/W)
736 #define LSM6DSV_CTRL_EIS 0x6B
737 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_MASK 0xc0
738 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_SHIFT 6
739 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_OFF 0
740 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_1920HZ 1
741 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_960HZ 2
742 #define LSM6DSV_CTRL_EIS_LPF_G_EIS_BW 0x10
743 #define LSM6DSV_CTRL_EIS_G_EIS_ON_G_OIS_OUT_REG 0x08
744 #define LSM6DSV_CTRL_EIS_FS_G_EIS_MASK 0x07
745 #define LSM6DSV_CTRL_EIS_FS_G_EIS_SHIFT 0
746 #define LSM6DSV_CTRL_EIS_FS_G_EIS_125DPS 0
747 #define LSM6DSV_CTRL_EIS_FS_G_EIS_250DPS 1
748 #define LSM6DSV_CTRL_EIS_FS_G_EIS_500DPS 2
749 #define LSM6DSV_CTRL_EIS_FS_G_EIS_1000DPS 3
750 #define LSM6DSV_CTRL_EIS_FS_G_EIS_2000DPS 4
752 // RESERVED - 6C - 6E
754 // OIS interrupt configuration register (R/W)
755 #define LSM6DSV_UI_INT_OIS 0x6F
756 #define LSM6DSV_UI_INT_OIS_INT2_DRDY_OIS 0x80
757 #define LSM6DSV_UI_INT_OIS_DRDY_MASK_OIS 0x40
758 #define LSM6DSV_UI_INT_OIS_ST_OIS_CLAMPDIS 0x10
760 // OIS configuration register (R/W)
761 #define LSM6DSV_UI_CTRL1_OIS 0x70
762 #define LSM6DSV_UI_CTRL1_OIS_SIM_OIS 0x20
763 #define LSM6DSV_UI_CTRL1_OIS_OIS_XL_EN 0x04
764 #define LSM6DSV_UI_CTRL1_OIS_OIS_G_EN 0x02
765 #define LSM6DSV_UI_CTRL1_OIS_SPI2_READ_EN 0x01
767 // OIS configuration register (R/W)
768 #define LSM6DSV_UI_CTRL2_OIS 0x71
769 #define LSM6DSV_UI_CTRL2_OIS_LPF1_G_OIS_BW_MASK 0x18
770 #define LSM6DSV_UI_CTRL2_OIS_LPF1_G_OIS_BW_SHIFT 3
771 #define LSM6DSV_UI_CTRL2_OIS_FS_G_OIS_MASK 0x07
772 #define LSM6DSV_UI_CTRL2_OIS_FS_G_OIS_SHIFT 0
773 #define LSM6DSV_UI_CTRL2_FS_G_EIS_125DPS 0
774 #define LSM6DSV_UI_CTRL2_FS_G_EIS_250DPS 1
775 #define LSM6DSV_UI_CTRL2_FS_G_EIS_500DPS 2
776 #define LSM6DSV_UI_CTRL2_FS_G_EIS_1000DPS 3
777 #define LSM6DSV_UI_CTRL2_FS_G_EIS_2000DPS 4
779 // OIS configuration register (R/W)
780 #define LSM6DSV_UI_CTRL3_OIS 0x72
781 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_MASK 0x38
782 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_SHIFT 3
783 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_2G 0
784 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_4G 1
785 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_8G 2
786 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_16G 3
787 #define LSM6DSV_UI_CTRL3_OIS_FS_XL_OIS_MASK 0x03
788 #define LSM6DSV_UI_CTRL3_OIS_FS_XL_OIS_SHIFT 0
790 // Accelerometer X-axis user offset correction (R/W)
791 #define LSM6DSV_X_OFS_USR 0x73
793 // Accelerometer Y-axis user offset correction (R/W)
794 #define LSM6DSV_Y_OFS_USR 0x74
796 // Accelerometer Z-axis user offset correction (R/W)
797 #define LSM6DSV_Z_OFS_USR 0x75
801 // FIFO tag register (R)
802 #define LSM6DSV_FIFO_DATA_OUT_TAG 0x78
803 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_MASK 0xf8
804 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_SHIFT 3
805 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_EMPTY 0x00
806 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC 0x01
807 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC 0x02
808 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_TEMP 0x03
809 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_TIMESTAMP 0x04
810 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_CFG_CHANGE 0x05
811 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC_T_2 0x06
812 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC_T_1 0x07
813 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_2XC 0x08
814 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_3XC 0x09
815 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC_T_2 0x0a
816 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC_T_1 0x0b
817 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_2XC 0x0c
818 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_3XC 0x0d
819 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_0 0x0e
820 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_1 0x0f
821 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_2 0x10
822 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_3 0x11
823 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_STEP_COUNT 0x12
824 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GAME_ROT_VEC 0x13
825 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GYRO_BIAS 0x16
826 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GRAVITY_VEC 0x17
827 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_NACK 0x19
828 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_RESULT 0x1a
829 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_FILTER 0x1b
830 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_FEATURE 0x1c
831 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_DUALC 0x1d
832 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ENHANCED_EIS_GYRO 0x1e
833 #define LSM6DSV_FIFO_DATA_OUT_TAG_CNT_MASK 0x07
834 #define LSM6DSV_FIFO_DATA_OUT_TAG_CNT_SHIFT 0
836 // FIFO data output X (R)
837 #define LSM6DSV_FIFO_DATA_OUT_X_L 0x79
838 #define LSM6DSV_FIFO_DATA_OUT_X_H 0x7A
840 // FIFO data output Y (R)
841 #define LSM6DSV_FIFO_DATA_OUT_Y_L 0x7B
842 #define LSM6DSV_FIFO_DATA_OUT_Y_H 0x7C
844 // FIFO data output Z (R)
845 #define LSM6DSV_FIFO_DATA_OUT_Z_L 0x7D
846 #define LSM6DSV_FIFO_DATA_OUT_Z_H 0x7E
848 uint8_t lsm6dsv16xSpiDetect(const extDevice_t
*dev
)
850 const uint8_t whoAmI
= spiReadRegMsk(dev
, LSM6DSV_WHO_AM_I
);
852 if (whoAmI
!= LSM6DSV16X_WHO_AM_I_CONST
) {
856 return LSM6DSV16X_SPI
;
859 void lsm6dsv16xAccInit(accDev_t
*acc
)
862 acc
->acc_1G
= 512 * 4;
865 static bool lsm6dsv16xAccReadSPI(accDev_t
*acc
)
867 switch (acc
->gyro
->gyroModeSPI
) {
869 case GYRO_EXTI_NO_INT
:
871 acc
->gyro
->dev
.txBuf
[0] = LSM6DSV_OUTX_L_A
| 0x80;
873 busSegment_t segments
[] = {
874 {.u
.buffers
= {NULL
, NULL
}, 7, true, NULL
},
875 {.u
.link
= {NULL
, NULL
}, 0, true, NULL
},
877 segments
[0].u
.buffers
.txData
= acc
->gyro
->dev
.txBuf
;
878 segments
[0].u
.buffers
.rxData
= &acc
->gyro
->dev
.rxBuf
[1];
880 spiSequence(&acc
->gyro
->dev
, &segments
[0]);
882 // Wait for completion
883 spiWait(&acc
->gyro
->dev
);
885 int16_t *accData
= (int16_t *)acc
->gyro
->dev
.rxBuf
;
887 acc
->ADCRaw
[X
] = accData
[1];
888 acc
->ADCRaw
[Y
] = accData
[2];
889 acc
->ADCRaw
[Z
] = accData
[3];
893 case GYRO_EXTI_INT_DMA
:
895 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
898 // This data was read from the gyro, which is the same SPI device as the acc
899 int16_t *accData
= (int16_t *)acc
->gyro
->dev
.rxBuf
;
901 acc
->ADCRaw
[X
] = accData
[4];
902 acc
->ADCRaw
[Y
] = accData
[5];
903 acc
->ADCRaw
[Z
] = accData
[6];
915 bool lsm6dsv16xSpiAccDetect(accDev_t
*acc
)
917 if (acc
->mpuDetectionResult
.sensor
!= LSM6DSV16X_SPI
) {
921 acc
->initFn
= lsm6dsv16xAccInit
;
922 acc
->readFn
= lsm6dsv16xAccReadSPI
;
927 void lsm6dsv16xGyroInit(gyroDev_t
*gyro
)
929 const extDevice_t
*dev
= &gyro
->dev
;
930 // Set default LPF1 filter bandwidth to be as close as possible to MPU6000's 250Hz cutoff
931 uint8_t lsm6dsv16xLPF1BandwidthOptions
[GYRO_HARDWARE_LPF_COUNT
] = {
932 [GYRO_HARDWARE_LPF_NORMAL
] = LSM6DSV_CTRL6_FS_G_BW_288HZ
,
933 [GYRO_HARDWARE_LPF_OPTION_1
] = LSM6DSV_CTRL6_FS_G_BW_157HZ
,
934 [GYRO_HARDWARE_LPF_OPTION_2
] = LSM6DSV_CTRL6_FS_G_BW_215HZ
,
935 #ifdef USE_GYRO_DLPF_EXPERIMENTAL
936 [GYRO_HARDWARE_LPF_EXPERIMENTAL
] = LSM6DSV_CTRL6_FS_G_BW_455HZ
940 spiSetClkDivisor(dev
, spiCalculateDivider(LSM6DSV16X_MAX_SPI_CLK_HZ
));
942 // Perform a software reset
943 spiWriteReg(dev
, LSM6DSV_CTRL3
, LSM6DSV_CTRL3_SW_RESET
);
945 // Wait for the device to be ready
946 while (spiReadRegMsk(dev
, LSM6DSV_CTRL3
) & LSM6DSV_CTRL3_SW_RESET
) {}
948 // Autoincrement register address when doing block SPI reads and update continuously
949 spiWriteReg(dev
, LSM6DSV_CTRL3
, LSM6DSV_CTRL3_IF_INC
| LSM6DSV_CTRL3_BDU
); /*BDU bit need to be set*/
951 // Select high-accuracy ODR mode 1
952 spiWriteReg(dev
, LSM6DSV_HAODR_CFG
,
953 LSM6DSV_ENCODE_BITS(LSM6DSV_HAODR_MODE1
,
954 LSM6DSV_HAODR_CFG_HAODR_SEL_MASK
,
955 LSM6DSV_HAODR_CFG_HAODR_SEL_SHIFT
));
957 // Enable the accelerometer in high accuracy
958 spiWriteReg(dev
, LSM6DSV_CTRL1
,
959 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL1_OP_MODE_XL_HIGH_ACCURACY
,
960 LSM6DSV_CTRL1_OP_MODE_XL_MASK
,
961 LSM6DSV_CTRL1_OP_MODE_XL_SHIFT
));
963 // Enable the gyro in high accuracy
964 spiWriteReg(dev
, LSM6DSV_CTRL2
,
965 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL2_OP_MODE_G_HIGH_ACCURACY
,
966 LSM6DSV_CTRL2_OP_MODE_G_MASK
,
967 LSM6DSV_CTRL2_OP_MODE_G_SHIFT
));
969 // Enable 16G sensitivity
970 spiWriteReg(dev
, LSM6DSV_CTRL8
,
971 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL8_FS_XL_16G
,
972 LSM6DSV_CTRL8_FS_XL_MASK
,
973 LSM6DSV_CTRL8_FS_XL_SHIFT
));
975 // Enable the accelerometer odr at 1kHz
976 spiWriteReg(dev
, LSM6DSV_CTRL1
,
977 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL1_ODR_XL_1000HZ
,
978 LSM6DSV_CTRL1_ODR_XL_MASK
,
979 LSM6DSV_CTRL1_ODR_XL_SHIFT
));
981 // Enable the gyro odr at 8kHz
982 spiWriteReg(dev
, LSM6DSV_CTRL2
,
983 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL2_ODR_G_8000HZ
,
984 LSM6DSV_CTRL2_ODR_G_MASK
,
985 LSM6DSV_CTRL2_ODR_G_SHIFT
));
987 // Enable 2000 deg/s sensitivity and selected LPF1 filter setting
988 // Set the LPF1 filter bandwidth
989 spiWriteReg(dev
, LSM6DSV_CTRL6
,
990 LSM6DSV_ENCODE_BITS(lsm6dsv16xLPF1BandwidthOptions
[gyroConfig()->gyro_hardware_lpf
],
991 LSM6DSV_CTRL6_LPF1_G_BW_MASK
,
992 LSM6DSV_CTRL6_LPF1_G_BW_SHIFT
) |
993 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL6_FS_G_2000DPS
,
994 LSM6DSV_CTRL6_FS_G_MASK
,
995 LSM6DSV_CTRL6_FS_G_SHIFT
));
997 // Enable the gyro digital LPF1 filter
998 spiWriteReg(dev
, LSM6DSV_CTRL7
, LSM6DSV_CTRL7_LPF1_G_EN
);
1000 // Generate pulse on interrupt line, not requiring a read to clear
1001 spiWriteReg(dev
, LSM6DSV_CTRL4
, LSM6DSV_CTRL4_DRDY_PULSED
);
1003 // From section 4.1, Mechanical characteristics, of the datasheet, G_So is 70mdps/LSB for FS = ±2000 dps.
1004 gyro
->scale
= 0.070f
;
1006 // Enable the INT1 output to interrupt when new gyro data is ready
1007 spiWriteReg(dev
, LSM6DSV_INT1_CTRL
, LSM6DSV_INT1_CTRL_INT1_DRDY_G
);
1012 bool lsm6dsv16xGyroReadSPI(gyroDev_t
*gyro
)
1014 int16_t *gyroData
= (int16_t *)gyro
->dev
.rxBuf
;
1015 switch (gyro
->gyroModeSPI
) {
1016 case GYRO_EXTI_INIT
:
1018 // Initialise the tx buffer to all 0xff
1019 memset(gyro
->dev
.txBuf
, 0xff, 16);
1021 // Check that minimum number of interrupts have been detected
1023 // We need some offset from the gyro interrupts to ensure sampling after the interrupt
1024 gyro
->gyroDmaMaxDuration
= 5;
1025 if (gyro
->detectedEXTI
> GYRO_EXTI_DETECT_THRESHOLD
) {
1026 if (spiUseDMA(&gyro
->dev
)) {
1027 gyro
->dev
.callbackArg
= (uint32_t)gyro
;
1028 gyro
->dev
.txBuf
[0] = LSM6DSV_OUTX_L_G
| 0x80;
1029 // Read three words of gyro data immediately followed by three bytes of acc data
1030 gyro
->segments
[0].len
= sizeof(uint8_t) + 6 * sizeof(int16_t);
1031 gyro
->segments
[0].callback
= mpuIntCallback
;
1032 gyro
->segments
[0].u
.buffers
.txData
= gyro
->dev
.txBuf
;
1033 gyro
->segments
[0].u
.buffers
.rxData
= &gyro
->dev
.rxBuf
[1];
1034 gyro
->segments
[0].negateCS
= true;
1035 gyro
->gyroModeSPI
= GYRO_EXTI_INT_DMA
;
1037 // Interrupts are present, but no DMA
1038 gyro
->gyroModeSPI
= GYRO_EXTI_INT
;
1041 gyro
->gyroModeSPI
= GYRO_EXTI_NO_INT
;
1047 case GYRO_EXTI_NO_INT
:
1049 gyro
->dev
.txBuf
[0] = LSM6DSV_OUTX_L_G
| 0x80;
1051 busSegment_t segments
[] = {
1052 {.u
.buffers
= {NULL
, NULL
}, 7, true, NULL
},
1053 {.u
.link
= {NULL
, NULL
}, 0, true, NULL
},
1055 segments
[0].u
.buffers
.txData
= gyro
->dev
.txBuf
;
1056 segments
[0].u
.buffers
.rxData
= &gyro
->dev
.rxBuf
[1];
1058 spiSequence(&gyro
->dev
, &segments
[0]);
1060 // Wait for completion
1061 spiWait(&gyro
->dev
);
1063 gyro
->gyroADCRaw
[X
] = gyroData
[1];
1064 gyro
->gyroADCRaw
[Y
] = gyroData
[2];
1065 gyro
->gyroADCRaw
[Z
] = gyroData
[3];
1069 case GYRO_EXTI_INT_DMA
:
1071 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
1073 gyro
->gyroADCRaw
[X
] = gyroData
[1];
1074 gyro
->gyroADCRaw
[Y
] = gyroData
[2];
1075 gyro
->gyroADCRaw
[Z
] = gyroData
[3];
1086 bool lsm6dsv16xSpiGyroDetect(gyroDev_t
*gyro
)
1088 if (gyro
->mpuDetectionResult
.sensor
!= LSM6DSV16X_SPI
) {
1092 gyro
->initFn
= lsm6dsv16xGyroInit
;
1093 gyro
->readFn
= lsm6dsv16xGyroReadSPI
;
1097 #endif // USE_ACCGYRO_LSM6DSV16X