Encapsulate LSM6DSV16X driver specific macros (#13196)
[betaflight.git] / src / main / drivers / accgyro / accgyro_spi_lsm6dsv16x.c
blobd167b8847a01f86ecc859969d681d0f5466b3d14
1 /*
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
8 * version.
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/>.
22 #include <stdlib.h>
23 #include <string.h>
25 #include "platform.h"
27 #if defined(USE_ACCGYRO_LSM6DSV16X)
29 #include "accgyro_spi_lsm6dsv16x.h"
31 /* See datasheet
33 * 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
37 // 10 MHz max SPI frequency
38 #define LSM6DSV16X_MAX_SPI_CLK_HZ 10000000
40 // Need to see at least this many interrupts during initialisation to confirm EXTI connectivity
41 #define GYRO_EXTI_DETECT_THRESHOLD 1000
43 // Macros to encode/decode multi-bit values
44 #define LSM6DSV_ENCODE_BITS(val, mask, shift) ((val << shift) & mask)
45 #define LSM6DSV_DECODE_BITS(val, mask, shift) ((val & mask) >> shift)
47 // Enable embedded functions register (R/W)
48 #define LSM6DSV_FUNC_CFG_ACCESS 0x01
49 #define LSM6DSV_EMB_FUNC_REG_ACCESS_EMB_FUNC_REG_ACCESS 0x80
50 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SHUB_REG_ACCESS 0x40
51 #define LSM6DSV_EMB_FUNC_REG_ACCESS_FSM_WR_CTRL_EN 0x08
52 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SW_POR 0x04
53 #define LSM6DSV_EMB_FUNC_REG_ACCESS_SPI2_RESET 0x02
54 #define LSM6DSV_EMB_FUNC_REG_ACCESS_OIS_CTRL_FROM_UI 0x01
56 // SDO, OCS_Aux, SDO_Aux pins pull-up register (R/W)
57 #define LSM6DSV_PIN_CTRL 0x02
58 #define LSM6DSV_PIN_CTRL_OIRS_PU_DIS 0x80
59 #define LSM6DSV_PIN_CTRL_DSO_PU_EN 0x40
60 #define LSM6DSV_PIN_CTRL_IBHR_POR_EN 0x20
61 #define LSM6DSV_PIN_CTRL_RESDV 0x03
63 // Interface configuration register (R/W)
64 #define LSM6DSV_IF_CFG 0x03
65 #define LSM6DSV_IF_CFG_SDA_PU_EN 0x80
66 #define LSM6DSV_IF_CFG_SHUB_PU_EN 0x40
67 #define LSM6DSV_IF_CFG_ASF_CTRL 0x20
68 #define LSM6DSV_IF_CFG_H_LACTIVE 0x10
69 #define LSM6DSV_IF_CFG_PP_OD 0x08
70 #define LSM6DSV_IF_CFG_SIM 0x04
71 #define LSM6DSV_IF_CFG_I2C_I3C_DISABLE 0x01
73 // ODR-triggered mode configuration register (R/W)
74 #define LSM6DSV_ODR_TRIG_CFG 0x06
76 // FIFO control register 1 (R/W)
77 #define LSM6DSV_FIFO_CTRL1 0x07
79 // FIFO control register 2 (R/W)
80 #define LSM6DSV_FIFO_CTRL2 0x08
81 #define LSM6DSV_FIFO_CTRL2_STOP_ON_WTM 0x80
82 #define LSM6DSV_FIFO_CTRL2_FIFO_COMPR_RT_EN 0x40
83 #define LSM6DSV_FIFO_CTRL2_ODR_CHG_EN 0x10
84 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_MASK 0x06
85 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_SHIFT 1
86 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_NOT_FORCED 0
87 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_8 1
88 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_16 2
89 #define LSM6DSV_FIFO_CTRL2_UNCOMPR_RATE_32 3
90 #define LSM6DSV_FIFO_CTRL2_XL_DUALC_BATCH_FROM_FS 0x01
92 // FIFO control register 3 (R/W)
93 #define LSM6DSV_FIFO_CTRL3 0x09
94 #define LSM6DSV_FIFO_CTRL3_BDR_GY_MASK 0xf0
95 #define LSM6DSV_FIFO_CTRL3_BDR_GY_SHIFT 4
96 #define LSM6DSV_FIFO_CTRL3_BDR_GY_1875HZ 0x01
97 #define LSM6DSV_FIFO_CTRL3_BDR_GY_7_5HZ 0x02
98 #define LSM6DSV_FIFO_CTRL3_BDR_GY_15HZ 0x03
99 #define LSM6DSV_FIFO_CTRL3_BDR_GY_30HZ 0x04
100 #define LSM6DSV_FIFO_CTRL3_BDR_GY_60HZ 0x05
101 #define LSM6DSV_FIFO_CTRL3_BDR_GY_120HZ 0x06
102 #define LSM6DSV_FIFO_CTRL3_BDR_GY_240HZ 0x07
103 #define LSM6DSV_FIFO_CTRL3_BDR_GY_480HZ 0x08
104 #define LSM6DSV_FIFO_CTRL3_BDR_GY_960HZ 0x09
105 #define LSM6DSV_FIFO_CTRL3_BDR_GY_1920HZ 0x0a
106 #define LSM6DSV_FIFO_CTRL3_BDR_GY_3840HZ 0x0b
107 #define LSM6DSV_FIFO_CTRL3_BDR_GY_7680HZ 0x0c
108 #define LSM6DSV_FIFO_CTRL3_BDR_XL_MASK 0xff
109 #define LSM6DSV_FIFO_CTRL3_BDR_XL_SHIFT 0
110 #define LSM6DSV_FIFO_CTRL3_BDR_XL_1875HZ 0x01
111 #define LSM6DSV_FIFO_CTRL3_BDR_XL_7_5HZ 0x02
112 #define LSM6DSV_FIFO_CTRL3_BDR_XL_15HZ 0x03
113 #define LSM6DSV_FIFO_CTRL3_BDR_XL_30HZ 0x04
114 #define LSM6DSV_FIFO_CTRL3_BDR_XL_60HZ 0x05
115 #define LSM6DSV_FIFO_CTRL3_BDR_XL_120HZ 0x06
116 #define LSM6DSV_FIFO_CTRL3_BDR_XL_240HZ 0x07
117 #define LSM6DSV_FIFO_CTRL3_BDR_XL_480HZ 0x08
118 #define LSM6DSV_FIFO_CTRL3_BDR_XL_960HZ 0x09
119 #define LSM6DSV_FIFO_CTRL3_BDR_XL_1920HZ 0x0a
120 #define LSM6DSV_FIFO_CTRL3_BDR_XL_3840HZ 0x0b
121 #define LSM6DSV_FIFO_CTRL3_BDR_XL_7680HZ 0x0c
123 // FIFO control register 4 (R/W)
124 #define LSM6DSV_FIFO_CTRL4 0x0A
125 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_MASK 0xc0
126 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_SHIFT 6
127 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_NONE 0
128 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_1 1
129 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_8 2
130 #define LSM6DSV_FIFO_CTRL4_DEC_TS_BATCH_DECIMATION_32 3
131 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_MASK 0x30
132 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_SHIFT 4
133 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_NONE 0
134 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_1875HZ 1
135 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_15HZ 2
136 #define LSM6DSV_FIFO_CTRL4_ODR_T_BATCH_60HZ 3
137 #define LSM6DSV_FIFO_CTRL4_G_EIS_FIFO_EN 0x08
138 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_MASK 0x07
139 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_SHIFT 0
140 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS 0
141 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_FIFO_MODE 1
142 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT_WTM 2
143 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT_FIFO 3
144 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS_CONT 4
145 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_CONT 6
146 #define LSM6DSV_FIFO_CTRL4_FIFO_MODE_BYPASS_FIFO 7
148 // Counter batch data rate register 1 (R/W)
149 #define LSM6DSV_COUNTER_BDR_REG1 0x0B
150 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_MASK 0x60
151 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_SHIFT 5
152 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_ACC 0
153 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_GYRO 1
154 #define LSM6DSV_COUNTER_BDR_REG1_TRIG_COUNTER_BDR_GYRO_EIS 2
155 #define LSM6DSV_COUNTER_BDR_REG2_CNT_BDR_TH_HI_MASK 0x03
156 #define LSM6DSV_COUNTER_BDR_REG2_CNT_BDR_TH_HI_SHIFT 0
158 // Counter batch data rate register 2 (R/W)
159 #define LSM6DSV_COUNTER_BDR_REG2 0x0C
161 // INT1 pin control register (R/W)
162 #define LSM6DSV_INT1_CTRL 0x0D
163 #define LSM6DSV_INT1_CTRL_INT1_CNT_BDR 0x40
164 #define LSM6DSV_INT1_CTRL_INT1_FIFO_FULL 0x20
165 #define LSM6DSV_INT1_CTRL_INT1_FIFO_OVR 0x10
166 #define LSM6DSV_INT1_CTRL_INT1_FIFO_TH 0x08
167 #define LSM6DSV_INT1_CTRL_INT1_DRDY_G 0x02
168 #define LSM6DSV_INT1_CTRL_INT1_DRDY_XL 0x01
170 // INT2 pin control register (R/W)
171 #define LSM6DSV_INT2_CTRL 0x0E
172 #define LSM6DSV_INT2_CTRL_INT2_EMB_FUNC_ENDOP 0x80
173 #define LSM6DSV_INT2_CTRL_INT2_CNT_BDR 0x40
174 #define LSM6DSV_INT2_CTRL_INT2_FIFO_FULL 0x20
175 #define LSM6DSV_INT2_CTRL_INT2_FIFO_OVR 0x10
176 #define LSM6DSV_INT2_CTRL_INT2_FIFO_TH 0x08
177 #define LSM6DSV_INT2_CTRL_INT2_DRDY_G_EIS 0x04
178 #define LSM6DSV_INT2_CTRL_INT2_DRDY_G 0x02
179 #define LSM6DSV_INT2_CTRL_INT2_DRDY_XL 0x01
181 // WHO_AM_I register (R)
182 #define LSM6DSV_WHO_AM_I 0x0F
184 // Accelerometer control register 1 (R/W)
185 #define LSM6DSV_CTRL1 0x10
186 #define LSM6DSV_CTRL1_OP_MODE_XL_MASK 0x70
187 #define LSM6DSV_CTRL1_OP_MODE_XL_SHIFT 4
188 #define LSM6DSV_CTRL1_OP_MODE_XL_HIGH_PERF 0
189 #define LSM6DSV_CTRL1_OP_MODE_XL_HIGH_ACCURACY 1
190 #define LSM6DSV_CTRL1_OP_MODE_XL_ODR_TRIG 3
191 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE1 4
192 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE2 5
193 #define LSM6DSV_CTRL1_OP_MODE_XL_LOW_PWR_MODE3 6
194 #define LSM6DSV_CTRL1_OP_MODE_XL_NORMAL 7
195 #define LSM6DSV_CTRL1_ODR_XL_MASK 0x0f
196 #define LSM6DSV_CTRL1_ODR_XL_SHIFT 0
197 #define LSM6DSV_CTRL1_ODR_XL_POWERDOWN 0
198 #define LSM6DSV_CTRL1_ODR_XL_1875HZ 1
199 #define LSM6DSV_CTRL1_ODR_XL_7_5HZ 2
201 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 00
202 // or in high-performance mode mode
203 #define LSM6DSV_CTRL1_ODR_XL_15HZ 3
204 #define LSM6DSV_CTRL1_ODR_XL_30HZ 4
205 #define LSM6DSV_CTRL1_ODR_XL_60HZ 5
206 #define LSM6DSV_CTRL1_ODR_XL_120HZ 6
207 #define LSM6DSV_CTRL1_ODR_XL_240HZ 7
208 #define LSM6DSV_CTRL1_ODR_XL_480HZ 8
209 #define LSM6DSV_CTRL1_ODR_XL_960HZ 9
210 #define LSM6DSV_CTRL1_ODR_XL_1920HZ 10
211 #define LSM6DSV_CTRL1_ODR_XL_3840HZ 11
212 #define LSM6DSV_CTRL1_ODR_XL_7680HZ 12
214 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 01
215 #define LSM6DSV_CTRL1_ODR_XL_15_625HZ 3
216 #define LSM6DSV_CTRL1_ODR_XL_31_25HZ 4
217 #define LSM6DSV_CTRL1_ODR_XL_62_5HZ 5
218 #define LSM6DSV_CTRL1_ODR_XL_125HZ 6
219 #define LSM6DSV_CTRL1_ODR_XL_250HZ 7
220 #define LSM6DSV_CTRL1_ODR_XL_500HZ 8
221 #define LSM6DSV_CTRL1_ODR_XL_1000HZ 9
222 #define LSM6DSV_CTRL1_ODR_XL_2000HZ 10
223 #define LSM6DSV_CTRL1_ODR_XL_4000HZ 11
224 #define LSM6DSV_CTRL1_ODR_XL_8000HZ 12
226 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 10
227 #define LSM6DSV_CTRL1_ODR_XL_12_5HZ 3
228 #define LSM6DSV_CTRL1_ODR_XL_25HZ 4
229 #define LSM6DSV_CTRL1_ODR_XL_50HZ 5
230 #define LSM6DSV_CTRL1_ODR_XL_100HZ 6
231 #define LSM6DSV_CTRL1_ODR_XL_200HZ 7
232 #define LSM6DSV_CTRL1_ODR_XL_400HZ 8
233 #define LSM6DSV_CTRL1_ODR_XL_800HZ 9
234 #define LSM6DSV_CTRL1_ODR_XL_1600HZ 10
235 #define LSM6DSV_CTRL1_ODR_XL_3200HZ 11
236 #define LSM6DSV_CTRL1_ODR_XL_6400HZ 12
238 // Gyroscope control register 2 (R/W)
239 #define LSM6DSV_CTRL2 0x11
240 #define LSM6DSV_CTRL2_OP_MODE_G_MASK 0x70
241 #define LSM6DSV_CTRL2_OP_MODE_G_SHIFT 4
242 #define LSM6DSV_CTRL2_OP_MODE_G_HIGH_PERF 0
243 #define LSM6DSV_CTRL2_OP_MODE_G_HIGH_ACCURACY 1
244 #define LSM6DSV_CTRL2_OP_MODE_G_ODR_TRIG 3
245 #define LSM6DSV_CTRL2_OP_MODE_G_SLEEP 4
246 #define LSM6DSV_CTRL2_OP_MODE_G_LOW_PWR_MODE 5
247 #define LSM6DSV_CTRL2_ODR_G_MASK 0x0f
248 #define LSM6DSV_CTRL2_ODR_G_SHIFT 0
249 #define LSM6DSV_CTRL2_ODR_G_POWERDOWN 0
250 #define LSM6DSV_CTRL2_ODR_G_1875HZ 1
251 #define LSM6DSV_CTRL2_ODR_G_7_5HZ 2
253 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 00
254 // or in high-performance mode mode
255 #define LSM6DSV_CTRL2_ODR_G_15HZ 3
256 #define LSM6DSV_CTRL2_ODR_G_30HZ 4
257 #define LSM6DSV_CTRL2_ODR_G_60HZ 5
258 #define LSM6DSV_CTRL2_ODR_G_120HZ 6
259 #define LSM6DSV_CTRL2_ODR_G_240HZ 7
260 #define LSM6DSV_CTRL2_ODR_G_480HZ 8
261 #define LSM6DSV_CTRL2_ODR_G_960HZ 9
262 #define LSM6DSV_CTRL2_ODR_G_1920HZ 10
263 #define LSM6DSV_CTRL2_ODR_G_3840HZ 11
264 #define LSM6DSV_CTRL2_ODR_G_7680HZ 12
266 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 01
267 #define LSM6DSV_CTRL2_ODR_G_15_625HZ 3
268 #define LSM6DSV_CTRL2_ODR_G_31_25HZ 4
269 #define LSM6DSV_CTRL2_ODR_G_62_5HZ 5
270 #define LSM6DSV_CTRL2_ODR_G_125HZ 6
271 #define LSM6DSV_CTRL2_ODR_G_250HZ 7
272 #define LSM6DSV_CTRL2_ODR_G_500HZ 8
273 #define LSM6DSV_CTRL2_ODR_G_1000HZ 9
274 #define LSM6DSV_CTRL2_ODR_G_2000HZ 10
275 #define LSM6DSV_CTRL2_ODR_G_4000HZ 11
276 #define LSM6DSV_CTRL2_ODR_G_8000HZ 12
278 // Values to use in high-accuracy ODR mode with HAODR_SEL[] = 10
279 #define LSM6DSV_CTRL2_ODR_G_12_5HZ 3
280 #define LSM6DSV_CTRL2_ODR_G_25HZ 4
281 #define LSM6DSV_CTRL2_ODR_G_50HZ 5
282 #define LSM6DSV_CTRL2_ODR_G_100HZ 6
283 #define LSM6DSV_CTRL2_ODR_G_200HZ 7
284 #define LSM6DSV_CTRL2_ODR_G_400HZ 8
285 #define LSM6DSV_CTRL2_ODR_G_800HZ 9
286 #define LSM6DSV_CTRL2_ODR_G_1600HZ 10
287 #define LSM6DSV_CTRL2_ODR_G_3200HZ 11
288 #define LSM6DSV_CTRL2_ODR_G_6400HZ 12
291 // Control register 3 (R/W)
292 #define LSM6DSV_CTRL3 0x12
293 #define LSM6DSV_CTRL3_BOOT 0x80
294 #define LSM6DSV_CTRL3_BDU 0x40
295 #define LSM6DSV_CTRL3_IF_INC 0x04
296 #define LSM6DSV_CTRL3_SW_RESET 0x01
298 // Control register 4 (R/W)
299 #define LSM6DSV_CTRL4 0x13
300 #define LSM6DSV_CTRL4_INT2_ON_INT1 0x10
301 #define LSM6DSV_CTRL4_DRDY_MASK 0x08
302 #define LSM6DSV_CTRL4_INT2_DRDY_TEMP 0x04
303 #define LSM6DSV_CTRL4_DRDY_PULSED 0x02
304 #define LSM6DSV_CTRL4_INT2_IN_LH 0x01
306 // Control register 5 (R/W)
307 #define LSM6DSV_CTRL5 0x14
308 #define LSM6DSV_CTRL5_BUS_ACT_SEL_MASK 0x06
309 #define LSM6DSV_CTRL5_BUS_ACT_SEL_SHIFT 1
310 #define LSM6DSV_CTRL5_BUS_ACT_SEL_2US 0
311 #define LSM6DSV_CTRL5_BUS_ACT_SEL_50US 1
312 #define LSM6DSV_CTRL5_BUS_ACT_SEL_1US 2
313 #define LSM6DSV_CTRL5_BUS_ACT_SEL_25US 3
314 #define LSM6DSV_CTRL5_INT_EN_I3C 0x01
316 // Control register 6 (R/W)
317 #define LSM6DSV_CTRL6 0x15
318 #define LSM6DSV_CTRL6_LPF1_G_BW_MASK 0x70 // See table 64
319 #define LSM6DSV_CTRL6_LPF1_G_BW_SHIFT 4
321 // Gyro LPF1 + LPF2 bandwidth selection when ODR=7.68kHz
322 #define LSM6DSV_CTRL6_FS_G_BW_281HZ 0
323 #define LSM6DSV_CTRL6_FS_G_BW_213HZ 1
324 #define LSM6DSV_CTRL6_FS_G_BW_156HZ 2
325 #define LSM6DSV_CTRL6_FS_G_BW_407HZ 3
326 #define LSM6DSV_CTRL6_FS_G_BW_102HZ 4
327 #define LSM6DSV_CTRL6_FS_G_BW_58HZ 5
328 #define LSM6DSV_CTRL6_FS_G_BW_28_8HZ 6
329 #define LSM6DSV_CTRL6_FS_G_BW_14_4HZ 7
331 #define LSM6DSV_CTRL6_FS_G_MASK 0x0f
332 #define LSM6DSV_CTRL6_FS_G_SHIFT 0
333 #define LSM6DSV_CTRL6_FS_G_125DPS 0x00
334 #define LSM6DSV_CTRL6_FS_G_250DPS 0x01
335 #define LSM6DSV_CTRL6_FS_G_500DPS 0x02
336 #define LSM6DSV_CTRL6_FS_G_1000DPS 0x03
337 #define LSM6DSV_CTRL6_FS_G_2000DPS 0x04
338 #define LSM6DSV_CTRL6_FS_G_4000DPS 0xc0
340 // Control register 7 (R/W)
341 #define LSM6DSV_CTRL7 0x16
342 #define LSM6DSV_CTRL7_AH_QVAR_EN 0x80
343 #define LSM6DSV_CTRL7_INT2_DRDY_AH_QVAR 0x40
344 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_MASK 0x30
345 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_SHIFT 4
346 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_2_4G 0
347 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_730M 1
348 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_300M 2
349 #define LSM6DSV_CTRL7_AH_QVAR_C_ZIN_235M 3
350 #define LSM6DSV_CTRL7_LPF1_G_EN 0x01
352 // Control register 8 (R/W)
353 #define LSM6DSV_CTRL8 0x17
354 #define LSM6DSV_CTRL8_HP_LPF2_XL_BW_2_MASK 0xe0 // See table 69
355 #define LSM6DSV_CTRL8_HP_LPF2_XL_BW_2_SHIFT 5
356 #define LSM6DSV_CTRL8_XL_DUALC_EN 0x08
357 #define LSM6DSV_CTRL8_FS_XL_MASK 0x03
358 #define LSM6DSV_CTRL8_FS_XL_SHIFT 0
359 #define LSM6DSV_CTRL8_FS_XL_2G 0
360 #define LSM6DSV_CTRL8_FS_XL_4G 1
361 #define LSM6DSV_CTRL8_FS_XL_8G 2
362 #define LSM6DSV_CTRL8_FS_XL_16G 3
364 // Control register 9 (R/W)
365 #define LSM6DSV_CTRL9 0x18
366 #define LSM6DSV_CTRL9_HP_REF_MODE_XL 0x40
367 #define LSM6DSV_CTRL9_XL_FASTSETTL_MODE 0x20
368 #define LSM6DSV_CTRL9_HP_SLOPE_XL_EN 0x10
369 #define LSM6DSV_CTRL9_LPF2_XL_EN 0x08
370 #define LSM6DSV_CTRL9_USR_OFF_W 0x02
371 #define LSM6DSV_CTRL9_USR_OFF_ON_OUT 0x01
373 // Control register 10 (R/W)
374 #define LSM6DSV_CTRL10 0x19
375 #define LSM6DSV_CTRL10_EMB_FUNC_DEBUG 0x40
376 #define LSM6DSV_CTRL10_ST_G_MASK 0x0c
377 #define LSM6DSV_CTRL10_ST_G_SHIFT 2
378 #define LSM6DSV_CTRL10_ST_G_NORMAL 0
379 #define LSM6DSV_CTRL10_ST_G_POS_SELFTEST 1
380 #define LSM6DSV_CTRL10_ST_G_NEG_SELFTEST 2
381 #define LSM6DSV_CTRL10_ST_XL_MASK 0x03
382 #define LSM6DSV_CTRL10_ST_XL_SHIFT 0
383 #define LSM6DSV_CTRL10_ST_XL_NORMAL 0
384 #define LSM6DSV_CTRL10_ST_XL_POS_SELFTEST 1
385 #define LSM6DSV_CTRL10_ST_XL_NEG_SELFTEST 2
387 // Control Status (R)
388 #define LSM6DSV_CTRL_STATUS 0x1A
389 #define LSM6DSV_CTRL_STATUS_FSM_WR_CTRL_STATUS 0x04
391 // FIFO status register 1 (R)
392 #define LSM6DSV_FIFO_STATUS1 0x1B
394 // FIFO status register 2 (R)
395 #define LSM6DSV_FIFO_STATUS2 0x1C
396 #define LSM6DSV_FIFO_STATUS2_FIFO_WTM_IA 0x80
397 #define LSM6DSV_FIFO_STATUS2_FIFO_OVR_IA 0x40
398 #define LSM6DSV_FIFO_STATUS2_FIFO_FULL_IA 0x20
399 #define LSM6DSV_FIFO_STATUS2_COUNTER_BDR_IA 0x10
400 #define LSM6DSV_FIFO_STATUS2_FIFO_OVR_LATCHED 0x08
401 #define LSM6DSV_FIFO_STATUS2_DIFF_FIFO_8 0x01
403 // Source register for all interrupts (R)
404 #define LSM6DSV_ALL_INT_SRC 0x1D
405 #define LSM6DSV_ALL_INT_SRC_EMB_FUNC_IA 0x80
406 #define LSM6DSV_ALL_INT_SRC_SHUB_IA 0x40
407 #define LSM6DSV_ALL_INT_SRC_SLEEP_CHANGE_IA 0x20
408 #define LSM6DSV_ALL_INT_SRC_D6D_IA 0x10
409 #define LSM6DSV_ALL_INT_SRC_TAP_IA 0x04
410 #define LSM6DSV_ALL_INT_SRC_WU_IA 0x02
411 #define LSM6DSV_ALL_INT_SRC_FF_IA 0x01
413 // The STATUS_REG register is read by the primary interface SPI/I²C & MIPI I3C® (R)
414 #define LSM6DSV_STATUS_REG 0x1E
415 #define LSM6DSV_STATUS_REG_TIMESTAMP_ENDCOUNT 0x80
416 #define LSM6DSV_STATUS_REG_OIS_DRDY 0x20
417 #define LSM6DSV_STATUS_REG_GDA_EIS 0x10
418 #define LSM6DSV_STATUS_REG_AH_QVARDA 0x80
419 #define LSM6DSV_STATUS_REG_TDA 0x40
420 #define LSM6DSV_STATUS_REG_GDA 0x20
421 #define LSM6DSV_STATUS_REG_XLDA 0x10
423 // RESERVED - 1F
425 // Temperature data output register (R)
426 #define LSM6DSV_OUT_TEMP_L 0x20
427 #define LSM6DSV_OUT_TEMP_H 0x21
429 // Angular rate sensor pitch axis (X) angular rate output register (R)
430 #define LSM6DSV_OUTX_L_G 0x22
431 #define LSM6DSV_OUTX_H_G 0x23
433 // Angular rate sensor roll axis (Y) angular rate output register (R)
434 #define LSM6DSV_OUTY_L_G 0x24
435 #define LSM6DSV_OUTY_H_G 0x25
437 // Angular rate sensor yaw axis (Z) angular rate output register (R)
438 #define LSM6DSV_OUTZ_L_G 0x26
439 #define LSM6DSV_OUTZ_H_G 0x27
441 // Linear acceleration sensor X-axis output register (R)
442 #define LSM6DSV_OUTX_L_A 0x28
443 #define LSM6DSV_OUTX_H_A 0x29
445 // Linear acceleration sensor Y-axis output register (R)
446 #define LSM6DSV_OUTY_L_A 0x2A
447 #define LSM6DSV_OUTY_H_A 0x2B
449 // Linear acceleration sensor Z-axis output register (R)
450 #define LSM6DSV_OUTZ_L_A 0x2C
451 #define LSM6DSV_OUTZ_H_A 0x2D
453 // Angular rate sensor pitch axis (X) angular rate output register (R)
454 #define LSM6DSV_UI_OUTX_L_G_OIS_EIS 0x2E
455 #define LSM6DSV_UI_OUTX_H_G_OIS_EIS 0x2F
457 // Angular rate sensor roll axis (Y) angular rate output register (R)
458 #define LSM6DSV_UI_OUTY_L_G_OIS_EIS 0x30
459 #define LSM6DSV_UI_OUTY_H_G_OIS_EIS 0x31
461 // Angular rate sensor yaw axis (Z) angular rate output register (R)
462 #define LSM6DSV_UI_OUTZ_L_G_OIS_EIS 0x32
463 #define LSM6DSV_UI_OUTZ_H_G_OIS_EIS 0x33
465 // Linear acceleration sensor X-axis output register (R)
466 #define UI_OUTX_L_A_OIS_DualC 0x34
467 #define UI_OUTX_H_A_OIS_DualC 0x35
469 // Linear acceleration sensor Y-axis output register (R)
470 #define UI_OUTY_L_A_OIS_DualC 0x36
471 #define UI_OUTY_H_A_OIS_DualC 0x37
473 // Linear acceleration sensor Z-axis output register (R)
474 #define UI_OUTZ_L_A_OIS_DualC 0x38
475 #define UI_OUTZ_H_A_OIS_DualC 0x39
477 // Analog hub and Qvar data output register (R)
478 #define LSM6DSV_AH_QVAR_OUT_L 0x3A
479 #define LSM6DSV_AH_QVAR_OUT_H 0x3B
481 // RESERVED - 3C-3F
483 // Timestamp first data output register (R)
484 #define LSM6DSV_TIMESTAMP0 0x40
485 #define LSM6DSV_TIMESTAMP1 0x41
486 #define LSM6DSV_TIMESTAMP2 0x42
487 #define LSM6DSV_TIMESTAMP3 0x43
489 // Status regsiter
490 #define LSM6DSV_UI_STATUS_REG_OIS 0x44
491 #define LSM6DSV_UI_STATUS_REG_OIS_GYRO_SETTLING 0x04
492 #define LSM6DSV_UI_STATUS_REG_OIS_GDA_OIS 0x02
493 #define LSM6DSV_UI_STATUS_REG_OIS_XLDA_OIS 0x01
495 // Wake-up interrupt source register (R)
496 #define LSM6DSV_WAKE_UP_SRC 0x45
497 #define LSM6DSV_WAKE_UP_SRC_SLEEP_CHANGE_IA 0x40
498 #define LSM6DSV_WAKE_UP_SRC_FF_IA 0x20
499 #define LSM6DSV_WAKE_UP_SRC_SLEEP_STATE 0x10
500 #define LSM6DSV_WAKE_UP_SRC_WU_IA 0x08
501 #define LSM6DSV_WAKE_UP_SRC_X_WU 0x04
502 #define LSM6DSV_WAKE_UP_SRC_Y_WU 0x02
503 #define LSM6DSV_WAKE_UP_SRC_Z_WU 0x01
505 //Tap source register (R)
506 #define LSM6DSV_TAP_SRC 0x46
507 #define LSM6DSV_TAP_SRC_TAP_IA 0x40
508 #define LSM6DSV_TAP_SRC_SINGLE_TAP 0x20
509 #define LSM6DSV_TAP_SRC_DOUBLE_TAP 0x10
510 #define LSM6DSV_TAP_SRC_TAP_SIGN 0x08
511 #define LSM6DSV_TAP_SRC_X_TAP 0x04
512 #define LSM6DSV_TAP_SRC_Y_TAP 0x02
513 #define LSM6DSV_TAP_SRC_Z_TAP 0x01
515 // Portrait, landscape, face-up and face-down source register (R)
516 #define LSM6DSV_D6D_SRC 0x47
517 #define LSM6DSV_D6D_SRC_D6D_IA 0x40
518 #define LSM6DSV_D6D_SRC_ZH 0x20
519 #define LSM6DSV_D6D_SRC_ZL 0x10
520 #define LSM6DSV_D6D_SRC_YH 0x08
521 #define LSM6DSV_D6D_SRC_YL 0x04
522 #define LSM6DSV_D6D_SRC_XH 0x02
523 #define LSM6DSV_D6D_SRC_XL 0x01
525 // Sensor hub source register (R)
526 #define LSM6DSV_STATUS_MASTER_MAINPAGE 0x48
527 #define LSM6DSV_STATUS_MASTER_MAINPAGE_WR_ONCE_DONE 0x80
528 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE3_NACK 0x40
529 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE2_NACK 0x20
530 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE1_NACK 0x10
531 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SLAVE0_NACK 0x08
532 #define LSM6DSV_STATUS_MASTER_MAINPAGE_SENS_HUB_ENDOP 0x01
534 // Embedded function status register (R)
535 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE 0x49
536 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_FSM_LC 0x80
537 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_SIGMOT 0x20
538 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_TILT 0x10
539 #define LSM6DSV_EMB_FUNC_STATUS_MAINPAGE_IS_STEP_DET 0x08
541 // Finite state machine status register (R)
542 #define LSM6DSV_FSM_STATUS_MAINPAGE 0x4A
543 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM8 0x80
544 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM7 0x40
545 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM6 0x20
546 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM5 0x10
547 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM4 0x08
548 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM3 0x04
549 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM2 0x02
550 #define LSM6DSV_FSM_STATUS_MAINPAGE_IS_FSM1 0x01
552 // Embedded function status register (R)
553 #define LSM6DSV_MLC_STATUS_MAINPAGE 0x4B
554 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC4 0x08
555 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC3 0x04
556 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC2 0x02
557 #define LSM6DSV_MLC_STATUS_MAINPAGE_IS_MLC1 0x01
559 // RESERVED - 4C-4E
561 // Internal frequency register (R)
562 #define LSM6DSV_INTERNAL_FREQ_FINE 0x4F
564 // Enable interrupt functions register (R/W)
565 #define LSM6DSV_FUNCTIONS_ENABLE 0x50
566 #define LSM6DSV_FUNCTIONS_ENABLE_INTERRUPTS_ENABLE 0x80
567 #define LSM6DSV_FUNCTIONS_ENABLE_TIMESTAMP_EN 0x40
568 #define LSM6DSV_FUNCTIONS_ENABLE_DIS_RST_LIR_ALL_INT 0x08
569 #define LSM6DSV_FUNCTIONS_ENABLE_INACT_EN_MASK 0x03
570 #define LSM6DSV_FUNCTIONS_ENABLE_INACT_EN_SHIFT 0
572 // DEN configuration register (R/W)
573 #define LSM6DSV_DEN 0x51
574 #define LSM6DSV_DEN_LVL1_EN 0x40
575 #define LSM6DSV_DEN_LVL2_EN 0x20
576 #define LSM6DSV_DEN_DEN_XL_EN 0x10
577 #define LSM6DSV_DEN_DEN_X 0x08
578 #define LSM6DSV_DEN_DEN_Y 0x04
579 #define LSM6DSV_DEN_DEN_Z 0x02
580 #define LSM6DSV_DEN_DEN_XL_G 0x01
582 // Activity/inactivity configuration register (R/W)
583 #define LSM6DSV_INACTIVITY_DUR 0x54
584 #define LSM6DSV_INACTIVITY_DUR_SLEEP_STATUS_ON_INT 0x80
585 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_MASK 0x70
586 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_SHIFT 4
587 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_7_8125MG_LSB 0
588 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_15_625MG_LSB 1
589 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_31_25MG_LSB 2
590 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_62_5MG_LSB 3
591 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_125MG_LSB 4
592 #define LSM6DSV_INACTIVITY_DUR_WU_INACT_THS_W_250MG_LSB 5
593 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_MASK 0x0c
594 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_SHIFT 2
595 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_1_875HZ 0
596 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_15HZ 1
597 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_30HZ 2
598 #define LSM6DSV_INACTIVITY_DUR_XL_INACT_ODR_60HZ 3
599 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_MASK 0x03
600 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_SHIFT 0
601 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_1 0
602 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_2 1
603 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_3 2
604 #define LSM6DSV_INACTIVITY_DUR_INACT_DUR_4 3
606 // Activity/inactivity threshold setting register (R/W)
607 #define LSM6DSV_INACTIVITY_THS 0x55
608 #define LSM6DSV_INACTIVITY_THS_MASK 0x3f
610 // Tap configuration register 0 (R/W)
611 #define LSM6DSV_TAP_CFG0 0x56
612 #define LSM6DSV_TAP_CFG0_LOW_PASS_ON_6D 0x40
613 #define LSM6DSV_TAP_CFG0_HW_FUNC_MASK_XL_SETTL 0x20
614 #define LSM6DSV_TAP_CFG0_SLOPE_FDS 0x10
615 #define LSM6DSV_TAP_CFG0_TAP_X_EN 0x08
616 #define LSM6DSV_TAP_CFG0_TAP_Y_EN 0x04
617 #define LSM6DSV_TAP_CFG0_TAP_Z_EN 0x02
618 #define LSM6DSV_TAP_CFG0_LIR 0x01
620 // Tap configuration register 1 (R/W)
621 #define LSM6DSV_TAP_CFG1 0x57
622 #define LSM6DSV_TAP_CFG1_TAP_PRIORITY_MASK 0xe0
623 #define LSM6DSV_TAP_CFG1_TAP_PRIORITY_SHIFT 5
624 #define LSM6DSV_TAP_CFG1_TAP_THS_X_MASK 0x1f
625 #define LSM6DSV_TAP_CFG1_TAP_THS_X_SHIFT 0
627 // Tap configuration register 2 (R/W)
628 #define LSM6DSV_TAP_CFG2 0x58
629 #define LSM6DSV_TAP_CFG2_TAP_THS_X_MASK 0x1f
630 #define LSM6DSV_TAP_CFG2_TAP_THS_X_SHIFT 0
632 // Portrait/landscape position and tap function threshold register (R/W)
633 #define LSM6DSV_TAP_THS_6D 0x59
634 #define LSM6DSV_TAP_THS_6D_D4D_EN 0x80
635 #define LSM6DSV_TAP_THS_6D_SIXD_THS_MASK 0x60
636 #define LSM6DSV_TAP_THS_6D_SIXD_THS_SHIFT 5
637 #define LSM6DSV_TAP_THS_6D_TAP_THS_Z_MASK 0x1f
638 #define LSM6DSV_TAP_THS_6D_TAP_THS_Z_SHIFT 0
640 // Tap recognition function setting register (R/W)
641 #define LSM6DSV_TAP_DUR 0x5A
642 #define LSM6DSV_TAP_DUR_DUR_MASK 0xf0
643 #define LSM6DSV_TAP_DUR_DUR_SHIFT 4
644 #define LSM6DSV_TAP_DUR_QUIET_MASK 0x0c
645 #define LSM6DSV_TAP_DUR_QUIET_SHIFT 2
646 #define LSM6DSV_TAP_DUR_SHOCK_MASK 0x03
647 #define LSM6DSV_TAP_DUR_SHOCK_SHIFT 0
649 // Single/double-tap selection and wake-up configuration (R/W)
650 #define LSM6DSV_WAKE_UP_THS 0x5B
651 #define LSM6DSV_WAKE_UP_THS_SINGLE_DOUBLE_TAP 0x80
652 #define LSM6DSV_WAKE_UP_THS_USR_OFF_ON_WU 0x40
653 #define LSM6DSV_WAKE_UP_THS_WK_THS_MASK 0x3f
654 #define LSM6DSV_WAKE_UP_THS_WK_THS_SHIFT 6
656 // Free-fall, wake-up, and sleep mode functions duration setting register (R/W)
657 #define LSM6DSV_WAKE_UP_DUR 0x5C
658 #define LSM6DSV_WAKE_UP_DUR_FF_DUR_5 0x80
659 #define LSM6DSV_WAKE_UP_DUR_WAKE_DUR_MASK 0x60
660 #define LSM6DSV_WAKE_UP_DUR_WAKE_DUR_SHIFT 5
661 #define LSM6DSV_WAKE_UP_DUR_SLEEP_DUR_MASK 0x0f
662 #define LSM6DSV_WAKE_UP_DUR_SLEEP_DUR_SHIFT 0
664 // Free-fall function duration setting register (R/W)
665 #define LSM6DSV_FREE_FALL 0x5D
666 #define LSM6DSV_FREE_FALL_FF_DUR_MASK 0xf8
667 #define LSM6DSV_FREE_FALL_FF_DUR_SHIFT 3
668 #define LSM6DSV_FREE_FALL_FF_THS_MASK 0x07
669 #define LSM6DSV_FREE_FALL_FF_THS_SHIFT 0
671 // Functions routing to INT1 pin register (R/W)
672 #define LSM6DSV_MD1_CFG 0x5E
673 #define LSM6DSV_MD1_CFG_INT1_SLEEP_CHANG 0x80
674 #define LSM6DSV_MD1_CFG_INT1_SINGLE_TAP 0x40
675 #define LSM6DSV_MD1_CFG_INT1_WU 0x20
676 #define LSM6DSV_MD1_CFG_INT1_FF 0x10
677 #define LSM6DSV_MD1_CFG_INT1_DOUBLE_TAP 0x08
678 #define LSM6DSV_MD1_CFG_INT1_6D 0x04
679 #define LSM6DSV_MD1_CFG_INT1_EMB_FUNC 0x02
680 #define LSM6DSV_MD1_CFG_INT1_SHUB 0x01
682 // Functions routing to INT2 pin register (R/W)
683 #define LSM6DSV_MD2_CFG 0x5F
684 #define LSM6DSV_MD2_CFG_INT2_SLEEP_CHANG 0x80
685 #define LSM6DSV_MD2_CFG_INT2_SINGLE_TAP 0x40
686 #define LSM6DSV_MD2_CFG_INT2_WU 0x20
687 #define LSM6DSV_MD2_CFG_INT2_FF 0x10
688 #define LSM6DSV_MD2_CFG_INT2_DOUBLE_TAP 0x08
689 #define LSM6DSV_MD2_CFG_INT2_6D 0x04
690 #define LSM6DSV_MD2_CFG_INT2_EMB_FUNC 0x02
691 #define LSM6DSV_MD2_CFG_INT2_TIMESTAMP 0x01
693 // RESERVED - 60-61
695 // HAODR data rate configuration register (R/W)
696 #define LSM6DSV_HAODR_CFG 0x62
697 #define LSM6DSV_HAODR_CFG_HAODR_SEL_MASK 0x03
698 #define LSM6DSV_HAODR_CFG_HAODR_SEL_SHIFT 0
699 #define LSM6DSV_HAODR_MODE0 0
700 #define LSM6DSV_HAODR_MODE1 1
701 #define LSM6DSV_HAODR_MODE2 2
703 // Embedded functions configuration register (R/W)
704 #define LSM6DSV_EMB_FUNC_CFG 0x63
705 #define LSM6DSV_EMB_FUNC_CFG_XL_DUALC_BATCH_FROM_IF 0x80
706 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_IRQ_MASK_G_SETTL 0x20
707 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_IRQ_MASK_XL_SETTL 0x10
708 #define LSM6DSV_EMB_FUNC_CFG_EMB_FUNC_DISABLE 0x08
710 // Control register (UI side) for UI / SPI2 shared registers (R/W)
711 #define LSM6DSV_UI_HANDSHAKE_CTRL 0x64
712 #define LSM6DSV_UI_HANDSHAKE_CTRL_UI_SHARED_ACK 0x02
713 #define LSM6DSV_UI_HANDSHAKE_CTRL_UI_SHARED_REQ 0x01
715 // UI / SPI2 shared register 0 (R/W)
716 #define LSM6DSV_UI_SPI2_SHARED_0 0x65
718 // UI / SPI2 shared register 1 (R/W)
719 #define LSM6DSV_UI_SPI2_SHARED_1 0x66
721 // UI / SPI2 shared register 2 (R/W)
722 #define LSM6DSV_UI_SPI2_SHARED_2 0x67
724 // UI / SPI2 shared register 3 (R/W)
725 #define LSM6DSV_UI_SPI2_SHARED_3 0x68
727 // UI / SPI2 shared register 4 (R/W)
728 #define LSM6DSV_UI_SPI2_SHARED_4 0x69
730 // UI / SPI2 shared register 5 (R/W)
731 #define LSM6DSV_UI_SPI2_SHARED_5 0x6A
733 // Gyroscope EIS channel control register (R/W)
734 #define LSM6DSV_CTRL_EIS 0x6B
735 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_MASK 0xc0
736 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_SHIFT 6
737 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_OFF 0
738 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_1920HZ 1
739 #define LSM6DSV_CTRL_EIS_ODR_G_EIS_960HZ 2
740 #define LSM6DSV_CTRL_EIS_LPF_G_EIS_BW 0x10
741 #define LSM6DSV_CTRL_EIS_G_EIS_ON_G_OIS_OUT_REG 0x08
742 #define LSM6DSV_CTRL_EIS_FS_G_EIS_MASK 0x07
743 #define LSM6DSV_CTRL_EIS_FS_G_EIS_SHIFT 0
744 #define LSM6DSV_CTRL_EIS_FS_G_EIS_125DPS 0
745 #define LSM6DSV_CTRL_EIS_FS_G_EIS_250DPS 1
746 #define LSM6DSV_CTRL_EIS_FS_G_EIS_500DPS 2
747 #define LSM6DSV_CTRL_EIS_FS_G_EIS_1000DPS 3
748 #define LSM6DSV_CTRL_EIS_FS_G_EIS_2000DPS 4
750 // RESERVED - 6C - 6E
752 // OIS interrupt configuration register (R/W)
753 #define LSM6DSV_UI_INT_OIS 0x6F
754 #define LSM6DSV_UI_INT_OIS_INT2_DRDY_OIS 0x80
755 #define LSM6DSV_UI_INT_OIS_DRDY_MASK_OIS 0x40
756 #define LSM6DSV_UI_INT_OIS_ST_OIS_CLAMPDIS 0x10
758 // OIS configuration register (R/W)
759 #define LSM6DSV_UI_CTRL1_OIS 0x70
760 #define LSM6DSV_UI_CTRL1_OIS_SIM_OIS 0x20
761 #define LSM6DSV_UI_CTRL1_OIS_OIS_XL_EN 0x04
762 #define LSM6DSV_UI_CTRL1_OIS_OIS_G_EN 0x02
763 #define LSM6DSV_UI_CTRL1_OIS_SPI2_READ_EN 0x01
765 // OIS configuration register (R/W)
766 #define LSM6DSV_UI_CTRL2_OIS 0x71
767 #define LSM6DSV_UI_CTRL2_OIS_LPF1_G_OIS_BW_MASK 0x18
768 #define LSM6DSV_UI_CTRL2_OIS_LPF1_G_OIS_BW_SHIFT 3
769 #define LSM6DSV_UI_CTRL2_OIS_FS_G_OIS_MASK 0x07
770 #define LSM6DSV_UI_CTRL2_OIS_FS_G_OIS_SHIFT 0
771 #define LSM6DSV_UI_CTRL2_FS_G_EIS_125DPS 0
772 #define LSM6DSV_UI_CTRL2_FS_G_EIS_250DPS 1
773 #define LSM6DSV_UI_CTRL2_FS_G_EIS_500DPS 2
774 #define LSM6DSV_UI_CTRL2_FS_G_EIS_1000DPS 3
775 #define LSM6DSV_UI_CTRL2_FS_G_EIS_2000DPS 4
777 // OIS configuration register (R/W)
778 #define LSM6DSV_UI_CTRL3_OIS 0x72
779 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_MASK 0x38
780 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_SHIFT 3
781 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_2G 0
782 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_4G 1
783 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_8G 2
784 #define LSM6DSV_UI_CTRL3_OIS_LPF_XL_OIS_BW_16G 3
785 #define LSM6DSV_UI_CTRL3_OIS_FS_XL_OIS_MASK 0x03
786 #define LSM6DSV_UI_CTRL3_OIS_FS_XL_OIS_SHIFT 0
788 // Accelerometer X-axis user offset correction (R/W)
789 #define LSM6DSV_X_OFS_USR 0x73
791 // Accelerometer Y-axis user offset correction (R/W)
792 #define LSM6DSV_Y_OFS_USR 0x74
794 // Accelerometer Z-axis user offset correction (R/W)
795 #define LSM6DSV_Z_OFS_USR 0x75
797 // RESERVED - 76-77
799 // FIFO tag register (R)
800 #define LSM6DSV_FIFO_DATA_OUT_TAG 0x78
801 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_MASK 0xf8
802 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_SHIFT 3
803 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_EMPTY 0x00
804 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC 0x01
805 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC 0x02
806 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_TEMP 0x03
807 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_TIMESTAMP 0x04
808 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_CFG_CHANGE 0x05
809 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC_T_2 0x06
810 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_NC_T_1 0x07
811 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_2XC 0x08
812 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_3XC 0x09
813 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC_T_2 0x0a
814 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_NC_T_1 0x0b
815 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_2XC 0x0c
816 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_GYRO_3XC 0x0d
817 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_0 0x0e
818 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_1 0x0f
819 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_2 0x10
820 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_SLAVE_3 0x11
821 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_STEP_COUNT 0x12
822 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GAME_ROT_VEC 0x13
823 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GYRO_BIAS 0x16
824 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SFLP_GRAVITY_VEC 0x17
825 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_SENSOR_HUB_NACK 0x19
826 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_RESULT 0x1a
827 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_FILTER 0x1b
828 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_MLC_FEATURE 0x1c
829 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ACC_DUALC 0x1d
830 #define LSM6DSV_FIFO_DATA_OUT_TAG_SENSOR_FIFO_ENHANCED_EIS_GYRO 0x1e
831 #define LSM6DSV_FIFO_DATA_OUT_TAG_CNT_MASK 0x07
832 #define LSM6DSV_FIFO_DATA_OUT_TAG_CNT_SHIFT 0
834 // FIFO data output X (R)
835 #define LSM6DSV_FIFO_DATA_OUT_X_L 0x79
836 #define LSM6DSV_FIFO_DATA_OUT_X_H 0x7A
838 // FIFO data output Y (R)
839 #define LSM6DSV_FIFO_DATA_OUT_Y_L 0x7B
840 #define LSM6DSV_FIFO_DATA_OUT_Y_H 0x7C
842 // FIFO data output Z (R)
843 #define LSM6DSV_FIFO_DATA_OUT_Z_L 0x7D
844 #define LSM6DSV_FIFO_DATA_OUT_Z_H 0x7E
847 uint8_t lsm6dsv16xSpiDetect(const extDevice_t *dev)
849 const uint8_t whoAmI = spiReadRegMsk(dev, LSM6DSV_WHO_AM_I);
851 if (whoAmI != LSM6DSV16X_WHO_AM_I_CONST) {
852 return MPU_NONE;
855 return LSM6DSV16X_SPI;
858 void lsm6dsv16xAccInit(accDev_t *acc)
860 const extDevice_t *dev = &acc->gyro->dev;
862 // Enable the accelerometer in high accuracy mode at 1kHz
863 spiWriteReg(dev, LSM6DSV_CTRL1,
864 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL1_OP_MODE_XL_HIGH_ACCURACY,
865 LSM6DSV_CTRL1_OP_MODE_XL_MASK,
866 LSM6DSV_CTRL1_OP_MODE_XL_SHIFT) |
867 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL1_ODR_XL_1000HZ,
868 LSM6DSV_CTRL1_ODR_XL_MASK,
869 LSM6DSV_CTRL1_ODR_XL_SHIFT));
871 // Enable 16G sensitivity
872 spiWriteReg(dev, LSM6DSV_CTRL8,
873 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL8_FS_XL_16G,
874 LSM6DSV_CTRL8_FS_XL_MASK,
875 LSM6DSV_CTRL8_FS_XL_SHIFT));
877 // ±16G mode
878 acc->acc_1G = 512 * 4;
881 static bool lsm6dsv16xAccReadSPI(accDev_t *acc)
883 switch (acc->gyro->gyroModeSPI) {
884 case GYRO_EXTI_INT:
885 case GYRO_EXTI_NO_INT:
887 acc->gyro->dev.txBuf[0] = LSM6DSV_OUTX_L_A | 0x80;
889 busSegment_t segments[] = {
890 {.u.buffers = {NULL, NULL}, 7, true, NULL},
891 {.u.link = {NULL, NULL}, 0, true, NULL},
893 segments[0].u.buffers.txData = acc->gyro->dev.txBuf;
894 segments[0].u.buffers.rxData = &acc->gyro->dev.rxBuf[1];
896 spiSequence(&acc->gyro->dev, &segments[0]);
898 // Wait for completion
899 spiWait(&acc->gyro->dev);
901 int16_t *accData = (int16_t *)acc->gyro->dev.rxBuf;
903 acc->ADCRaw[X] = accData[1];
904 acc->ADCRaw[Y] = accData[2];
905 acc->ADCRaw[Z] = accData[3];
906 break;
909 case GYRO_EXTI_INT_DMA:
911 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
912 // up an old value.
914 // This data was read from the gyro, which is the same SPI device as the acc
915 int16_t *accData = (int16_t *)acc->gyro->dev.rxBuf;
917 acc->ADCRaw[X] = accData[4];
918 acc->ADCRaw[Y] = accData[5];
919 acc->ADCRaw[Z] = accData[6];
920 break;
923 case GYRO_EXTI_INIT:
924 default:
925 break;
928 return true;
931 bool lsm6dsv16xSpiAccDetect(accDev_t *acc)
933 if (acc->mpuDetectionResult.sensor != LSM6DSV16X_SPI) {
934 return false;
937 acc->initFn = lsm6dsv16xAccInit;
938 acc->readFn = lsm6dsv16xAccReadSPI;
940 return true;
943 void lsm6dsv16xGyroInit(gyroDev_t *gyro)
945 const extDevice_t *dev = &gyro->dev;
947 spiSetClkDivisor(dev, spiCalculateDivider(LSM6DSV16X_MAX_SPI_CLK_HZ));
949 // Perform a software reset
950 spiWriteReg(dev, LSM6DSV_CTRL3, LSM6DSV_CTRL3_SW_RESET);
952 // Select high-accuracy ODR mode 1 before leaving power-off mode
953 spiWriteReg(dev, LSM6DSV_HAODR_CFG,
954 LSM6DSV_ENCODE_BITS(LSM6DSV_HAODR_MODE1,
955 LSM6DSV_HAODR_CFG_HAODR_SEL_MASK,
956 LSM6DSV_HAODR_CFG_HAODR_SEL_SHIFT));
958 // Enable the gyro in high accuracy mode at 8kHz
959 spiWriteReg(dev, LSM6DSV_CTRL2,
960 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL2_OP_MODE_G_HIGH_ACCURACY,
961 LSM6DSV_CTRL2_OP_MODE_G_MASK,
962 LSM6DSV_CTRL2_OP_MODE_G_SHIFT) |
963 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL2_ODR_G_8000HZ,
964 LSM6DSV_CTRL2_ODR_G_MASK,
965 LSM6DSV_CTRL2_ODR_G_SHIFT));
967 // Enable 2000 deg/s sensitivity
968 spiWriteReg(dev, LSM6DSV_CTRL6,
969 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL6_FS_G_BW_407HZ,
970 LSM6DSV_CTRL6_LPF1_G_BW_MASK,
971 LSM6DSV_CTRL6_LPF1_G_BW_SHIFT) |
972 LSM6DSV_ENCODE_BITS(LSM6DSV_CTRL6_FS_G_2000DPS,
973 LSM6DSV_CTRL6_FS_G_MASK,
974 LSM6DSV_CTRL6_FS_G_SHIFT));
976 // Autoincrement register address when doing block SPI reads and update continuously
977 spiWriteReg(dev, LSM6DSV_CTRL3, LSM6DSV_CTRL3_IF_INC);
979 // Generate pulse on interrupt line, not requiring a read to clear
980 // TODO this pulse lasts 66us followed by a low of 66us, so we get 132us cycle time, not 125us
981 spiWriteReg(dev, LSM6DSV_CTRL4, LSM6DSV_CTRL4_DRDY_PULSED);
983 // From section 4.1, Mechanical characteristics, of the datasheet, G_So is 70mdps/LSB for FS = ±2000 dps.
984 gyro->scale = 0.070f;
986 // Enable the INT1 output to interrupt when new gyro data is ready
987 spiWriteReg(dev, LSM6DSV_INT1_CTRL, LSM6DSV_INT1_CTRL_INT1_DRDY_G);
989 mpuGyroInit(gyro);
992 bool lsm6dsv16xGyroReadSPI(gyroDev_t *gyro)
994 int16_t *gyroData = (int16_t *)gyro->dev.rxBuf;
995 switch (gyro->gyroModeSPI) {
996 case GYRO_EXTI_INIT:
998 // Initialise the tx buffer to all 0xff
999 memset(gyro->dev.txBuf, 0xff, 16);
1001 // Check that minimum number of interrupts have been detected
1003 // We need some offset from the gyro interrupts to ensure sampling after the interrupt
1004 gyro->gyroDmaMaxDuration = 5;
1005 if (gyro->detectedEXTI > GYRO_EXTI_DETECT_THRESHOLD) {
1006 if (spiUseDMA(&gyro->dev)) {
1007 gyro->dev.callbackArg = (uint32_t)gyro;
1008 gyro->dev.txBuf[0] = LSM6DSV_OUTX_L_G | 0x80;
1009 // Read three words of gyro data immediately followed by three bytes of acc data
1010 gyro->segments[0].len = sizeof(uint8_t) + 6 * sizeof(int16_t);
1011 gyro->segments[0].callback = mpuIntCallback;
1012 gyro->segments[0].u.buffers.txData = gyro->dev.txBuf;
1013 gyro->segments[0].u.buffers.rxData = &gyro->dev.rxBuf[1];
1014 gyro->segments[0].negateCS = true;
1015 gyro->gyroModeSPI = GYRO_EXTI_INT_DMA;
1016 } else {
1017 // Interrupts are present, but no DMA
1018 gyro->gyroModeSPI = GYRO_EXTI_INT;
1020 } else {
1021 gyro->gyroModeSPI = GYRO_EXTI_NO_INT;
1023 break;
1026 case GYRO_EXTI_INT:
1027 case GYRO_EXTI_NO_INT:
1029 gyro->dev.txBuf[0] = gyro->gyroDataReg | 0x80;
1031 busSegment_t segments[] = {
1032 {.u.buffers = {NULL, NULL}, 7, true, NULL},
1033 {.u.link = {NULL, NULL}, 0, true, NULL},
1035 segments[0].u.buffers.txData = gyro->dev.txBuf;
1036 segments[0].u.buffers.rxData = &gyro->dev.rxBuf[1];
1038 spiSequence(&gyro->dev, &segments[0]);
1040 // Wait for completion
1041 spiWait(&gyro->dev);
1043 gyro->gyroADCRaw[X] = gyroData[1];
1044 gyro->gyroADCRaw[Y] = gyroData[2];
1045 gyro->gyroADCRaw[Z] = gyroData[3];
1046 break;
1049 case GYRO_EXTI_INT_DMA:
1051 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
1052 // up an old value.
1053 gyro->gyroADCRaw[X] = gyroData[1];
1054 gyro->gyroADCRaw[Y] = gyroData[2];
1055 gyro->gyroADCRaw[Z] = gyroData[3];
1056 break;
1059 default:
1060 break;
1063 return true;
1066 bool lsm6dsv16xSpiGyroDetect(gyroDev_t *gyro)
1068 if (gyro->mpuDetectionResult.sensor != LSM6DSV16X_SPI) {
1069 return false;
1072 gyro->initFn = lsm6dsv16xGyroInit;
1073 gyro->readFn = lsm6dsv16xGyroReadSPI;
1075 return true;
1077 #endif // USE_ACCGYRO_LSM6DSV16X