| eMD IIM4265x Driver API 1.0.0

Ixm42xxxDriver_HL.c
Go to the documentation of this file.
1 /*
2 * ________________________________________________________________________________________________________
3 * Copyright (c) 2017 InvenSense Inc. All rights reserved.
4 *
5 * This software, related documentation and any modifications thereto (collectively “Software”) is subject
6 * to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
7 * and other intellectual property rights laws.
8 *
9 * InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
10 * and any use, reproduction, disclosure or distribution of the Software without an express license agreement
11 * from InvenSense is strictly prohibited.
12 *
13 * EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
14 * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
16 * EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
17 * INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
18 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
19 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THE SOFTWARE.
21 * ________________________________________________________________________________________________________
22 */
23
24 #include "Invn/Drivers/Ixm42xxx/Ixm42xxxDefs.h"
25 #include "Invn/Drivers/Ixm42xxx/Ixm42xxxExtFunc.h"
26 #include "Invn/Drivers/Ixm42xxx/Ixm42xxxDriver_HL.h"
27 #include "Invn/Drivers/Ixm42xxx/Ixm42xxxTransport.h"
28 #include "Invn/Drivers/Ixm42xxx/Ixm42xxxVersion.h"
29
30 static int inv_ixm42xxx_configure_serial_interface(struct inv_ixm42xxx * s);
31 static int inv_ixm42xxx_init_hardware_from_ui(struct inv_ixm42xxx * s);
32 static int inv_ixm42xxx_is_wu_osc_active(struct inv_ixm42xxx * s);
33 static void inv_ixm42xxx_format_data(const uint8_t endian, const uint8_t *in, uint16_t *out);
34
35 int inv_ixm42xxx_set_reg_bank(struct inv_ixm42xxx * s, uint8_t bank)
36 {
37 return inv_ixm42xxx_write_reg(s, MPUREG_REG_BANK_SEL, 1, &bank);
38 }
39
40 int inv_ixm42xxx_init(struct inv_ixm42xxx * s, struct inv_ixm42xxx_serif * serif, void (*sensor_event_cb)(inv_ixm42xxx_sensor_event_t * event))
41 {
42 int status = 0;
43
44 memset(s, 0, sizeof(*s));
45
46 s->transport.serif = *serif;
47
48 /* Wait some time for ICM to be properly supplied */
49 inv_ixm42xxx_sleep_us(3000);
50
51 if((status |= inv_ixm42xxx_configure_serial_interface(s)) != 0 )
52 return status;
53
54 /* Register the callback to be executed each time inv_ixm42xxx_get_data_from_fifo extracts
55 * a packet from fifo or inv_ixm42xxx_get_data_from_registers read data
56 */
57 s->sensor_event_cb = sensor_event_cb;
58
59 /* initialize hardware */
60 status |= inv_ixm42xxx_init_hardware_from_ui(s);
61
62 /* First data are noisy after enabling sensor
63 * This variable keeps track of gyro start time. Set to UINT32_MAX at init
64 */
65 s->gyro_start_time_us = UINT32_MAX;
66 /* First data are noisy after enabling sensor
67 * This variable keeps track of accel start time. Set to UINT32_MAX at init
68 */
69 s->accel_start_time_us = UINT32_MAX;
70
71 /* Gyro power-off to power-on transition can cause ring down issue
72 * This variable keeps track of timestamp when gyro is power off. Set to UINT32_MAX at init
73 */
74 s->gyro_power_off_tmst = UINT32_MAX;
75
76 return status;
77 }
78
79 int inv_ixm42xxx_device_reset(struct inv_ixm42xxx * s)
80 {
81 int status = INV_ERROR_SUCCESS;
82 uint8_t data;
83 uint8_t intf_cfg4_reg, intf_cfg6_reg;
84
85 /* Set memory bank 1 */
86 status |= inv_ixm42xxx_set_reg_bank(s, 1);
87 /* save registers necessary to perform soft reset while still keeping communication link alive */
88 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG4_B1, 1, &intf_cfg4_reg); // AUX SPI and AP SPI fields
89 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &intf_cfg6_reg);
90 /* Set memory bank 0 */
91 status |= inv_ixm42xxx_set_reg_bank(s, 0);
92
93 /* Reset the internal registers and restores the default settings.
94 * The bit automatically clears to 0 once the reset is done.
95 * Since soft-reset will trigger OTP reload, SPI mode (bit4) does not need saving
96 */
97 data = IXM42XXX_DEVICE_CONFIG_RESET_EN;
98 status |= inv_ixm42xxx_write_reg(s, MPUREG_DEVICE_CONFIG, 1, &data);
99 if(status)
100 return status;
101
102 /* Wait 1000us for soft reset to be effective before trying to perform any further read */
103 inv_ixm42xxx_sleep_us(1000);
104
105 status |= inv_ixm42xxx_set_reg_bank(s, 1);
106 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG4_B1, 1, &intf_cfg4_reg);
107 status |= inv_ixm42xxx_set_reg_bank(s, 0);
108
109 /* Check the Int Reset Done bit */
110 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_STATUS, 1, &data);
111 if (0 == (data & BIT_INT_STATUS_RESET_DONE)) {
112 return INV_ERROR_UNEXPECTED;
113 }
114
115 /* Init transport layer */
116 inv_ixm42xxx_init_transport(s);
117
118 status |= inv_ixm42xxx_set_reg_bank(s, 1);
119 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &intf_cfg6_reg);
120 /* Configure FSYNC on INT2=pin 9 */
121 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG5_B1, 1, &data);
122 data &= (uint8_t)~BIT_INTF_CONFIG5_GPIO_PAD_SEL_MASK;
123 data |= (1 << BIT_INTF_CONFIG5_GPIO_PAD_SEL_POS);
124 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG5_B1, 1, &data);
125 status |= inv_ixm42xxx_set_reg_bank(s, 0);
126
127 /* Read and set endianess for further processing */
128 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG0, 1, &data);
129 s->endianess_data = data & BIT_DATA_ENDIAN_MASK;
130
131 if(s->transport.serif.serif_type == IXM42XXX_UI_I3C){
132 status |= s->transport.serif.configure((struct inv_ixm42xxx_serif *)s);
133 }
134
135 return status;
136 }
137
138 int inv_ixm42xxx_get_who_am_i(struct inv_ixm42xxx * s, uint8_t * who_am_i)
139 {
140 return inv_ixm42xxx_read_reg(s, MPUREG_WHO_AM_I, 1, who_am_i);
141 }
142
143 int inv_ixm42xxx_force_clock_source(struct inv_ixm42xxx * s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t clk_src)
144 {
145 int status = 0;
146 uint8_t data;
147 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
148 if(clk_src == IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC)
149 data &= (uint8_t)~BIT_ACCEL_LP_CLK_SEL_MASK;
150 else
151 data |= (uint8_t)IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC;
152
153 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
154
155 return status;
156 }
157
158 int inv_ixm42xxx_enable_accel_low_power_mode(struct inv_ixm42xxx * s)
159 {
160 int status = 0;
161 uint8_t data;
162 uint8_t pwr_mgmt0_reg;
163 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
164 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t accel_mode;
165 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyro_mode;
166 IXM42XXX_ACCEL_CONFIG0_ODR_t acc_odr_bitfield;
167 uint32_t accel_odr_us = 0;
168 uint8_t accel_cfg_0_reg;
169
170 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
171 accel_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mgmt0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
172 gyro_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t)(pwr_mgmt0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
173
174 /* Subroutines need to be followed when enabling or disabling sensor to ensure ODR regularity
175 * Check if the accelerometer is the only one enabled
176 */
177 if ((accel_mode != IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) &&
178 ((gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) || (gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY))){
179 /* Get accelerometer's ODR for next required wait */
180 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
181 acc_odr_bitfield = (IXM42XXX_ACCEL_CONFIG0_ODR_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_ODR_MASK);
182 accel_odr_us = inv_ixm42xxx_convert_odr_bitfield_to_us(acc_odr_bitfield);
183 // Select the RC OSC as clock source for the accelerometer
184 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC);
185 }
186
187 /* FIFO contains Gyro and Accel data if enabled on the OIS path
188 * Dynamically configure the FIFO to publish data only for sensors explicitely enabled on the UI path
189 */
190 if(accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF && gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) {
191 uint8_t data_endianess;
192 if(s->fifo_is_used) {
193 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
194 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_ACCEL_EN;
195 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_GYRO_EN;
196 if(s->fifo_highres_enabled)
197 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_HIRES_EN;
198 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
199 }
200
201 /* Read data endianess in order to process correctly data*/
202 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG0, 1, &data_endianess);
203 s->endianess_data = data_endianess & BIT_DATA_ENDIAN_MASK;
204 }
205 #endif
206
207 /* Restore filter averaging settings */
208 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
209 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK;
210 data |= s->avg_bw_setting.acc_lp_avg;
211 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
212
213 /* Enable/Switch the accelerometer in/to low power mode */
214 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
215 pwr_mgmt0_reg &= ~BIT_PWR_MGMT_0_ACCEL_MODE_MASK;
216 pwr_mgmt0_reg |= IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP;
217 status |= inv_ixm42xxx_write_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
218 inv_ixm42xxx_sleep_us(200);
219
220 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
221 /* Subroutines need to be followed when enabling or disabling sensor to ensure ODR regularity */
222 if ((accel_mode != IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) &&
223 ((gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) || (gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY))){
224 /* Wait one accelerometer ODR before switching to the WU OSC */
225 if (accel_odr_us > 200) /* if ODR is smaller than 200 us, we already waited for one ODR above */
226 inv_ixm42xxx_sleep_us(accel_odr_us - 200);
227 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC);
228 }
229
230 /* Accel Low Power could report with wrong ODR if internal counter for ODR changed overflowed */
231 if (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP != accel_mode) {
232 /* Check whether counter has overflowed */
233 if(s->wu_off_acc_odr_changes >= 8) {
234 IXM42XXX_ACCEL_CONFIG0_ODR_t cur_freq, new_freq;
235 /* Dummy transition to ODR valid for both ALN/ALP */
236 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
237 cur_freq = (IXM42XXX_ACCEL_CONFIG0_ODR_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_ODR_MASK);
238 new_freq = (cur_freq != IXM42XXX_ACCEL_CONFIG0_ODR_1_5625_HZ) ?
239 IXM42XXX_ACCEL_CONFIG0_ODR_1_5625_HZ : IXM42XXX_ACCEL_CONFIG0_ODR_3_125_HZ;
240 accel_cfg_0_reg &= (uint8_t)~BIT_ACCEL_CONFIG0_ODR_MASK;
241 accel_cfg_0_reg |= (uint8_t)new_freq;
242 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
243 inv_ixm42xxx_sleep_us(200);
244 accel_cfg_0_reg &= (uint8_t)~BIT_ACCEL_CONFIG0_ODR_MASK;
245 accel_cfg_0_reg |= (uint8_t)cur_freq;
246 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
247 }
248 }
249 /* Even though transition was a dummy and controller received two ODR updates,
250 * it was enabled. Therefore they were not missed, so it is safe to reset counter.
251 */
252 s->wu_off_acc_odr_changes = 0;
253
254 if (accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF) {
255 /* First data are noisy after enabling sensor
256 * Keeps track of the start time to discard first sample
257 */
258 if(s->fifo_is_used) {
259 s->accel_start_time_us = inv_ixm42xxx_get_time_us();
260 }
261 }
262 #endif
263
264 return status;
265 }
266
267 int inv_ixm42xxx_enable_accel_low_noise_mode(struct inv_ixm42xxx * s)
268 {
269 int status = 0;
270 uint8_t data;
271 uint8_t pwr_mgmt0_reg;
272 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
273 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t accel_mode;
274 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyro_mode;
275 IXM42XXX_ACCEL_CONFIG0_ODR_t acc_odr_bitfield;
276 uint32_t accel_odr_us;
277 uint8_t accel_cfg_0_reg;
278
279 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
280 accel_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mgmt0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
281 gyro_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t)(pwr_mgmt0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
282
283 /* Subroutines need to be followed when enabling or disabling sensor to ensure ODR regularity
284 * Check if the accelerometer is the only one enabled
285 */
286 if ((accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) &&
287 ((gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) || (gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY))){
288 /* Get accelerometer's ODR for next required wait */
289 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
290 acc_odr_bitfield = (IXM42XXX_ACCEL_CONFIG0_ODR_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_ODR_MASK);
291 accel_odr_us = inv_ixm42xxx_convert_odr_bitfield_to_us(acc_odr_bitfield);
292 /* Select the RC OSC as clock source for the accelerometer */
293 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC);
294 /* Wait one accel ODR before switching to low noise mode */
295 inv_ixm42xxx_sleep_us(accel_odr_us);
296 }
297
298 /* FIFO contains Gyro and Accel data if enabled on the OIS path
299 * Dynamically configure the FIFO to publish data only for sensors explicitely enabled on the UI path
300 */
301 if(accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF && gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) {
302 uint8_t data_endianess;
303
304 if(s->fifo_is_used) {
305 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
306 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_ACCEL_EN;
307 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_GYRO_EN;
308 if(s->fifo_highres_enabled)
309 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_HIRES_EN;
310 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
311 }
312 /* Read data endianess in order to process correctly data */
313 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG0, 1, &data_endianess);
314 s->endianess_data = data_endianess & BIT_DATA_ENDIAN_MASK;
315 }
316 #endif
317
318 /* Restore filter BW settings */
319 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
320 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK;
321 data |= s->avg_bw_setting.acc_ln_bw;
322 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
323
324 /* Enable/Switch the accelerometer in/to low noise mode */
325 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
326 pwr_mgmt0_reg &= (uint8_t)~BIT_PWR_MGMT_0_ACCEL_MODE_MASK;
327 pwr_mgmt0_reg |= (uint8_t)IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LN;
328 status |= inv_ixm42xxx_write_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mgmt0_reg);
329 inv_ixm42xxx_sleep_us(200);
330
331 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
332 if (accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF) {
333 /* First data are noisy after enabling sensor
334 * Keeps track of the start time to discard first sample
335 */
336 if(s->fifo_is_used) {
337 s->accel_start_time_us = inv_ixm42xxx_get_time_us();
338 }
339 }
340 #endif
341
342 return status;
343 }
344
345 int inv_ixm42xxx_disable_accel(struct inv_ixm42xxx * s)
346 {
347 int status=0;
348 uint8_t pwr_mngt_0_reg;
349
350 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
351 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyro_mode;
352 int stop_fifo_usage = 0;
353 uint8_t data;
354 #endif
355
356 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
357
358 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
359 gyro_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
360 if((gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) && s->fifo_is_used) {
361 /* First FSYNC event after enable is irrelevant */
362 s->fsync_to_be_ignored = 1;
363 /* FIFO contains Gyro and Accel data if enabled on the OIS path
364 * Dynamically configure the FIFO to publish data only for sensors explicitely enabled on the UI path
365 */
366 stop_fifo_usage = 1;
367 }
368 #endif
369
370 pwr_mngt_0_reg &= (uint8_t)~BIT_PWR_MGMT_0_ACCEL_MODE_MASK;
371 pwr_mngt_0_reg |= (uint8_t) IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF;
372 status = inv_ixm42xxx_write_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
373
374 /* Restore POR clock source for the accelerometer */
375 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC);
376
377 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
378 if(stop_fifo_usage && s->fifo_is_used) {
379 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
380 data &= (uint8_t)~(BIT_FIFO_CONFIG1_ACCEL_MASK | BIT_FIFO_CONFIG1_GYRO_MASK | BIT_FIFO_CONFIG1_HIRES_MASK);
381 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
382
383 /* Reset FIFO explicitely so the new configuration is taken into account */
384 status |= inv_ixm42xxx_reset_fifo(s);
385 }
386 #endif
387
388 return status;
389 }
390
391 int inv_ixm42xxx_enable_gyro_low_noise_mode(struct inv_ixm42xxx * s)
392 {
393 int status = 0;
394 uint8_t data;
395 uint8_t pwr_mngt_0_reg;
396 uint64_t current_time;
397
398 /* Powering the gyroscope on immediately after powering it off can result in device failure.
399 * The gyroscope proof mass can continue vibrating after it has been powered off,
400 * and powering it back on immediately can result in unpredictable proof mass movement.
401 * After powering the gyroscope off, a period of > 150ms should be allowed to elapse before it is powered back on. */
402 if (s->gyro_power_off_tmst != UINT32_MAX) {
403 current_time = inv_ixm42xxx_get_time_us();
404 /* Handle rollover */
405 if (current_time <= s->gyro_power_off_tmst)
406 current_time += UINT32_MAX;
407 /* If 150 ms are not elapsed since power-off error is returned */
408 if ((current_time - s->gyro_power_off_tmst) <= (150 * 1000))
409 return INV_ERROR_HW;
410 }
411
412 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
413 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyro_mode;
414 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t accel_mode;
415 IXM42XXX_ACCEL_CONFIG0_ODR_t acc_odr_bitfield;
416 uint32_t accel_odr_us;
417 uint8_t accel_cfg_0_reg;
418
419 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
420 gyro_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
421 accel_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
422
423 /* Subroutines need to be followed when enabling or disabling sensor to ensure ODR regularity
424 * Check if the accelerometer is the only one enabled
425 */
426 if ((accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) &&
427 ((gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) || (gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY))) {
428 /* Get accelerometer's ODR for next required wait */
429 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
430 acc_odr_bitfield = (IXM42XXX_ACCEL_CONFIG0_ODR_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_ODR_MASK);
431 accel_odr_us = inv_ixm42xxx_convert_odr_bitfield_to_us(acc_odr_bitfield);
432 /* Select the RC OSC as clock source for the accelerometer */
433 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC);
434 /* Wait one accel ODR before enabling the gyroscope */
435 inv_ixm42xxx_sleep_us(accel_odr_us);
436 }
437
438 /* FIFO contains Gyro and Accel data if enabled on the OIS path
439 * Dynamically configure the FIFO to publish data only for sensors explicitely enabled on the UI path
440 */
441 if(accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF && gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) {
442 uint8_t data_endianess;
443
444 if(s->fifo_is_used) {
445 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
446 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_ACCEL_EN;
447 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_GYRO_EN;
448 if(s->fifo_highres_enabled)
449 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_HIRES_EN;
450 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
451 }
452 /* Read data endianess in order to process correctly data */
453 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG0, 1, &data_endianess);
454 s->endianess_data = data_endianess & BIT_DATA_ENDIAN_MASK;
455 }
456 #endif
457
458 /* Restore filter BW settings */
459 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
460 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_GYRO_FILT_MASK;
461 data |= s->avg_bw_setting.gyr_ln_bw;
462 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
463
464 /* Enable/Switch the gyroscope in/to low noise mode */
465 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
466 pwr_mngt_0_reg &= (uint8_t)~BIT_PWR_MGMT_0_GYRO_MODE_MASK;
467 pwr_mngt_0_reg |= (uint8_t)IXM42XXX_PWR_MGMT_0_GYRO_MODE_LN;
468 status |= inv_ixm42xxx_write_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
469 inv_ixm42xxx_sleep_us(200);
470
471 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
472 if (gyro_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) {
473 /* First data are noisy after enabling sensor
474 * Keeps track of the start time to discard first sample
475 */
476 if(s->fifo_is_used) {
477 s->gyro_start_time_us = inv_ixm42xxx_get_time_us();
478 }
479 }
480 #endif
481
482 return status;
483 }
484
485 int inv_ixm42xxx_disable_gyro(struct inv_ixm42xxx * s)
486 {
487 int status = 0;
488 uint8_t pwr_mngt_0_reg;
489
490 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
491 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t accel_mode;
492 int stop_fifo_usage = 0;
493 uint8_t data;
494 uint8_t accel_cfg_0_reg;
495 IXM42XXX_ACCEL_CONFIG0_ODR_t acc_odr_bitfield;
496 #endif
497
498 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
499 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
500 accel_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
501 if((accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF) && s->fifo_is_used) {
502 /* First FSYNC event after enable is irrelevant */
503 s->fsync_to_be_ignored = 1;
504 /* FIFO contains Gyro and Accel data if enabled on the OIS path
505 * Dynamically configure the FIFO to publish data only for sensors explicitely enabled on the UI path
506 */
507 stop_fifo_usage = 1;
508 }
509 #endif
510
511 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
512 /* Check if the accelerometer is enabled in low power mode */
513 if (accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) {
514 /* Select the RC OSC as clock source for the accelerometer */
515 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC);
516 }
517 #endif
518
519 pwr_mngt_0_reg &= (uint8_t)~BIT_PWR_MGMT_0_GYRO_MODE_MASK;
520 pwr_mngt_0_reg |= IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF;
521 status |= inv_ixm42xxx_write_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
522 /* keep track of gyro power-off time to check if gyro will be power-on after more than 150ms*/
523 s->gyro_power_off_tmst = inv_ixm42xxx_get_time_us();
524
525 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
526 if (accel_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) {
527 /* Wait based on accelerometer ODR */
528 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
529 acc_odr_bitfield = (IXM42XXX_ACCEL_CONFIG0_ODR_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_ODR_MASK);
530 inv_ixm42xxx_sleep_us(2 * inv_ixm42xxx_convert_odr_bitfield_to_us(acc_odr_bitfield));
531 /* Select the WU OSC as clock source for the accelerometer */
532 status |= inv_ixm42xxx_force_clock_source(s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC);
533 }
534
535 if(stop_fifo_usage && s->fifo_is_used) {
536 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
537 data &= (uint8_t)~(BIT_FIFO_CONFIG1_ACCEL_MASK | BIT_FIFO_CONFIG1_GYRO_MASK | BIT_FIFO_CONFIG1_HIRES_MASK);
538 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
539
540 /* Reset FIFO explicitely so the new configuration is taken into account */
541 status |= inv_ixm42xxx_reset_fifo(s);
542 }
543 #endif
544
545 return status;
546 }
547
548 int inv_ixm42xxx_enable_fsync(struct inv_ixm42xxx * s)
549 {
550 int status = 0;
551 uint8_t value;
552
553 /* Enable Fsync */
554 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &value);
555 value &= (uint8_t)~BIT_TMST_CONFIG_TMST_FSYNC_MASK;
556 value |= (uint8_t)IXM42XXX_TMST_CONFIG_TMST_FSYNC_EN;
557 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &value);
558
559 return status;
560 }
561
562 int inv_ixm42xxx_disable_fsync(struct inv_ixm42xxx * s)
563 {
564 int status = 0;
565 uint8_t value;
566
567 /* Disable Fsync */
568 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &value);
569 value &= (uint8_t)~BIT_TMST_CONFIG_TMST_FSYNC_MASK;
570 value |= (uint8_t)IXM42XXX_TMST_CONFIG_TMST_FSYNC_DIS;
571 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &value);
572
573
574 return status;
575 }
576
577 int inv_ixm42xxx_configure_timestamp_resolution(struct inv_ixm42xxx * s, IXM42XXX_TMST_CONFIG_RESOL_t resol)
578 {
579 int status = 0;
580 uint8_t value;
581
582 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &value);
583 value &= (uint8_t)~BIT_TMST_CONFIG_RESOL_MASK;
584 value |= (uint8_t)resol;
585 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &value);
586
587 return status;
588 }
589
590 int inv_ixm42xxx_get_config_ibi(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
591 {
592 int status = 0;
593 uint8_t data[3] = {0};
594
595 status |= inv_ixm42xxx_set_reg_bank(s, 4);
596 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE8_B4, 3, data); /* burst read int_source8/int_source9/int_source10 */
597 status |= inv_ixm42xxx_set_reg_bank(s, 0);
598
599 /* Handles INT_SOURCE8 bits */
600 interrupt_to_configure->INV_IXM42XXX_UI_FSYNC = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE8_UI_FSYNC_IBI_EN) >> BIT_INT_UI_FSYNC_IBI_EN_POS);
601 interrupt_to_configure->INV_IXM42XXX_UI_DRDY = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE8_UI_DRDY_IBI_EN) >> BIT_INT_UI_DRDY_IBI_EN_POS);
602 interrupt_to_configure->INV_IXM42XXX_FIFO_THS = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE8_FIFO_THS_IBI_EN) >> BIT_INT_FIFO_THS_IBI_EN_POS);
603 interrupt_to_configure->INV_IXM42XXX_FIFO_FULL = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE8_FIFO_FULL_IBI_EN) >> BIT_INT_FIFO_FULL_IBI_EN_POS);
604
605 /* Handles INT_SOURCE9 bits */
606 interrupt_to_configure->INV_IXM42XXX_SMD = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE9_SMD_IBI_EN ) >> BIT_INT_SMD_IBI_EN_POS);
607 interrupt_to_configure->INV_IXM42XXX_WOM_X = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE9_WOM_X_IBI_EN ) >> BIT_INT_WOM_X_IBI_EN_POS);
608 interrupt_to_configure->INV_IXM42XXX_WOM_Y = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE9_WOM_Y_IBI_EN ) >> BIT_INT_WOM_Y_IBI_EN_POS);
609 interrupt_to_configure->INV_IXM42XXX_WOM_Z = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE9_WOM_Z_IBI_EN ) >> BIT_INT_WOM_Z_IBI_EN_POS);
610
611 /* Handles INT_SOURCE10 bits */
612 interrupt_to_configure->INV_IXM42XXX_STEP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE10_STEP_DET_IBI_EN) >> BIT_INT_STEP_DET_IBI_EN_POS);
613 interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE10_STEP_CNT_OVFL_IBI_EN) >> BIT_INT_STEP_CNT_OVFL_IBI_EN_POS);
614 interrupt_to_configure->INV_IXM42XXX_TILT_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE10_TILT_DET_IBI_EN) >> BIT_INT_TILT_DET_IBI_EN_POS);
615 interrupt_to_configure->INV_IXM42XXX_TAP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE10_TAP_DET_IBI_EN) >> BIT_INT_TAP_DET_IBI_EN_POS);
616
617 return status;
618 }
619
620 int inv_ixm42xxx_get_config_int1(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
621 {
622 int status = 0;
623 uint8_t data[3] = {0};
624
625 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE0, 2, data); /* burst read int_source0/int_source1 */
626 status |= inv_ixm42xxx_set_reg_bank(s, 4);
627 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE6_B4, 1, &data[2]); /* int_source6 */
628 status |= inv_ixm42xxx_set_reg_bank(s, 0);
629
630 /* Handles INT_SOURCE0 bits */
631 interrupt_to_configure->INV_IXM42XXX_UI_FSYNC = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE0_UI_FSYNC_INT1_EN) >> BIT_INT_UI_FSYNC_INT_EN_POS);
632 interrupt_to_configure->INV_IXM42XXX_UI_DRDY = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE0_UI_DRDY_INT1_EN) >> BIT_INT_UI_DRDY_INT_EN_POS);
633 interrupt_to_configure->INV_IXM42XXX_FIFO_THS = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE0_FIFO_THS_INT1_EN) >> BIT_INT_FIFO_THS_INT_EN_POS);
634 interrupt_to_configure->INV_IXM42XXX_FIFO_FULL = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE0_FIFO_FULL_INT1_EN) >> BIT_INT_FIFO_FULL_INT_EN_POS);
635
636 /* Handles INT_SOURCE1 bits */
637 interrupt_to_configure->INV_IXM42XXX_SMD = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE1_SMD_INT1_EN ) >> BIT_INT_SMD_INT_EN_POS);
638 interrupt_to_configure->INV_IXM42XXX_WOM_X = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE1_WOM_X_INT1_EN ) >> BIT_INT_WOM_X_INT_EN_POS);
639 interrupt_to_configure->INV_IXM42XXX_WOM_Y = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE1_WOM_Y_INT1_EN ) >> BIT_INT_WOM_Y_INT_EN_POS);
640 interrupt_to_configure->INV_IXM42XXX_WOM_Z = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE1_WOM_Z_INT1_EN ) >> BIT_INT_WOM_Z_INT_EN_POS);
641
642 /* Handles INT_SOURCE6 bits */
643 interrupt_to_configure->INV_IXM42XXX_STEP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_STEP_DET_INT1_EN) >> BIT_INT_STEP_DET_INT_EN_POS);
644 interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_STEP_CNT_OVFL_INT1_EN) >> BIT_INT_STEP_CNT_OVFL_INT_EN_POS);
645 interrupt_to_configure->INV_IXM42XXX_TILT_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_TILT_DET_INT1_EN) >> BIT_INT_TILT_DET_INT_EN_POS);
646 interrupt_to_configure->INV_IXM42XXX_SLEEP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_SLEEP_DET_INT1_EN) >> BIT_INT_SLEEP_DET_INT_EN_POS);
647 interrupt_to_configure->INV_IXM42XXX_WAKE_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_WAKE_DET_INT1_EN) >> BIT_INT_WAKE_DET_INT_EN_POS);
648 interrupt_to_configure->INV_IXM42XXX_TAP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE6_TAP_DET_INT1_EN) >> BIT_INT_TAP_DET_INT_EN_POS);
649
650 return status;
651 }
652
653 int inv_ixm42xxx_get_config_int2(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
654 {
655 int status = 0;
656 uint8_t data[3] = {0};
657
658 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE3, 2, data); /* burst read int_source3/int_source4 */
659 status |= inv_ixm42xxx_set_reg_bank(s, 4);
660 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE7_B4, 1, &data[2]); /* int_source7 */
661 status |= inv_ixm42xxx_set_reg_bank(s, 0);
662
663 /* Handles INT_SOURCE3 bits */
664 interrupt_to_configure->INV_IXM42XXX_UI_FSYNC = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE3_UI_FSYNC_INT2_EN) >> BIT_INT_UI_FSYNC_INT_EN_POS);
665 interrupt_to_configure->INV_IXM42XXX_UI_DRDY = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE3_UI_DRDY_INT2_EN) >> BIT_INT_UI_DRDY_INT_EN_POS);
666 interrupt_to_configure->INV_IXM42XXX_FIFO_THS = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE3_FIFO_THS_INT2_EN) >> BIT_INT_FIFO_THS_INT_EN_POS);
667 interrupt_to_configure->INV_IXM42XXX_FIFO_FULL = (inv_ixm42xxx_interrupt_value) ((data[0] & BIT_INT_SOURCE3_FIFO_FULL_INT2_EN) >> BIT_INT_FIFO_FULL_INT_EN_POS);
668
669 /* Handles INT_SOURCE4 bits */
670 interrupt_to_configure->INV_IXM42XXX_SMD = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE4_SMD_INT2_EN) >> BIT_INT_SMD_INT_EN_POS);
671 interrupt_to_configure->INV_IXM42XXX_WOM_X = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE4_WOM_X_INT2_EN ) >> BIT_INT_WOM_X_INT_EN_POS);
672 interrupt_to_configure->INV_IXM42XXX_WOM_Y = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE4_WOM_Y_INT2_EN ) >> BIT_INT_WOM_Y_INT_EN_POS);
673 interrupt_to_configure->INV_IXM42XXX_WOM_Z = (inv_ixm42xxx_interrupt_value) ((data[1] & BIT_INT_SOURCE4_WOM_Z_INT2_EN ) >> BIT_INT_WOM_Z_INT_EN_POS);
674
675 /* Handles INT_SOURCE7 bits */
676 interrupt_to_configure->INV_IXM42XXX_STEP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_STEP_DET_INT2_EN) >> BIT_INT_STEP_DET_INT_EN_POS);
677 interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_STEP_CNT_OVFL_INT2_EN) >> BIT_INT_STEP_CNT_OVFL_INT_EN_POS);
678 interrupt_to_configure->INV_IXM42XXX_TILT_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_TILT_DET_INT2_EN) >> BIT_INT_TILT_DET_INT_EN_POS);
679 interrupt_to_configure->INV_IXM42XXX_SLEEP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_SLEEP_DET_INT2_EN) >> BIT_INT_SLEEP_DET_INT_EN_POS);
680 interrupt_to_configure->INV_IXM42XXX_WAKE_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_WAKE_DET_INT2_EN) >> BIT_INT_WAKE_DET_INT_EN_POS);
681 interrupt_to_configure->INV_IXM42XXX_TAP_DET = (inv_ixm42xxx_interrupt_value) ((data[2] & BIT_INT_SOURCE7_TAP_DET_INT2_EN) >> BIT_INT_TAP_DET_INT_EN_POS);
682
683 return status;
684 }
685
686 int inv_ixm42xxx_set_config_ibi(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
687 {
688 int status = 0;
689 uint8_t data[3] = {0};
690
691 status |= inv_ixm42xxx_set_reg_bank(s, 4);
692 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE8_B4, 3, data); /* burst read int_source8/int_source9/int_source10 */
693
694 /* Set INT_SOURCE8 bits */
695 data[0] &= (uint8_t)~(BIT_INT_SOURCE8_UI_FSYNC_IBI_EN
696 | BIT_INT_SOURCE8_UI_DRDY_IBI_EN
697 | BIT_INT_SOURCE8_FIFO_THS_IBI_EN
698 | BIT_INT_SOURCE8_FIFO_FULL_IBI_EN);
699 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_FSYNC != 0) << BIT_INT_UI_FSYNC_IBI_EN_POS);
700 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_DRDY != 0) << BIT_INT_UI_DRDY_IBI_EN_POS);
701 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_THS != 0) << BIT_INT_FIFO_THS_IBI_EN_POS);
702 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_FULL != 0) << BIT_INT_FIFO_FULL_IBI_EN_POS);
703
704 /* Set INT_SOURCE9 bits */
705 data[1] &= (uint8_t)~(BIT_INT_SOURCE9_SMD_IBI_EN
706 | BIT_INT_SOURCE9_WOM_X_IBI_EN
707 | BIT_INT_SOURCE9_WOM_Y_IBI_EN
708 | BIT_INT_SOURCE9_WOM_Z_IBI_EN);
709 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_SMD != 0) << BIT_INT_SMD_IBI_EN_POS);
710 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_X != 0) << BIT_INT_WOM_X_IBI_EN_POS);
711 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Y != 0) << BIT_INT_WOM_Y_IBI_EN_POS);
712 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Z != 0) << BIT_INT_WOM_Z_IBI_EN_POS);
713
714 /* Set INT_SOURCE10 bits */
715 data[2] &= (uint8_t)~(BIT_INT_SOURCE10_STEP_DET_IBI_EN
716 | BIT_INT_SOURCE10_STEP_CNT_OVFL_IBI_EN
717 | BIT_INT_SOURCE10_TILT_DET_IBI_EN
718 | BIT_INT_SOURCE10_TAP_DET_IBI_EN);
719 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_DET != 0) << BIT_INT_STEP_DET_IBI_EN_POS);
720 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL != 0) << BIT_INT_STEP_CNT_OVFL_IBI_EN_POS);
721 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TILT_DET != 0) << BIT_INT_TILT_DET_IBI_EN_POS);
722 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TAP_DET != 0) << BIT_INT_TAP_DET_IBI_EN_POS);
723
724 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_SOURCE8_B4, 3, data); /* burst write int_source8/int_source9/int_source10 */
725 status |= inv_ixm42xxx_set_reg_bank(s, 0);
726
727 return status;
728 }
729
730 int inv_ixm42xxx_set_config_int1(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
731 {
732 int status = 0;
733 uint8_t data[3] = {0};
734
735 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE0, 2, data); /* burst read int_source0/int_source1 */
736 status |= inv_ixm42xxx_set_reg_bank(s, 4);
737 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE6_B4, 1, &data[2]); /* switch to bank4 for int_source6 */
738
739 /* Set INT_SOURCE0 bits */
740 data[0] &= (uint8_t)~(BIT_INT_SOURCE0_UI_FSYNC_INT1_EN
741 | BIT_INT_SOURCE0_UI_DRDY_INT1_EN
742 | BIT_INT_SOURCE0_FIFO_THS_INT1_EN
743 | BIT_INT_SOURCE0_FIFO_FULL_INT1_EN);
744 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_FSYNC != 0) << BIT_INT_UI_FSYNC_INT_EN_POS);
745 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_DRDY != 0) << BIT_INT_UI_DRDY_INT_EN_POS);
746 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_THS != 0) << BIT_INT_FIFO_THS_INT_EN_POS);
747 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_FULL != 0) << BIT_INT_FIFO_FULL_INT_EN_POS);
748
749 /* Set INT_SOURCE1 bits */
750 data[1] &= (uint8_t)~(BIT_INT_SOURCE1_SMD_INT1_EN
751 | BIT_INT_SOURCE1_WOM_X_INT1_EN
752 | BIT_INT_SOURCE1_WOM_Y_INT1_EN
753 | BIT_INT_SOURCE1_WOM_Z_INT1_EN);
754 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_SMD != 0) << BIT_INT_SMD_INT_EN_POS);
755 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_X != 0) << BIT_INT_WOM_X_INT_EN_POS);
756 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Y != 0) << BIT_INT_WOM_Y_INT_EN_POS);
757 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Z != 0) << BIT_INT_WOM_Z_INT_EN_POS);
758
759 /* Set INT_SOURCE6 bits */
760 data[2] &= (uint8_t)~(BIT_INT_SOURCE6_STEP_DET_INT1_EN
761 | BIT_INT_SOURCE6_STEP_CNT_OVFL_INT1_EN
762 | BIT_INT_SOURCE6_TILT_DET_INT1_EN
763 | BIT_INT_SOURCE6_SLEEP_DET_INT1_EN
764 | BIT_INT_SOURCE6_WAKE_DET_INT1_EN
765 | BIT_INT_SOURCE6_TAP_DET_INT1_EN);
766 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_DET != 0) << BIT_INT_STEP_DET_INT_EN_POS);
767 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL != 0) << BIT_INT_STEP_CNT_OVFL_INT_EN_POS);
768 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TILT_DET != 0) << BIT_INT_TILT_DET_INT_EN_POS);
769 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_SLEEP_DET != 0) << BIT_INT_SLEEP_DET_INT_EN_POS);
770 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_WAKE_DET != 0) << BIT_INT_WAKE_DET_INT_EN_POS);
771 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TAP_DET != 0) << BIT_INT_TAP_DET_INT_EN_POS);
772
773 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_SOURCE6_B4, 1, &data[2]); /* start with int_source6 since we are still in bank4 */
774 status |= inv_ixm42xxx_set_reg_bank(s, 0);
775 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_SOURCE0, 2, data); /* burst write int_source0/int_source1 */
776
777 return status;
778 }
779
780 int inv_ixm42xxx_set_config_int2(struct inv_ixm42xxx * s, inv_ixm42xxx_interrupt_parameter_t * interrupt_to_configure)
781 {
782 int status = 0;
783 uint8_t data[3] = {0};
784
785 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE3, 2, data); /* burst read int_source3/int_source4 */
786 status |= inv_ixm42xxx_set_reg_bank(s, 4);
787 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_SOURCE7_B4, 1, &data[2]); /* switch to bank4 for int_source7 */
788
789 /* Set INT_SOURCE3 bits */
790 data[0] &= (uint8_t)~(BIT_INT_SOURCE3_UI_FSYNC_INT2_EN
791 | BIT_INT_SOURCE3_UI_DRDY_INT2_EN
792 | BIT_INT_SOURCE3_FIFO_THS_INT2_EN
793 | BIT_INT_SOURCE3_FIFO_FULL_INT2_EN);
794 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_FSYNC != 0) << BIT_INT_UI_FSYNC_INT_EN_POS);
795 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_UI_DRDY != 0) << BIT_INT_UI_DRDY_INT_EN_POS);
796 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_THS != 0) << BIT_INT_FIFO_THS_INT_EN_POS);
797 data[0] |= ((interrupt_to_configure->INV_IXM42XXX_FIFO_FULL != 0) << BIT_INT_FIFO_FULL_INT_EN_POS);
798
799 /* Set INT_SOURCE4 bits */
800 data[1] &= (uint8_t)~(BIT_INT_SOURCE4_SMD_INT2_EN
801 | BIT_INT_SOURCE4_WOM_X_INT2_EN
802 | BIT_INT_SOURCE4_WOM_Y_INT2_EN
803 | BIT_INT_SOURCE4_WOM_Z_INT2_EN);
804 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_SMD != 0) << BIT_INT_SMD_INT_EN_POS);
805 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_X != 0) << BIT_INT_WOM_X_INT_EN_POS);
806 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Y != 0) << BIT_INT_WOM_Y_INT_EN_POS);
807 data[1] |= ((interrupt_to_configure->INV_IXM42XXX_WOM_Z != 0) << BIT_INT_WOM_Z_INT_EN_POS);
808
809 /* Set INT_SOURCE7 bits */
810 data[2] &= (uint8_t)~(BIT_INT_SOURCE7_STEP_DET_INT2_EN
811 | BIT_INT_SOURCE7_STEP_CNT_OVFL_INT2_EN
812 | BIT_INT_SOURCE7_TILT_DET_INT2_EN
813 | BIT_INT_SOURCE7_SLEEP_DET_INT2_EN
814 | BIT_INT_SOURCE7_WAKE_DET_INT2_EN
815 | BIT_INT_SOURCE7_TAP_DET_INT2_EN);
816 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_DET != 0) << BIT_INT_STEP_DET_INT_EN_POS);
817 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_STEP_CNT_OVFL != 0) << BIT_INT_STEP_CNT_OVFL_INT_EN_POS);
818 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TILT_DET != 0) << BIT_INT_TILT_DET_INT_EN_POS);
819 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_SLEEP_DET != 0) << BIT_INT_SLEEP_DET_INT_EN_POS);
820 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_WAKE_DET != 0) << BIT_INT_WAKE_DET_INT_EN_POS);
821 data[2] |= ((interrupt_to_configure->INV_IXM42XXX_TAP_DET != 0) << BIT_INT_TAP_DET_INT_EN_POS);
822
823 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_SOURCE7_B4, 1, &data[2]); /* start with int_source7 since we are still in bank4 */
824 status |= inv_ixm42xxx_set_reg_bank(s, 0);
825 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_SOURCE3, 2, data); /* burst write int_source3/int_source4 */
826
827 return status;
828 }
829
830 int inv_ixm42xxx_get_data_from_registers(struct inv_ixm42xxx * s)
831 {
832 int status = 0;
833 uint8_t int_status;
834 uint8_t temperature[2];
835 uint8_t accel[ACCEL_DATA_SIZE];
836 uint8_t gyro[GYRO_DATA_SIZE];
837 inv_ixm42xxx_sensor_event_t event;
838
839 /* Ensure data ready status bit is set */
840 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_STATUS, 1, &int_status);
841 if(status)
842 return status;
843
844 if(int_status & BIT_INT_STATUS_DRDY) {
845
846 status = inv_ixm42xxx_read_reg(s, MPUREG_TEMP_DATA0_UI, TEMP_DATA_SIZE, temperature);
847 inv_ixm42xxx_format_data(s->endianess_data, temperature, (uint16_t *)&event.temperature);
848
849 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_DATA_X0_UI, ACCEL_DATA_SIZE, accel);
850 inv_ixm42xxx_format_data(s->endianess_data, &accel[0], (uint16_t *)&event.accel[0]);
851 inv_ixm42xxx_format_data(s->endianess_data, &accel[2], (uint16_t *)&event.accel[1]);
852 inv_ixm42xxx_format_data(s->endianess_data, &accel[4], (uint16_t *)&event.accel[2]);
853
854 status |= inv_ixm42xxx_read_reg(s, MPUREG_GYRO_DATA_X0_UI, GYRO_DATA_SIZE, gyro);
855 inv_ixm42xxx_format_data(s->endianess_data, &gyro[0], (uint16_t *)&event.gyro[0]);
856 inv_ixm42xxx_format_data(s->endianess_data, &gyro[2], (uint16_t *)&event.gyro[1]);
857 inv_ixm42xxx_format_data(s->endianess_data, &gyro[4], (uint16_t *)&event.gyro[2]);
858
859 /* call sensor event callback */
860 if(s->sensor_event_cb)
861 s->sensor_event_cb(&event);
862
863 /* Device interrupts delayed when communicating with other slaves connected to same bus
864 * Semi-Write to release interrupt in I2C
865 */
866 if((s->transport.serif.serif_type == IXM42XXX_UI_I2C) || (s->transport.serif.serif_type == IXM42XXX_UI_I3C)) {
867 uint8_t data = 0;
868 status |= inv_ixm42xxx_write_reg(s, MPUREG_WHO_AM_I, 1, &data);
869 }
870
871 }
872 /*else: Data Ready was not set*/
873
874 return status;
875 }
876
877 int inv_ixm42xxx_get_data_from_fifo(struct inv_ixm42xxx * s)
878 {
879 int status = 0;
880 uint8_t int_status;
881 uint8_t data_reg = 0;
882 uint8_t data[2];
883 uint16_t packet_count_i, packet_count = 0;
884 uint16_t packet_size = FIFO_HEADER_SIZE + FIFO_ACCEL_DATA_SIZE + FIFO_GYRO_DATA_SIZE + FIFO_TEMP_DATA_SIZE + FIFO_TS_FSYNC_SIZE;
885 fifo_header_t * header;
886
887 /* Ensure data ready status bit is set */
888 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_STATUS, 1, &int_status);
889 if(status)
890 return status;
891
892 if((int_status & BIT_INT_STATUS_FIFO_THS) || (int_status & BIT_INT_STATUS_FIFO_FULL)) {
893
894 /* FIFO record mode configured at driver init, so we read packet number, not byte count */
895 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_COUNTH, 2, data);
896 if(status != INV_ERROR_SUCCESS)
897 return status;
898 inv_ixm42xxx_format_data(IXM42XXX_INTF_CONFIG0_DATA_LITTLE_ENDIAN, data, &packet_count);
899
900 if (packet_count > 0) {
901 /* Read FIFO only when data is expected in FIFO */
902 /* fifo_idx type variable must be large enough to parse the FIFO_MIRRORING_SIZE */
903 uint16_t fifo_idx = 0;
904
905 if(s->fifo_highres_enabled)
906 packet_size = FIFO_20BYTES_PACKET_SIZE;
907
908 if(s->transport.serif.serif_type == IXM42XXX_UI_I3C) {
909 /* in case of I3C, need to read packet by packet since INT is embedded on protocol so this can
910 happen that FIFO read is interrupted to handle IBI, and in that case FIFO is partially read.
911 To handle this, 2 solution :
912 - handle fifo lost packet & partial read
913 - read packet by packet
914 2nd solution prefered here because less heavy from driver point of view but it is less optimal
915 for the timing because we have to initiate N transactions in any case */
916 for(packet_count_i = 0 ; packet_count_i < packet_count ; packet_count_i++) {
917 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_DATA, packet_size, &s->fifo_data[packet_count_i*packet_size]);
918 if(status) {
919 /* sensor data is in FIFO according to FIFO_COUNT but failed to read FIFO,
920 reset FIFO and try next chance */
921 inv_ixm42xxx_reset_fifo(s);
922 return status;
923 }
924 }
925 } else {
926 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_DATA, packet_size * packet_count, s->fifo_data);
927 if(status) {
928 /* sensor data is in FIFO according to FIFO_COUNT but failed to read FIFO,
929 reset FIFO and try next chance */
930 inv_ixm42xxx_reset_fifo(s);
931 return status;
932 }
933 }
934
935 for(packet_count_i = 0; packet_count_i < packet_count; packet_count_i++) {
936 inv_ixm42xxx_sensor_event_t event;
937 event.sensor_mask = 0;
938
939 header = (fifo_header_t *) &s->fifo_data[fifo_idx];
940 fifo_idx += FIFO_HEADER_SIZE;
941
942 /* Decode packet */
943 if (header->bits.msg_bit) {
944 /* MSG BIT set in FIFO header, Resetting FIFO */
945 inv_ixm42xxx_reset_fifo(s);
946 return INV_ERROR;
947 }
948
949 if(header->bits.accel_bit) {
950 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[0+fifo_idx], (uint16_t *)&event.accel[0]);
951 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[2+fifo_idx], (uint16_t *)&event.accel[1]);
952 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[4+fifo_idx], (uint16_t *)&event.accel[2]);
953 fifo_idx += FIFO_ACCEL_DATA_SIZE;
954 }
955
956 if (header->bits.gyro_bit) {
957 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[0+fifo_idx], (uint16_t *)&event.gyro[0]);
958 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[2+fifo_idx], (uint16_t *)&event.gyro[1]);
959 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[4+fifo_idx], (uint16_t *)&event.gyro[2]);
960 fifo_idx += FIFO_GYRO_DATA_SIZE;
961 }
962
963 if ((header->bits.accel_bit) || (header->bits.gyro_bit)) {
964 if(header->bits.twentybits_bit) {
965 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[0+fifo_idx], (uint16_t *)&event.temperature);
966 fifo_idx += FIFO_TEMP_DATA_SIZE + FIFO_TEMP_HIGH_RES_SIZE;
967
968 /* new temperature data */
969 if (event.temperature != INVALID_VALUE_FIFO)
970 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_TEMPERATURE);
971 } else {
972 event.temperature = (int8_t)s->fifo_data[0+fifo_idx]; /* cast to int8_t since FIFO is in 16 bits mode (temperature on 8 bits) */
973 fifo_idx += FIFO_TEMP_DATA_SIZE;
974
975 /* new temperature data */
976 if (event.temperature != INVALID_VALUE_FIFO_1B)
977 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_TEMPERATURE);
978 }
979 }
980
981 if ((header->bits.timestamp_bit) || (header->bits.fsync_bit)) {
982 inv_ixm42xxx_format_data(s->endianess_data, &s->fifo_data[0+fifo_idx], (uint16_t *)&event.timestamp_fsync);
983 fifo_idx += FIFO_TS_FSYNC_SIZE;
984
985 /* new fsync event */
986 /* First FSYNC event after enable is irrelevant
987 * FSYNC tag and FSYNC data should be ignored on the first ODR after restart.
988 */
989 if (header->bits.fsync_bit){
990 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
991 if(s->fsync_to_be_ignored == 0)
992 #endif
993 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_FSYNC_EVENT);
994 }
995 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
996 s->fsync_to_be_ignored = 0;
997 #endif
998 }
999
1000 if (header->bits.accel_bit) {
1001 if( (event.accel[0] != INVALID_VALUE_FIFO) &&
1002 (event.accel[1] != INVALID_VALUE_FIFO) &&
1003 (event.accel[2] != INVALID_VALUE_FIFO) ) {
1004
1005 if (header->bits.twentybits_bit) {
1006 event.accel_high_res[0] = (s->fifo_data[0+fifo_idx] >> 4) & 0xF;
1007 event.accel_high_res[1] = (s->fifo_data[1+fifo_idx] >> 4) & 0xF;
1008 event.accel_high_res[2] = (s->fifo_data[2+fifo_idx] >> 4) & 0xF;
1009 }
1010
1011 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1012 if (s->accel_start_time_us == UINT32_MAX) {
1013 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_ACCEL);
1014 } else {
1015 if (!header->bits.fsync_bit) {
1016 /* First data are noisy after enabling sensor
1017 * Compare start time with current time to notify the event
1018 */
1019 if((inv_ixm42xxx_get_time_us() - s->accel_start_time_us) >= IXM42XXX_ACC_STARTUP_TIME_US) {
1020 s->accel_start_time_us = UINT32_MAX;
1021 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_ACCEL);
1022 }
1023 }
1024 }
1025 #else
1026 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_ACCEL);
1027 #endif
1028 }
1029 }
1030
1031 if (header->bits.gyro_bit) {
1032 if( (event.gyro[0] != INVALID_VALUE_FIFO) &&
1033 (event.gyro[1] != INVALID_VALUE_FIFO) &&
1034 (event.gyro[2] != INVALID_VALUE_FIFO) ) {
1035
1036 if (header->bits.twentybits_bit) {
1037 event.gyro_high_res[0] = (s->fifo_data[0+fifo_idx]) & 0xF;
1038 event.gyro_high_res[1] = (s->fifo_data[1+fifo_idx]) & 0xF;
1039 event.gyro_high_res[2] = (s->fifo_data[2+fifo_idx]) & 0xF;
1040 }
1041
1042 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1043 if (s->gyro_start_time_us == UINT32_MAX) {
1044 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_GYRO);
1045 } else {
1046 if (!header->bits.fsync_bit) {
1047 /* First data are noisy after enabling sensor
1048 * Compare start time with current time to notify the event
1049 */
1050 if((inv_ixm42xxx_get_time_us() - s->gyro_start_time_us) >= IXM42XXX_GYR_STARTUP_TIME_US) {
1051 s->gyro_start_time_us = UINT32_MAX;
1052 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_GYRO);
1053 }
1054 }
1055 }
1056 #else
1057 event.sensor_mask |= (1 << INV_IXM42XXX_SENSOR_GYRO);
1058 #endif
1059 }
1060 }
1061
1062 if (header->bits.twentybits_bit)
1063 fifo_idx += FIFO_ACCEL_GYRO_HIGH_RES_SIZE;
1064
1065 /* call sensor event callback */
1066 if(s->sensor_event_cb)
1067 s->sensor_event_cb(&event);
1068
1069 /* Device interrupts delayed when communicating with other slaves connected to same bus
1070 * Semi-Write to release interrupt in I2C
1071 */
1072 if((s->transport.serif.serif_type == IXM42XXX_UI_I2C) || (s->transport.serif.serif_type == IXM42XXX_UI_I3C)) {
1073 status |= inv_ixm42xxx_write_reg(s, MPUREG_WHO_AM_I, 1, &data_reg);
1074 }
1075
1076 } /* end of FIFO read for loop */
1077 }
1078 /*else: packet_count was 0*/
1079 }
1080 /*else: FIFO threshold was not reached and FIFO was not full*/
1081
1082 return packet_count;
1083 }
1084
1085 uint32_t inv_ixm42xxx_convert_odr_bitfield_to_us(uint32_t odr_bitfield)
1086 {
1087 /*
1088 odr bitfield - frequency : odr ms
1089 0 - N/A
1090 1 - 32K
1091 2 - 16K
1092 3 - 8k
1093 4 - 4k
1094 5 - 2k
1095 6 - 1k : 1ms
1096 (default) 7 - 200 : 5 ms
1097 8 - 100 : 10 ms
1098 9 - 50 : 20 ms
1099 10 - 25 : 40 ms
1100 11 - 12.5 : 80 ms
1101 12 - 6.25 : 160 ms
1102 13 - 3.125 : 320 ms
1103 14 - 1.5625 : 640 ms
1104 15 - 500 : 2 ms
1105 */
1106
1107 switch(odr_bitfield ) {
1108 case IXM42XXX_ACCEL_CONFIG0_ODR_32_KHZ: return 32;
1109 case IXM42XXX_ACCEL_CONFIG0_ODR_16_KHZ: return 63;
1110 case IXM42XXX_ACCEL_CONFIG0_ODR_8_KHZ: return 125;
1111 case IXM42XXX_ACCEL_CONFIG0_ODR_4_KHZ: return 250;
1112 case IXM42XXX_ACCEL_CONFIG0_ODR_2_KHZ: return 500;
1113 case IXM42XXX_ACCEL_CONFIG0_ODR_1_KHZ: return 1000;
1114 case IXM42XXX_ACCEL_CONFIG0_ODR_500_HZ: return 2000;
1115 case IXM42XXX_ACCEL_CONFIG0_ODR_200_HZ: return 5000;
1116 case IXM42XXX_ACCEL_CONFIG0_ODR_100_HZ: return 10000;
1117 case IXM42XXX_ACCEL_CONFIG0_ODR_50_HZ: return 20000;
1118 case IXM42XXX_ACCEL_CONFIG0_ODR_25_HZ: return 40000;
1119 case IXM42XXX_ACCEL_CONFIG0_ODR_12_5_HZ: return 80000;
1120 case IXM42XXX_ACCEL_CONFIG0_ODR_6_25_HZ: return 160000;
1121 case IXM42XXX_ACCEL_CONFIG0_ODR_3_125_HZ: return 320000;
1122 case IXM42XXX_ACCEL_CONFIG0_ODR_1_5625_HZ:
1123 default: return 640000;
1124 }
1125 }
1126
1127 int inv_ixm42xxx_set_accel_frequency(struct inv_ixm42xxx * s, const IXM42XXX_ACCEL_CONFIG0_ODR_t frequency)
1128 {
1129 int status = 0;
1130 uint8_t accel_cfg_0_reg;
1131 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1132 /* Accel Low Power could report with wrong ODR if internal counter for ODR changed overflowed
1133 * Update software counter to handle the overflow
1134 */
1135 uint8_t pwr_mngt_0_reg;
1136 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t accel_pwr_mode;
1137
1138 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
1139 accel_pwr_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
1140 if(IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP != accel_pwr_mode)
1141 s->wu_off_acc_odr_changes++; /* WUOSC is not clock source, this ODR change could be missed */
1142 else
1143 s->wu_off_acc_odr_changes = 0; /* WUOSC is on and acc is running, ODR change will be taken into account */
1144 #endif
1145 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1146 accel_cfg_0_reg &= (uint8_t)~BIT_ACCEL_CONFIG0_ODR_MASK;
1147 accel_cfg_0_reg |= (uint8_t)frequency;
1148 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1149
1150 return status;
1151 }
1152
1153 int inv_ixm42xxx_set_gyro_frequency(struct inv_ixm42xxx * s, const IXM42XXX_GYRO_CONFIG0_ODR_t frequency)
1154 {
1155 int status = 0;
1156 uint8_t gyro_cfg_0_reg;
1157 status |= inv_ixm42xxx_read_reg( s, MPUREG_GYRO_CONFIG0 , 1, &gyro_cfg_0_reg);
1158 gyro_cfg_0_reg &= (uint8_t)~BIT_GYRO_CONFIG0_ODR_MASK;
1159 gyro_cfg_0_reg |= (uint8_t)frequency;
1160 status |= inv_ixm42xxx_write_reg(s, MPUREG_GYRO_CONFIG0, 1, &gyro_cfg_0_reg);
1161
1162 return status;
1163 }
1164
1165 int inv_ixm42xxx_set_accel_fsr(struct inv_ixm42xxx * s, IXM42XXX_ACCEL_CONFIG0_FS_SEL_t accel_fsr_g)
1166 {
1167 int status = 0;
1168 uint8_t accel_cfg_0_reg;
1169 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1170 accel_cfg_0_reg &= (uint8_t)~BIT_ACCEL_CONFIG0_FS_SEL_MASK;
1171 accel_cfg_0_reg |= (uint8_t)accel_fsr_g;
1172 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1173
1174 return status;
1175 }
1176
1177 int inv_ixm42xxx_set_gyro_fsr(struct inv_ixm42xxx * s, IXM42XXX_GYRO_CONFIG0_FS_SEL_t gyro_fsr_dps)
1178 {
1179 int status = 0;
1180 uint8_t gyro_cfg_0_reg;
1181 status |= inv_ixm42xxx_read_reg( s, MPUREG_GYRO_CONFIG0 , 1, &gyro_cfg_0_reg);
1182 gyro_cfg_0_reg &= (uint8_t)~BIT_GYRO_CONFIG0_FS_SEL_MASK;
1183 gyro_cfg_0_reg |= (uint8_t)gyro_fsr_dps;
1184 status |= inv_ixm42xxx_write_reg(s, MPUREG_GYRO_CONFIG0, 1, &gyro_cfg_0_reg);
1185
1186 return status;
1187 }
1188
1189 int inv_ixm42xxx_get_accel_fsr(struct inv_ixm42xxx * s, IXM42XXX_ACCEL_CONFIG0_FS_SEL_t * accel_fsr_g)
1190 {
1191 int status = 0;
1192 uint8_t accel_cfg_0_reg;
1193
1194 if((s->fifo_highres_enabled) && (s->fifo_is_used == INV_IXM42XXX_FIFO_ENABLED))
1195 *accel_fsr_g = ACCEL_CONFIG0_FS_SEL_MAX;
1196 else {
1197 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1198 *accel_fsr_g = (IXM42XXX_ACCEL_CONFIG0_FS_SEL_t)(accel_cfg_0_reg & BIT_ACCEL_CONFIG0_FS_SEL_MASK);
1199 }
1200
1201 return status;
1202 }
1203
1204 int inv_ixm42xxx_get_gyro_fsr(struct inv_ixm42xxx * s, IXM42XXX_GYRO_CONFIG0_FS_SEL_t * gyro_fsr_dps)
1205 {
1206 int status = 0;
1207 uint8_t gyro_cfg_0_reg;
1208
1209 if((s->fifo_highres_enabled) && (s->fifo_is_used == INV_IXM42XXX_FIFO_ENABLED))
1210 *gyro_fsr_dps = GYRO_CONFIG0_FS_SEL_MAX;
1211 else {
1212 status |= inv_ixm42xxx_read_reg( s, MPUREG_GYRO_CONFIG0 , 1, &gyro_cfg_0_reg);
1213 *gyro_fsr_dps = (IXM42XXX_GYRO_CONFIG0_FS_SEL_t)(gyro_cfg_0_reg & BIT_GYRO_CONFIG0_FS_SEL_MASK);
1214 }
1215
1216 return status;
1217 }
1218
1219 int inv_ixm42xxx_set_accel_lp_avg(struct inv_ixm42xxx * s, IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_t acc_avg)
1220 {
1221 uint8_t data;
1222 int status = 0;
1223
1224 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1225 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK;
1226 data |= (uint8_t)acc_avg;
1227 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1228
1229 if(status == 0)
1230 /* Update SW mirror to re-apply it when required */
1231 s->avg_bw_setting.acc_lp_avg = (uint8_t)(acc_avg & BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK);
1232
1233 return status;
1234 }
1235
1236 int inv_ixm42xxx_set_accel_ln_bw(struct inv_ixm42xxx * s, IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_t acc_bw)
1237 {
1238 uint8_t data;
1239 int status = 0;
1240
1241 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1242 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK;
1243 data |= (uint8_t)acc_bw;
1244 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1245
1246 if(status == 0)
1247 /* Update SW mirror to re-apply it when required */
1248 s->avg_bw_setting.acc_ln_bw = (uint8_t)(acc_bw & BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK);
1249
1250 return status;
1251 }
1252
1253 int inv_ixm42xxx_set_gyro_ln_bw(struct inv_ixm42xxx * s, IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_t gyr_bw)
1254 {
1255 uint8_t data;
1256 int status = 0;
1257
1258 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1259 data &= (uint8_t)~BIT_GYRO_ACCEL_CONFIG0_GYRO_FILT_MASK;
1260 data |= (uint8_t)gyr_bw;
1261 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_GYRO_CONFIG0, 1, &data);
1262
1263 if(status == 0)
1264 /* Update SW mirror to re-apply it when required */
1265 s->avg_bw_setting.gyr_ln_bw = (uint8_t)(gyr_bw & BIT_GYRO_ACCEL_CONFIG0_GYRO_FILT_MASK);
1266
1267 return status;
1268 }
1269
1270 int inv_ixm42xxx_reset_fifo(struct inv_ixm42xxx * s)
1271 {
1272 uint8_t data;
1273 uint8_t saved_fifo_config;
1274 int status = 0;
1275 uint8_t pwr_mngt_0_reg;
1276 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t acc_mode;
1277 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyr_mode;
1278
1279 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt_0_reg);
1280 gyr_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
1281 acc_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t)(pwr_mngt_0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
1282
1283 if ( ( (gyr_mode != IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF) || (acc_mode != IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF) )
1284 && (acc_mode != IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) ) {
1285 data = (uint8_t)IXM42XXX_SIGNAL_PATH_RESET_FIFO_FLUSH_EN;
1286 status |= inv_ixm42xxx_write_reg(s, MPUREG_SIGNAL_PATH_RESET, 1, &data);
1287 }
1288 else {
1289 /* In case no sensor is enabled or in accel low power mode, change the FIFO_MODE to “bypass” (00) mode to force the FIFO reset,
1290 * potentials remaining data will be flushed
1291 * Then proceed to a dummy read to released the FIFO reset synchronously with the serial clock
1292 */
1293 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG, 1, &saved_fifo_config);
1294 data = (uint8_t)IXM42XXX_FIFO_CONFIG_MODE_BYPASS;
1295 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG, 1, &data);
1296 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG, 1, &saved_fifo_config);
1297 status |= inv_ixm42xxx_read_reg(s, MPUREG_WHO_AM_I, 1, &data);
1298 }
1299
1300 return status;
1301 }
1302
1303 int inv_ixm42xxx_enable_timestamp_to_register(struct inv_ixm42xxx * s)
1304 {
1305 int status = 0;
1306 uint8_t tmst_cfg_reg;
1307
1308 if(!s->tmst_to_reg_en_cnt) {
1309 /* Enable the 20-bits timestamp register reading
1310 * It's needed to wait at least 200us before doing the strobe
1311 */
1312 status |= inv_ixm42xxx_read_reg( s, MPUREG_TMST_CONFIG , 1, &tmst_cfg_reg);
1313 tmst_cfg_reg &= ~(uint8_t)BIT_TMST_CONFIG_TMST_TO_REGS_EN_MASK;
1314 tmst_cfg_reg |= (uint8_t)IXM42XXX_TMST_CONFIG_TMST_TO_REGS_EN;
1315 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &tmst_cfg_reg);
1316
1317 inv_ixm42xxx_sleep_us(200);
1318 }
1319 s->tmst_to_reg_en_cnt ++;
1320
1321 return status;
1322 }
1323
1324 int inv_ixm42xxx_disable_timestamp_to_register(struct inv_ixm42xxx * s)
1325 {
1326 int status = 0;
1327 uint8_t tmst_cfg_reg;
1328
1329 if(!s->tmst_to_reg_en_cnt) {
1330 /* Disable the 20-bits timestamp register reading */
1331 status |= inv_ixm42xxx_read_reg( s, MPUREG_TMST_CONFIG , 1, &tmst_cfg_reg);
1332 tmst_cfg_reg &= (uint8_t)~BIT_TMST_CONFIG_TMST_TO_REGS_EN_MASK;
1333 tmst_cfg_reg |=(uint8_t) IXM42XXX_TMST_CONFIG_TMST_TO_REGS_DIS;
1334 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &tmst_cfg_reg);
1335 }
1336 s->tmst_to_reg_en_cnt --;
1337
1338 return status;
1339 }
1340
1341 int inv_ixm42xxx_get_current_timestamp(struct inv_ixm42xxx * s, uint32_t * icm_time)
1342 {
1343 int status = 0;
1344 uint8_t data[3];
1345
1346 /* Enable timestamp counter to be latched in timestamp register */
1347 data[0] = (uint8_t)IXM42XXX_SIGNAL_PATH_RESET_TMST_STROBE_EN;
1348 status |= inv_ixm42xxx_write_reg(s, MPUREG_SIGNAL_PATH_RESET, 1, &data[0]);
1349
1350 /* Get ICM timestamp */
1351 status |= inv_ixm42xxx_set_reg_bank(s, 1);
1352 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_VAL0_B1, 3, data);
1353 status |= inv_ixm42xxx_set_reg_bank(s, 0);
1354 *icm_time = ((uint32_t)(data[2] & 0x0F) << 16) + ((uint32_t)data[1] << 8) + data[0];
1355
1356 return status;
1357 }
1358
1359 int inv_ixm42xxx_enable_clkin_rtc(struct inv_ixm42xxx * s, uint8_t enable)
1360 {
1361 int status = 0;
1362 uint8_t data;
1363
1364 if (enable) {
1365
1366 /* CLKIN is not supported for all parts, prevent the CLKIN to be enabled in this case. */
1367 #if (RTC_SUPPORTED)
1368 /* Configure CLKIN on pin 9 */
1369 status |= inv_ixm42xxx_set_reg_bank(s, 1);
1370 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG5_B1, 1, &data);
1371 data &= (uint8_t)~BIT_INTF_CONFIG5_GPIO_PAD_SEL_MASK;
1372 data |= (2 << BIT_INTF_CONFIG5_GPIO_PAD_SEL_POS);
1373 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG5_B1, 1, &data);
1374 status |= inv_ixm42xxx_set_reg_bank(s, 0);
1375 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
1376 data &= (uint8_t)~BIT_RTC_MODE_MASK;
1377 data |= (uint8_t)IXM42XXX_INTF_CONFIG1_RTC_MODE_EN;
1378 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
1379 status |= inv_ixm42xxx_configure_timestamp_resolution(s, IXM42XXX_TMST_CONFIG_RESOL_16us);
1380 #else
1381 (void)s;
1382 (void)enable;
1383 return INV_ERROR;
1384 #endif
1385
1386 } else {
1387 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
1388 data &= (uint8_t)~BIT_RTC_MODE_MASK;
1389 data |= (uint8_t)IXM42XXX_INTF_CONFIG1_RTC_MODE_DIS;
1390 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
1391 }
1392
1393 return status;
1394 }
1395
1396 int inv_ixm42xxx_get_clkin_rtc_status(struct inv_ixm42xxx * s)
1397 {
1398 uint8_t data;
1399 int status=0;
1400
1401 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG1, 1, &data);
1402 if ((data & BIT_RTC_MODE_MASK) == IXM42XXX_INTF_CONFIG1_RTC_MODE_EN)
1403 return 1;
1404 else
1405 return 0;
1406 }
1407
1408 int inv_ixm42xxx_enable_high_resolution_fifo(struct inv_ixm42xxx * s)
1409 {
1410 #if (INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1411 int status = 0;
1412 uint8_t data;
1413
1414 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1415 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_HIRES_EN;
1416 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1417 #endif
1418
1419 /* set FIFO packets to 20bit format (i.e. high res is enabled) */
1420 s->fifo_highres_enabled = 1;
1421
1422 return 0;
1423 }
1424
1425 int inv_ixm42xxx_disable_high_resolution_fifo(struct inv_ixm42xxx * s)
1426 {
1427 #if (INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1428 int status = 0;
1429 uint8_t data;
1430
1431 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1432 data |= (uint8_t)~BIT_FIFO_CONFIG1_HIRES_MASK; /* == IXM42XXX_FIFO_CONFIG1_HIRES_DIS */
1433 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1434 #endif
1435
1436 /* set FIFO packets to 16bit format (i.e. high res is disabled) */
1437 s->fifo_highres_enabled = 0;
1438
1439 return 0;
1440 }
1441
1442 int inv_ixm42xxx_configure_fifo(struct inv_ixm42xxx * s, INV_IXM42XXX_FIFO_CONFIG_t fifo_config)
1443 {
1444 int status = 0;
1445 uint8_t data;
1446 inv_ixm42xxx_interrupt_parameter_t config_int = {(inv_ixm42xxx_interrupt_value)0};
1447
1448 s->fifo_is_used = fifo_config;
1449
1450 switch (fifo_config) {
1451
1452 case INV_IXM42XXX_FIFO_ENABLED :
1453 /* Configure:
1454 * - FIFO record mode i.e FIFO count unit is packet
1455 * - FIFO snapshot mode i.e drop the data when the FIFO overflows
1456 * - Timestamp is logged in FIFO
1457 * - Little Endian fifo_count
1458 */
1459 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG0, 1, &data);
1460 data |= (uint8_t)IXM42XXX_INTF_CONFIG0_FIFO_COUNT_REC_RECORD;
1461 data &= (uint8_t)~BIT_FIFO_COUNT_ENDIAN_MASK; // little endian
1462 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG0, 1, &data);
1463 data = (uint8_t)IXM42XXX_FIFO_CONFIG_MODE_STOP_ON_FULL;
1464 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG, 1, &data);
1465 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &data);
1466 data |= IXM42XXX_TMST_CONFIG_TMST_EN;
1467 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &data);
1468
1469 #if (!INV_IXM42XXX_LIGHTWEIGHT_DRIVER)
1470 /* restart and reset FIFO configuration */
1471 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1472 data &= (uint8_t)~(BIT_FIFO_CONFIG1_GYRO_MASK | BIT_FIFO_CONFIG1_ACCEL_MASK);
1473 data |= (BIT_FIFO_CONFIG1_TEMP_MASK | BIT_FIFO_CONFIG1_TMST_FSYNC_MASK);
1474 #else
1475 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1476 data |= (BIT_FIFO_CONFIG1_GYRO_MASK | BIT_FIFO_CONFIG1_ACCEL_MASK | BIT_FIFO_CONFIG1_TEMP_MASK | BIT_FIFO_CONFIG1_TMST_FSYNC_MASK);
1477 #endif
1478 /* Set fifo_wm_int_w generating condition : fifo_wm_int_w generated when counter >= threshold */
1479 data |= (uint8_t)IXM42XXX_FIFO_CONFIG1_WM_GT_TH_EN;
1480 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1481 /* Configure FIFO WM so that INT is triggered for each packet */
1482 data = 0x1;
1483 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG2, 1, &data);
1484
1485 /* Disable Data Ready Interrupt */
1486 status |= inv_ixm42xxx_get_config_int1(s, &config_int);
1487 config_int.INV_IXM42XXX_UI_DRDY = INV_IXM42XXX_DISABLE;
1488 status |= inv_ixm42xxx_set_config_int1(s, &config_int);
1489 break;
1490
1491 case INV_IXM42XXX_FIFO_DISABLED :
1492 /* make sure FIFO is disabled */
1493 data = IXM42XXX_FIFO_CONFIG_MODE_BYPASS;
1494 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG, 1, &data);
1495
1496 /* restart and reset FIFO configuration */
1497 status |= inv_ixm42xxx_read_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1498 data &= (uint8_t)~(BIT_FIFO_CONFIG1_GYRO_MASK | BIT_FIFO_CONFIG1_ACCEL_MASK);
1499 data |= (BIT_FIFO_CONFIG1_TEMP_MASK | BIT_FIFO_CONFIG1_TMST_FSYNC_MASK);
1500 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG1, 1, &data);
1501
1502 /* Enable Data Ready Interrupt */
1503 status |= inv_ixm42xxx_get_config_int1(s, &config_int);
1504 config_int.INV_IXM42XXX_UI_DRDY = INV_IXM42XXX_ENABLE;
1505 status |= inv_ixm42xxx_set_config_int1(s, &config_int);
1506 break;
1507
1508 default :
1509 status = -1;
1510 }
1511 return status;
1512 }
1513
1514 int inv_ixm42xxx_configure_fifo_wm(struct inv_ixm42xxx * s, uint16_t wm)
1515 {
1516 int status = 0;
1517 inv_ixm42xxx_interrupt_parameter_t config_int1;
1518 inv_ixm42xxx_interrupt_parameter_t config_int2;
1519 inv_ixm42xxx_interrupt_parameter_t config_ibi;
1520 inv_ixm42xxx_interrupt_value fifo_ths_int1_bk;
1521 inv_ixm42xxx_interrupt_value fifo_ths_int2_bk;
1522 inv_ixm42xxx_interrupt_value fifo_ths_ibi_bk;
1523
1524 /* WM is coded on 12 bits so check that 4 MSb are 0 */
1525 if ((wm & 0xF000) != 0)
1526 return INV_ERROR_BAD_ARG;
1527
1528 /* FIFO WM interrupt must be disabled before being configured */
1529 status |= inv_ixm42xxx_get_config_int1(s, &config_int1);
1530 status |= inv_ixm42xxx_get_config_int2(s, &config_int2);
1531 status |= inv_ixm42xxx_get_config_ibi(s, &config_ibi);
1532
1533 /* backup INT configuration */
1534 fifo_ths_int1_bk = config_int1.INV_IXM42XXX_FIFO_THS;
1535 fifo_ths_int2_bk = config_int2.INV_IXM42XXX_FIFO_THS;
1536 fifo_ths_ibi_bk = config_ibi.INV_IXM42XXX_FIFO_THS;
1537
1538 /* Disable FIFO WM */
1539 if (config_int1.INV_IXM42XXX_FIFO_THS == INV_IXM42XXX_ENABLE) {
1540 config_int1.INV_IXM42XXX_FIFO_THS = INV_IXM42XXX_DISABLE;
1541 status |= inv_ixm42xxx_set_config_int1(s, &config_int1);
1542 }
1543 if (config_int2.INV_IXM42XXX_FIFO_THS == INV_IXM42XXX_ENABLE) {
1544 config_int2.INV_IXM42XXX_FIFO_THS = INV_IXM42XXX_DISABLE;
1545 status |= inv_ixm42xxx_set_config_int2(s, &config_int2);
1546 }
1547 if (config_ibi.INV_IXM42XXX_FIFO_THS == INV_IXM42XXX_ENABLE) {
1548 config_ibi.INV_IXM42XXX_FIFO_THS = INV_IXM42XXX_DISABLE;
1549 status |= inv_ixm42xxx_set_config_ibi(s, &config_ibi);
1550 }
1551
1552 /* Write FIFO WM */
1553 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG2, 2, (uint8_t *)&wm);
1554
1555 /* Restore initial INT config if necessary */
1556 if (fifo_ths_int1_bk != config_int1.INV_IXM42XXX_FIFO_THS) {
1557 config_int1.INV_IXM42XXX_FIFO_THS = fifo_ths_int1_bk;
1558 status |= inv_ixm42xxx_set_config_int1(s, &config_int1);
1559 }
1560 if (fifo_ths_int2_bk != config_int2.INV_IXM42XXX_FIFO_THS) {
1561 config_int2.INV_IXM42XXX_FIFO_THS = fifo_ths_int2_bk;
1562 status |= inv_ixm42xxx_set_config_int2(s, &config_int2);
1563 }
1564 if (fifo_ths_ibi_bk != config_ibi.INV_IXM42XXX_FIFO_THS) {
1565 config_ibi.INV_IXM42XXX_FIFO_THS = fifo_ths_ibi_bk;
1566 status |= inv_ixm42xxx_set_config_ibi(s, &config_ibi);
1567 }
1568
1569 return status;
1570 }
1571
1572 uint32_t inv_ixm42xxx_get_fifo_timestamp_resolution_us_q24(struct inv_ixm42xxx * s)
1573 {
1574 int status = 0;
1575 uint8_t tmst_cfg_reg;
1576 IXM42XXX_TMST_CONFIG_RESOL_t tmst_resol;
1577 uint32_t scale_factor_q24 = 1<<24;
1578
1579 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &tmst_cfg_reg);
1580 if (status < 0)
1581 return INV_ERROR;
1582
1583 tmst_resol = (IXM42XXX_TMST_CONFIG_RESOL_t)(tmst_cfg_reg & BIT_TMST_CONFIG_RESOL_MASK);
1584
1585 /* RTC is enabled, the resolution of the timestamp is one tick of RTC
1586 * RTC runs at 32768 Hz, so resolution is 1/32768 s, or 1000000/32768 us
1587 */
1588 if (inv_ixm42xxx_get_clkin_rtc_status(s))
1589 return ((1000000UL<<12)/32768UL)<<(24-12);
1590
1591 /* PLL scale factor doesn't apply when WU oscillator is in use */
1592 if (!inv_ixm42xxx_is_wu_osc_active(s))
1593 scale_factor_q24 = PLL_SCALE_FACTOR_Q24;
1594
1595 if (tmst_resol == IXM42XXX_TMST_CONFIG_RESOL_16us)
1596 return 16 * scale_factor_q24;
1597 else if (tmst_resol == IXM42XXX_TMST_CONFIG_RESOL_1us)
1598 return 1 * scale_factor_q24;
1599
1600 /* Should not happen, return 0 */
1601 return 0;
1602 }
1603
1604 uint32_t inv_ixm42xxx_get_reg_timestamp_resolution_us_q24(struct inv_ixm42xxx * s)
1605 {
1606 uint32_t scale_factor_q24 = 1<<24;
1607
1608 /* RTC is enabled, the resolution of the timestamp is one tick of RTC
1609 * Our RTC runs at 32768 Hz, so resolution is 1/32768 s, or 1000000/32768 us
1610 */
1611 if (inv_ixm42xxx_get_clkin_rtc_status(s))
1612 return ((1000000UL<<12)/32768UL)<<(24-12);
1613
1614 /* PLL scale factor doesn't apply when WU oscillator is in use */
1615 if (!inv_ixm42xxx_is_wu_osc_active(s))
1616 scale_factor_q24 = PLL_SCALE_FACTOR_Q24;
1617
1618 return 1 * scale_factor_q24;
1619 }
1620
1621 const char * inv_ixm42xxx_get_version(void)
1622 {
1623 return INV_IXM42XXX_VERSION_STRING;
1624 }
1625
1626 /*
1627 * Static functions definition
1628 */
1629 static int inv_ixm42xxx_configure_serial_interface(struct inv_ixm42xxx * s)
1630 {
1631 int status = 0;
1632 uint8_t value;
1633
1634 /* Set memory bank 1 */
1635 status |= inv_ixm42xxx_set_reg_bank(s, 1);
1636
1637 switch(s->transport.serif.serif_type) {
1638
1639 case IXM42XXX_UI_I2C:
1640 /* Enable I2C 50ns spike filtering */
1641 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &value);
1642 value &= (uint8_t)~(BIT_INTF_CONFIG6_I3C_SDR_EN_MASK | BIT_INTF_CONFIG6_I3C_DDR_EN_MASK);
1643 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &value);
1644 break;
1645
1646 case IXM42XXX_UI_I3C:
1647 /* Enable In Band Interrupt for I3C UI interface and associated payload byte and assign dynamic address */
1648 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &value);
1649 value |= (BIT_INTF_CONFIG6_I3C_IBI_BYTE_EN_MASK | BIT_INTF_CONFIG6_I3C_IBI_EN_MASK);
1650 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG6_B1, 1, &value);
1651 status |= s->transport.serif.configure((struct inv_ixm42xxx_serif *)s);
1652 break;
1653
1654 case IXM42XXX_UI_SPI4:
1655 value = IXM42XXX_INTF_CONFIG4_AP_SPI4W;
1656 status |= inv_ixm42xxx_write_reg(s, MPUREG_INTF_CONFIG4_B1, 1, &value);
1657 break;
1658
1659 default:
1660 status |= INV_ERROR_BAD_ARG;
1661 }
1662
1663 /* Set memory bank 0 */
1664 status |= inv_ixm42xxx_set_reg_bank(s, 0);
1665
1666 return status;
1667 }
1668
1669 static int inv_ixm42xxx_init_hardware_from_ui(struct inv_ixm42xxx * s)
1670 {
1671 uint8_t data;
1672 int status = 0;
1673 uint8_t wom_threshold[3];
1674 uint8_t gyro_cfg_0_reg, accel_cfg_0_reg, tmst_cfg_reg;
1675 inv_ixm42xxx_interrupt_parameter_t config_int = {
1676 .INV_IXM42XXX_UI_FSYNC = INV_IXM42XXX_DISABLE,
1677 .INV_IXM42XXX_UI_DRDY = INV_IXM42XXX_DISABLE,
1678 .INV_IXM42XXX_FIFO_THS = INV_IXM42XXX_ENABLE,
1679 .INV_IXM42XXX_FIFO_FULL = INV_IXM42XXX_DISABLE,
1680 .INV_IXM42XXX_SMD = INV_IXM42XXX_ENABLE,
1681 .INV_IXM42XXX_WOM_X = INV_IXM42XXX_ENABLE,
1682 .INV_IXM42XXX_WOM_Y = INV_IXM42XXX_ENABLE,
1683 .INV_IXM42XXX_WOM_Z = INV_IXM42XXX_ENABLE,
1684 .INV_IXM42XXX_STEP_DET = INV_IXM42XXX_ENABLE,
1685 .INV_IXM42XXX_STEP_CNT_OVFL = INV_IXM42XXX_ENABLE,
1686 .INV_IXM42XXX_TILT_DET = INV_IXM42XXX_ENABLE,
1687 .INV_IXM42XXX_SLEEP_DET = INV_IXM42XXX_ENABLE,
1688 .INV_IXM42XXX_WAKE_DET = INV_IXM42XXX_ENABLE,
1689 .INV_IXM42XXX_TAP_DET = INV_IXM42XXX_ENABLE,
1690 };
1691
1692 status |= inv_ixm42xxx_device_reset(s);
1693
1694 /* Setup MEMs properties */
1695 status |= inv_ixm42xxx_read_reg(s, MPUREG_GYRO_CONFIG0, 1, &gyro_cfg_0_reg);
1696 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1697 gyro_cfg_0_reg &= (uint8_t)~BIT_GYRO_CONFIG0_FS_SEL_MASK;
1698 gyro_cfg_0_reg |= (uint8_t)IXM42XXX_GYRO_CONFIG0_FS_SEL_2000dps;
1699 accel_cfg_0_reg &= (uint8_t)~BIT_ACCEL_CONFIG0_FS_SEL_MASK;
1700 accel_cfg_0_reg |= (uint8_t)IXM42XXX_ACCEL_CONFIG0_FS_SEL_4g;
1701 status |= inv_ixm42xxx_write_reg(s, MPUREG_GYRO_CONFIG0, 1, &gyro_cfg_0_reg);
1702 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG0, 1, &accel_cfg_0_reg);
1703
1704 /* make sure FIFO is disabled */
1705 data = IXM42XXX_FIFO_CONFIG_MODE_BYPASS;
1706 status |= inv_ixm42xxx_write_reg(s, MPUREG_FIFO_CONFIG, 1, &data);
1707
1708 /* Deactivate FSYNC by default */
1709 status |= inv_ixm42xxx_read_reg(s, MPUREG_FSYNC_CONFIG, 1, &data);
1710 data &= (uint8_t)~BIT_FSYNC_CONFIG_UI_SEL_MASK;
1711 status |= inv_ixm42xxx_write_reg(s, MPUREG_FSYNC_CONFIG, 1, &data);
1712
1713 status |= inv_ixm42xxx_read_reg(s, MPUREG_TMST_CONFIG, 1, &tmst_cfg_reg);
1714 tmst_cfg_reg &= (uint8_t)~BIT_TMST_CONFIG_TMST_FSYNC_MASK; // == IXM42XXX_FSYNC_CONFIG_UI_SEL_NO
1715 status |= inv_ixm42xxx_write_reg(s, MPUREG_TMST_CONFIG, 1, &tmst_cfg_reg);
1716
1717 /* Set default timestamp resolution 16us (Mobile use cases) */
1718 status |= inv_ixm42xxx_configure_timestamp_resolution(s, IXM42XXX_TMST_CONFIG_RESOL_16us);
1719
1720 status |= inv_ixm42xxx_configure_fifo(s, INV_IXM42XXX_FIFO_ENABLED);
1721
1722 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_CONFIG, 1, &data);
1723 /* Enable push pull on INT1 to avoid moving in Test Mode after a soft reset */
1724 data |= (uint8_t)IXM42XXX_INT_CONFIG_INT1_DRIVE_CIRCUIT_PP;
1725 /* Configure the INT1 interrupt pulse as active high */
1726 data |= (uint8_t)IXM42XXX_INT_CONFIG_INT1_POLARITY_HIGH;
1727 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_CONFIG, 1, &data);
1728
1729 /* Set interrupt config */
1730 status |= inv_ixm42xxx_set_config_int1(s,&config_int);
1731 config_int.INV_IXM42XXX_UI_DRDY = INV_IXM42XXX_ENABLE;
1732 config_int.INV_IXM42XXX_FIFO_THS = INV_IXM42XXX_DISABLE;
1733 status |= inv_ixm42xxx_set_config_ibi(s,&config_int);
1734
1735 /* Set the ASY_RESET_DISABLE bit to 0 (async enabled) in order to chop Tpulse as soon as interrupt status is read
1736 * Guideline is to set the ASY_RESET_DISABLE bit to 0 in pulse mode
1737 * No effect in latch mode */
1738 status |= inv_ixm42xxx_read_reg(s, MPUREG_INT_CONFIG1, 1, &data);
1739 data &= (uint8_t)~BIT_INT_CONFIG1_ASY_RST_MASK;
1740 data |= (uint8_t)IXM42XXX_INT_CONFIG1_ASY_RST_ENABLED;
1741 status |= inv_ixm42xxx_write_reg(s, MPUREG_INT_CONFIG1, 1, &data);
1742
1743 /* Set the UI filter order to 2 for both gyro and accel */
1744 status |= inv_ixm42xxx_read_reg(s, MPUREG_GYRO_CONFIG1, 1, &data);
1745 data &= (uint8_t)~BIT_GYRO_CONFIG1_GYRO_UI_FILT_ORD_MASK;
1746 data |= (uint8_t)IXM42XXX_GYRO_CONFIG_GYRO_UI_FILT_ORD_2ND_ORDER;
1747 status |= inv_ixm42xxx_write_reg(s, MPUREG_GYRO_CONFIG1, 1, &data);
1748 status |= inv_ixm42xxx_read_reg(s, MPUREG_ACCEL_CONFIG1, 1, &data);
1749 data &= (uint8_t)~BIT_ACCEL_CONFIG1_ACCEL_UI_FILT_ORD_MASK;
1750 data |= (uint8_t)IXM42XXX_ACCEL_CONFIG_ACCEL_UI_FILT_ORD_2ND_ORDER;
1751 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_CONFIG1, 1, &data);
1752
1753 /* FIFO packets are 16bit format by default (i.e. high res is disabled) */
1754 status |= inv_ixm42xxx_disable_high_resolution_fifo(s);
1755
1756 /* For retro-compatibility, configure WOM to compare current sample with the previous sample and to produce signal when all axis exceed 52 mg */
1757 status |= inv_ixm42xxx_set_reg_bank(s, 4); /* Set memory bank 4 */
1758 wom_threshold[0] = IXM42XXX_DEFAULT_WOM_THS_MG; /* Set X threshold */
1759 wom_threshold[1] = IXM42XXX_DEFAULT_WOM_THS_MG; /* Set Y threshold */
1760 wom_threshold[2] = IXM42XXX_DEFAULT_WOM_THS_MG; /* Set Z threshold */
1761 status |= inv_ixm42xxx_write_reg(s, MPUREG_ACCEL_WOM_X_THR_B4, sizeof(wom_threshold), &wom_threshold[0]);
1762
1763 status |= inv_ixm42xxx_set_reg_bank(s, 0); /* Set memory bank 0 */
1764 data = ((uint8_t)IXM42XXX_SMD_CONFIG_WOM_INT_MODE_ANDED) | ((uint8_t)IXM42XXX_SMD_CONFIG_WOM_MODE_CMP_PREV);
1765 status |= inv_ixm42xxx_write_reg(s, MPUREG_SMD_CONFIG, 1, &data);
1766
1767 /* by default, set IIR filter BW to ODR/4 for LN, 16x averaging for GLP, 16x averaging for ALP */
1768 s->avg_bw_setting.acc_ln_bw = (uint8_t)IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_4;
1769 s->avg_bw_setting.gyr_ln_bw = (uint8_t)IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_4;
1770 s->avg_bw_setting.acc_lp_avg = (uint8_t)IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_16;
1771
1772 /* Reset self-test result variable*/
1773 s->st_result = 0;
1774
1775 /* Configure Gyro in Periodic reset */
1776 status |= inv_ixm42xxx_set_reg_bank(s, 3); /* Set memory bank 3 */
1777
1778 /* Reg AMP_GSXYZ_TRIM0 */
1779 status |= inv_ixm42xxx_read_reg(s, 0x2E, 1, &data);
1780 data &= 0xfd;
1781 status |= inv_ixm42xxx_write_reg(s, 0x2E, 1, &data);
1782
1783 /* Reg AMP_GX_TRIM2 */
1784 status |= inv_ixm42xxx_read_reg(s, 0x32, 1, &data);
1785 data &= 0x9f;
1786 status |= inv_ixm42xxx_write_reg(s, 0x32, 1, &data);
1787
1788 /* Reg AMP_GY_TRIM2 */
1789 status |= inv_ixm42xxx_read_reg(s, 0x37, 1, &data);
1790 data &= 0x9f;
1791 status |= inv_ixm42xxx_write_reg(s, 0x37, 1, &data);
1792
1793 /* Reg AMP_GZ_TRIM2 */
1794 status |= inv_ixm42xxx_read_reg(s, 0x3C, 1, &data);
1795 data &= 0x9f;
1796 status |= inv_ixm42xxx_write_reg(s, 0x3C, 1, &data);
1797
1798 status |= inv_ixm42xxx_set_reg_bank(s, 0); /* Set memory bank 0 */
1799
1800 return status;
1801 }
1802
1803 static int inv_ixm42xxx_is_wu_osc_active(struct inv_ixm42xxx * s)
1804 {
1805 int status = 0;
1806 uint8_t pwr_mngt0_reg;
1807 uint8_t intf_cfg_1_reg;
1808
1809 /* WU oscillator is active is Accel is enabled alone, in LP, with lp_clk_sel sets to WU_OSC */
1810 IXM42XXX_PWR_MGMT_0_GYRO_MODE_t gyr_mode;
1811 IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t acc_mode;
1812 IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t lp_clk;
1813
1814 status |= inv_ixm42xxx_read_reg(s, MPUREG_PWR_MGMT_0, 1, &pwr_mngt0_reg);
1815 status |= inv_ixm42xxx_read_reg(s, MPUREG_INTF_CONFIG1, 1, &intf_cfg_1_reg);
1816 gyr_mode = (IXM42XXX_PWR_MGMT_0_GYRO_MODE_t) (pwr_mngt0_reg & BIT_PWR_MGMT_0_GYRO_MODE_MASK);
1817 acc_mode = (IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t) (pwr_mngt0_reg & BIT_PWR_MGMT_0_ACCEL_MODE_MASK);
1818 lp_clk = (IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t) (intf_cfg_1_reg & BIT_ACCEL_LP_CLK_SEL_MASK);
1819
1820
1821 return ( (gyr_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF || gyr_mode == IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY) /* Gyro is off or standby */
1822 && (acc_mode == IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP) /* Accel is enabled in LP */
1823 && (lp_clk == IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC)); /* WU oscillator is selected */
1824 }
1825
1826 /* Default implementation converts ICM endian to little endian */
1827 static void inv_ixm42xxx_format_data(const uint8_t endian, const uint8_t *in, uint16_t *out)
1828 {
1829 if(endian == IXM42XXX_INTF_CONFIG0_DATA_BIG_ENDIAN)
1830 *out = (in[0] << 8) | in[1];
1831 else
1832 *out = (in[1] << 8) | in[0];
1833 }
inv_ixm42xxx_configure_fifo_wm
int inv_ixm42xxx_configure_fifo_wm(struct inv_ixm42xxx *s, uint16_t wm)
Configure Fifo watermark (also refered to as fifo threshold)
Definition: Ixm42xxxDriver_HL.c:1514
PLL_SCALE_FACTOR_Q24
#define PLL_SCALE_FACTOR_Q24
Scale factor and max ODR Dependant of chip.
Definition: Ixm42xxxDriver_HL.h:76
IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_t
IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_t
Definition: Ixm42xxxDefs.h:848
inv_ixm42xxx_interrupt_parameter_t
Ixm42xxx set of interrupt enable flag.
Definition: Ixm42xxxDriver_HL.h:230
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_WAKE_DET
inv_ixm42xxx_interrupt_value INV_IXM42XXX_WAKE_DET
Definition: Ixm42xxxDriver_HL.h:243
MPUREG_ACCEL_WOM_X_THR_B4
#define MPUREG_ACCEL_WOM_X_THR_B4
Definition: Ixm42xxxDefs.h:186
BIT_INT_SOURCE0_FIFO_THS_INT1_EN
#define BIT_INT_SOURCE0_FIFO_THS_INT1_EN
Definition: Ixm42xxxDefs.h:1148
inv_ixm42xxx_disable_gyro
int inv_ixm42xxx_disable_gyro(struct inv_ixm42xxx *s)
Disable all 3 axes of gyro.
Definition: Ixm42xxxDriver_HL.c:485
IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LN
@ IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LN
Definition: Ixm42xxxDefs.h:677
inv_ixm42xxx_set_accel_frequency
int inv_ixm42xxx_set_accel_frequency(struct inv_ixm42xxx *s, const IXM42XXX_ACCEL_CONFIG0_ODR_t frequency)
Configure accel Output Data Rate.
Definition: Ixm42xxxDriver_HL.c:1127
BIT_INT_SOURCE1_WOM_Y_INT1_EN
#define BIT_INT_SOURCE1_WOM_Y_INT1_EN
Definition: Ixm42xxxDefs.h:1163
inv_ixm42xxx::fifo_is_used
INV_IXM42XXX_FIFO_CONFIG_t fifo_is_used
Definition: Ixm42xxxDriver_HL.h:187
BIT_INT_SOURCE7_STEP_CNT_OVFL_INT2_EN
#define BIT_INT_SOURCE7_STEP_CNT_OVFL_INT2_EN
Definition: Ixm42xxxDefs.h:1908
ACCEL_CONFIG0_FS_SEL_MAX
#define ACCEL_CONFIG0_FS_SEL_MAX
Max FSR values for accel and gyro Dependant of chip.
Definition: Ixm42xxxDriver_HL.h:90
IXM42XXX_TMST_CONFIG_RESOL_16us
@ IXM42XXX_TMST_CONFIG_RESOL_16us
Definition: Ixm42xxxDefs.h:900
inv_ixm42xxx::accel_start_time_us
uint64_t accel_start_time_us
Definition: Ixm42xxxDriver_HL.h:184
inv_ixm42xxx_enable_accel_low_noise_mode
int inv_ixm42xxx_enable_accel_low_noise_mode(struct inv_ixm42xxx *s)
Enable/put accel in low noise mode.
Definition: Ixm42xxxDriver_HL.c:267
MPUREG_GYRO_DATA_X0_UI
#define MPUREG_GYRO_DATA_X0_UI
Definition: Ixm42xxxDefs.h:92
fifo_header_t::msg_bit
unsigned char msg_bit
Definition: Ixm42xxxDefs.h:253
BIT_INT_SOURCE8_UI_DRDY_IBI_EN
#define BIT_INT_SOURCE8_UI_DRDY_IBI_EN
Definition: Ixm42xxxDefs.h:1929
inv_ixm42xxx_get_accel_fsr
int inv_ixm42xxx_get_accel_fsr(struct inv_ixm42xxx *s, IXM42XXX_ACCEL_CONFIG0_FS_SEL_t *accel_fsr_g)
Access accel full scale range.
Definition: Ixm42xxxDriver_HL.c:1189
FIFO_20BYTES_PACKET_SIZE
#define FIFO_20BYTES_PACKET_SIZE
Definition: Ixm42xxxDefs.h:224
BIT_DATA_ENDIAN_MASK
#define BIT_DATA_ENDIAN_MASK
Definition: Ixm42xxxDefs.h:582
BIT_INT_CONFIG1_ASY_RST_MASK
#define BIT_INT_CONFIG1_ASY_RST_MASK
Definition: Ixm42xxxDefs.h:1124
IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY
@ IXM42XXX_PWR_MGMT_0_GYRO_MODE_STANDBY
Definition: Ixm42xxxDefs.h:667
BIT_INTF_CONFIG6_I3C_SDR_EN_MASK
#define BIT_INTF_CONFIG6_I3C_SDR_EN_MASK
Definition: Ixm42xxxDefs.h:1335
INV_IXM42XXX_ENABLE
@ INV_IXM42XXX_ENABLE
Definition: Ixm42xxxDriver_HL.h:225
IXM42XXX_SMD_CONFIG_WOM_INT_MODE_ANDED
@ IXM42XXX_SMD_CONFIG_WOM_INT_MODE_ANDED
Definition: Ixm42xxxDefs.h:1003
FIFO_ACCEL_DATA_SIZE
#define FIFO_ACCEL_DATA_SIZE
Definition: Ixm42xxxDefs.h:216
BIT_GYRO_CONFIG0_ODR_MASK
#define BIT_GYRO_CONFIG0_ODR_MASK
Definition: Ixm42xxxDefs.h:718
MPUREG_INT_SOURCE0
#define MPUREG_INT_SOURCE0
Definition: Ixm42xxxDefs.h:126
inv_ixm42xxx_get_config_int2
int inv_ixm42xxx_get_config_int2(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Retrieve interrupts configuration.
Definition: Ixm42xxxDriver_HL.c:653
fifo_header_t::bits
struct fifo_header_t::@0 bits
MPUREG_WHO_AM_I
#define MPUREG_WHO_AM_I
Definition: Ixm42xxxDefs.h:134
Ixm42xxxDefs.h
inv_ixm42xxx
Ixm42xxx driver states definition.
Definition: Ixm42xxxDriver_HL.h:164
inv_ixm42xxx_init_transport
int inv_ixm42xxx_init_transport(struct inv_ixm42xxx *s)
Init cache variable.
Definition: Ixm42xxxTransport.c:35
INV_IXM42XXX_SENSOR_TEMPERATURE
@ INV_IXM42XXX_SENSOR_TEMPERATURE
Definition: Ixm42xxxDriver_HL.h:133
MPUREG_INT_CONFIG1
#define MPUREG_INT_CONFIG1
Definition: Ixm42xxxDefs.h:125
inv_ixm42xxx::tmst_to_reg_en_cnt
uint8_t tmst_to_reg_en_cnt
Definition: Ixm42xxxDriver_HL.h:179
IXM42XXX_TMST_CONFIG_TMST_FSYNC_DIS
@ IXM42XXX_TMST_CONFIG_TMST_FSYNC_DIS
Definition: Ixm42xxxDefs.h:911
inv_ixm42xxx_set_accel_fsr
int inv_ixm42xxx_set_accel_fsr(struct inv_ixm42xxx *s, IXM42XXX_ACCEL_CONFIG0_FS_SEL_t accel_fsr_g)
Set accel full scale range.
Definition: Ixm42xxxDriver_HL.c:1165
BIT_INT_SOURCE7_STEP_DET_INT2_EN
#define BIT_INT_SOURCE7_STEP_DET_INT2_EN
Definition: Ixm42xxxDefs.h:1907
MPUREG_TMST_CONFIG
#define MPUREG_TMST_CONFIG
Definition: Ixm42xxxDefs.h:118
inv_ixm42xxx_sleep_us
void inv_ixm42xxx_sleep_us(uint32_t us)
Hook for low-level high res system sleep() function to be implemented by upper layer ~100us resolutio...
BIT_INTF_CONFIG5_GPIO_PAD_SEL_POS
#define BIT_INTF_CONFIG5_GPIO_PAD_SEL_POS
Definition: Ixm42xxxDefs.h:1321
BIT_INT_SOURCE7_TAP_DET_INT2_EN
#define BIT_INT_SOURCE7_TAP_DET_INT2_EN
Definition: Ixm42xxxDefs.h:1912
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_UI_FSYNC
inv_ixm42xxx_interrupt_value INV_IXM42XXX_UI_FSYNC
Definition: Ixm42xxxDriver_HL.h:231
Ixm42xxxVersion.h
IXM42XXX_GYRO_CONFIG_GYRO_UI_FILT_ORD_2ND_ORDER
@ IXM42XXX_GYRO_CONFIG_GYRO_UI_FILT_ORD_2ND_ORDER
Definition: Ixm42xxxDefs.h:807
INVALID_VALUE_FIFO
#define INVALID_VALUE_FIFO
Definition: Ixm42xxxDefs.h:237
BIT_INT_WOM_Y_INT_EN_POS
#define BIT_INT_WOM_Y_INT_EN_POS
Definition: Ixm42xxxDefs.h:1158
MPUREG_ACCEL_GYRO_CONFIG0
#define MPUREG_ACCEL_GYRO_CONFIG0
Definition: Ixm42xxxDefs.h:116
BIT_FIFO_CONFIG1_HIRES_MASK
#define BIT_FIFO_CONFIG1_HIRES_MASK
Definition: Ixm42xxxDefs.h:1048
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_FIFO_THS
inv_ixm42xxx_interrupt_value INV_IXM42XXX_FIFO_THS
Definition: Ixm42xxxDriver_HL.h:233
inv_ixm42xxx::wu_off_acc_odr_changes
uint32_t wu_off_acc_odr_changes
Definition: Ixm42xxxDriver_HL.h:205
IXM42XXX_INT_CONFIG1_ASY_RST_ENABLED
@ IXM42XXX_INT_CONFIG1_ASY_RST_ENABLED
Definition: Ixm42xxxDefs.h:1129
IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t
IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t
Definition: Ixm42xxxDefs.h:620
inv_ixm42xxx_sensor_event_t
Sensor event structure definition.
Definition: Ixm42xxxDriver_HL.h:152
inv_ixm42xxx_reset_fifo
int inv_ixm42xxx_reset_fifo(struct inv_ixm42xxx *s)
reset IXM42XXX fifo
Definition: Ixm42xxxDriver_HL.c:1270
fifo_header_t::twentybits_bit
unsigned char twentybits_bit
Definition: Ixm42xxxDefs.h:250
inv_ixm42xxx_enable_accel_low_power_mode
int inv_ixm42xxx_enable_accel_low_power_mode(struct inv_ixm42xxx *s)
Enable/put accel in low power mode.
Definition: Ixm42xxxDriver_HL.c:158
INV_IXM42XXX_SENSOR_ACCEL
@ INV_IXM42XXX_SENSOR_ACCEL
Definition: Ixm42xxxDriver_HL.h:129
BIT_INT_SOURCE10_TAP_DET_IBI_EN
#define BIT_INT_SOURCE10_TAP_DET_IBI_EN
Definition: Ixm42xxxDefs.h:1964
inv_ixm42xxx_configure_timestamp_resolution
int inv_ixm42xxx_configure_timestamp_resolution(struct inv_ixm42xxx *s, IXM42XXX_TMST_CONFIG_RESOL_t resol)
Configure timestamp resolution from FIFO.
Definition: Ixm42xxxDriver_HL.c:577
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_WOM_X
inv_ixm42xxx_interrupt_value INV_IXM42XXX_WOM_X
Definition: Ixm42xxxDriver_HL.h:236
inv_ixm42xxx::acc_lp_avg
uint8_t acc_lp_avg
Definition: Ixm42xxxDriver_HL.h:213
IXM42XXX_ACCEL_CONFIG0_ODR_12_5_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_12_5_HZ
Definition: Ixm42xxxDefs.h:778
BIT_INT_SOURCE10_TILT_DET_IBI_EN
#define BIT_INT_SOURCE10_TILT_DET_IBI_EN
Definition: Ixm42xxxDefs.h:1961
inv_ixm42xxx_enable_fsync
int inv_ixm42xxx_enable_fsync(struct inv_ixm42xxx *s)
Enable fsync tagging functionnality. In details it:
Definition: Ixm42xxxDriver_HL.c:548
inv_ixm42xxx_interrupt_value
inv_ixm42xxx_interrupt_value
Definition: Ixm42xxxDriver_HL.h:223
BIT_INT_SOURCE9_SMD_IBI_EN
#define BIT_INT_SOURCE9_SMD_IBI_EN
Definition: Ixm42xxxDefs.h:1943
BIT_INT_SOURCE1_WOM_Z_INT1_EN
#define BIT_INT_SOURCE1_WOM_Z_INT1_EN
Definition: Ixm42xxxDefs.h:1162
BIT_INT_STATUS_FIFO_FULL
#define BIT_INT_STATUS_FIFO_FULL
Definition: Ixm42xxxDefs.h:397
IXM42XXX_TMST_CONFIG_TMST_TO_REGS_EN
@ IXM42XXX_TMST_CONFIG_TMST_TO_REGS_EN
Definition: Ixm42xxxDefs.h:890
BIT_INT_SOURCE9_WOM_Z_IBI_EN
#define BIT_INT_SOURCE9_WOM_Z_IBI_EN
Definition: Ixm42xxxDefs.h:1944
BIT_INT_STATUS_FIFO_THS
#define BIT_INT_STATUS_FIFO_THS
Definition: Ixm42xxxDefs.h:396
MPUREG_GYRO_CONFIG1
#define MPUREG_GYRO_CONFIG1
Definition: Ixm42xxxDefs.h:115
BIT_INT_STATUS_DRDY
#define BIT_INT_STATUS_DRDY
Definition: Ixm42xxxDefs.h:395
IXM42XXX_INTF_CONFIG4_AP_SPI4W
@ IXM42XXX_INTF_CONFIG4_AP_SPI4W
Definition: Ixm42xxxDefs.h:1311
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_t
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_t
Definition: Ixm42xxxDefs.h:826
BIT_INT_SLEEP_DET_INT_EN_POS
#define BIT_INT_SLEEP_DET_INT_EN_POS
Definition: Ixm42xxxDefs.h:1893
INV_IXM42XXX_FIFO_CONFIG_t
INV_IXM42XXX_FIFO_CONFIG_t
Configure Fifo usage.
Definition: Ixm42xxxDriver_HL.h:145
inv_ixm42xxx_sensor_event_t::sensor_mask
int sensor_mask
Definition: Ixm42xxxDriver_HL.h:153
inv_ixm42xxx::fifo_highres_enabled
uint8_t fifo_highres_enabled
Definition: Ixm42xxxDriver_HL.h:186
MPUREG_FIFO_COUNTH
#define MPUREG_FIFO_COUNTH
Definition: Ixm42xxxDefs.h:96
IXM42XXX_INT_CONFIG_INT1_DRIVE_CIRCUIT_PP
@ IXM42XXX_INT_CONFIG_INT1_DRIVE_CIRCUIT_PP
Definition: Ixm42xxxDefs.h:357
inv_ixm42xxx_set_gyro_fsr
int inv_ixm42xxx_set_gyro_fsr(struct inv_ixm42xxx *s, IXM42XXX_GYRO_CONFIG0_FS_SEL_t gyro_fsr_dps)
Set gyro full scale range.
Definition: Ixm42xxxDriver_HL.c:1177
inv_ixm42xxx_disable_fsync
int inv_ixm42xxx_disable_fsync(struct inv_ixm42xxx *s)
Disable fsync tagging functionnality. In details it:
Definition: Ixm42xxxDriver_HL.c:562
inv_ixm42xxx::st_result
int st_result
Definition: Ixm42xxxDriver_HL.h:175
MPUREG_INT_STATUS
#define MPUREG_INT_STATUS
Definition: Ixm42xxxDefs.h:95
BIT_INT_FIFO_THS_IBI_EN_POS
#define BIT_INT_FIFO_THS_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1922
IXM42XXX_ACCEL_CONFIG0_ODR_1_5625_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_1_5625_HZ
Definition: Ixm42xxxDefs.h:775
IXM42XXX_GYRO_CONFIG0_FS_SEL_t
IXM42XXX_GYRO_CONFIG0_FS_SEL_t
Gyroscope FSR selection.
Definition: Ixm42xxxDefs.h:694
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_SLEEP_DET
inv_ixm42xxx_interrupt_value INV_IXM42XXX_SLEEP_DET
Definition: Ixm42xxxDriver_HL.h:242
BIT_INT_FIFO_FULL_INT_EN_POS
#define BIT_INT_FIFO_FULL_INT_EN_POS
Definition: Ixm42xxxDefs.h:1141
BIT_INT_SOURCE4_WOM_Y_INT2_EN
#define BIT_INT_SOURCE4_WOM_Y_INT2_EN
Definition: Ixm42xxxDefs.h:1195
BIT_GYRO_CONFIG0_FS_SEL_MASK
#define BIT_GYRO_CONFIG0_FS_SEL_MASK
Definition: Ixm42xxxDefs.h:689
IXM42XXX_ACCEL_CONFIG0_ODR_4_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_4_KHZ
Definition: Ixm42xxxDefs.h:785
ACCEL_DATA_SIZE
#define ACCEL_DATA_SIZE
Definition: Ixm42xxxDefs.h:211
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_STEP_CNT_OVFL
inv_ixm42xxx_interrupt_value INV_IXM42XXX_STEP_CNT_OVFL
Definition: Ixm42xxxDriver_HL.h:240
BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK
#define BIT_GYRO_ACCEL_CONFIG0_ACCEL_FILT_MASK
Definition: Ixm42xxxDefs.h:823
GYRO_CONFIG0_FS_SEL_MAX
#define GYRO_CONFIG0_FS_SEL_MAX
Definition: Ixm42xxxDriver_HL.h:91
BIT_FIFO_CONFIG1_TEMP_MASK
#define BIT_FIFO_CONFIG1_TEMP_MASK
Definition: Ixm42xxxDefs.h:1068
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_TILT_DET
inv_ixm42xxx_interrupt_value INV_IXM42XXX_TILT_DET
Definition: Ixm42xxxDriver_HL.h:241
BIT_ACCEL_CONFIG1_ACCEL_UI_FILT_ORD_MASK
#define BIT_ACCEL_CONFIG1_ACCEL_UI_FILT_ORD_MASK
Definition: Ixm42xxxDefs.h:866
inv_ixm42xxx::acc_ln_bw
uint8_t acc_ln_bw
Definition: Ixm42xxxDriver_HL.h:215
inv_ixm42xxx_get_clkin_rtc_status
int inv_ixm42xxx_get_clkin_rtc_status(struct inv_ixm42xxx *s)
Get CLKIN/RTC feature status.
Definition: Ixm42xxxDriver_HL.c:1396
BIT_FIFO_COUNT_ENDIAN_MASK
#define BIT_FIFO_COUNT_ENDIAN_MASK
Definition: Ixm42xxxDefs.h:572
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_SMD
inv_ixm42xxx_interrupt_value INV_IXM42XXX_SMD
Definition: Ixm42xxxDriver_HL.h:235
BIT_INT_SOURCE1_WOM_X_INT1_EN
#define BIT_INT_SOURCE1_WOM_X_INT1_EN
Definition: Ixm42xxxDefs.h:1164
Ixm42xxxExtFunc.h
MPUREG_REG_BANK_SEL
#define MPUREG_REG_BANK_SEL
Definition: Ixm42xxxDefs.h:135
inv_ixm42xxx::fifo_data
uint8_t fifo_data[IXM42XXX_FIFO_MIRRORING_SIZE]
Definition: Ixm42xxxDriver_HL.h:177
INV_IXM42XXX_FIFO_DISABLED
@ INV_IXM42XXX_FIFO_DISABLED
Definition: Ixm42xxxDriver_HL.h:146
MPUREG_INTF_CONFIG6_B1
#define MPUREG_INTF_CONFIG6_B1
Definition: Ixm42xxxDefs.h:148
MPUREG_ACCEL_CONFIG0
#define MPUREG_ACCEL_CONFIG0
Definition: Ixm42xxxDefs.h:114
IXM42XXX_ACCEL_CONFIG0_ODR_8_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_8_KHZ
Definition: Ixm42xxxDefs.h:786
TEMP_DATA_SIZE
#define TEMP_DATA_SIZE
Definition: Ixm42xxxDefs.h:213
IXM42XXX_GYR_STARTUP_TIME_US
#define IXM42XXX_GYR_STARTUP_TIME_US
Ixm42xxx Gyroscope start-up time before having correct data.
Definition: Ixm42xxxDriver_HL.h:124
inv_ixm42xxx_configure_fifo
int inv_ixm42xxx_configure_fifo(struct inv_ixm42xxx *s, INV_IXM42XXX_FIFO_CONFIG_t fifo_config)
Configure Fifo to select the way data are gathered.
Definition: Ixm42xxxDriver_HL.c:1442
MPUREG_INTF_CONFIG5_B1
#define MPUREG_INTF_CONFIG5_B1
Definition: Ixm42xxxDefs.h:147
inv_ixm42xxx_set_accel_lp_avg
int inv_ixm42xxx_set_accel_lp_avg(struct inv_ixm42xxx *s, IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_t acc_avg)
Set accel Low-Power averaging value.
Definition: Ixm42xxxDriver_HL.c:1219
BIT_INT_STEP_CNT_OVFL_IBI_EN_POS
#define BIT_INT_STEP_CNT_OVFL_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1953
inv_ixm42xxx_set_accel_ln_bw
int inv_ixm42xxx_set_accel_ln_bw(struct inv_ixm42xxx *s, IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_t acc_bw)
Set accel Low-Noise bandwidth value.
Definition: Ixm42xxxDriver_HL.c:1236
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_FIFO_FULL
inv_ixm42xxx_interrupt_value INV_IXM42XXX_FIFO_FULL
Definition: Ixm42xxxDriver_HL.h:234
BIT_INT_SOURCE0_UI_DRDY_INT1_EN
#define BIT_INT_SOURCE0_UI_DRDY_INT1_EN
Definition: Ixm42xxxDefs.h:1147
Ixm42xxxTransport.h
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_WOM_Z
inv_ixm42xxx_interrupt_value INV_IXM42XXX_WOM_Z
Definition: Ixm42xxxDriver_HL.h:238
BIT_INT_STATUS_RESET_DONE
#define BIT_INT_STATUS_RESET_DONE
Definition: Ixm42xxxDefs.h:394
inv_ixm42xxx_get_version
const char * inv_ixm42xxx_get_version(void)
Return driver version x.y.z-suffix as a char array.
Definition: Ixm42xxxDriver_HL.c:1621
BIT_INTF_CONFIG6_I3C_IBI_EN_MASK
#define BIT_INTF_CONFIG6_I3C_IBI_EN_MASK
Definition: Ixm42xxxDefs.h:1348
BIT_INT_FIFO_THS_INT_EN_POS
#define BIT_INT_FIFO_THS_INT_EN_POS
Definition: Ixm42xxxDefs.h:1140
inv_ixm42xxx_disable_accel
int inv_ixm42xxx_disable_accel(struct inv_ixm42xxx *s)
Disable all 3 axes of accel.
Definition: Ixm42xxxDriver_HL.c:345
BIT_INT_STEP_DET_IBI_EN_POS
#define BIT_INT_STEP_DET_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1952
BIT_PWR_MGMT_0_GYRO_MODE_MASK
#define BIT_PWR_MGMT_0_GYRO_MODE_MASK
Definition: Ixm42xxxDefs.h:662
inv_ixm42xxx_get_config_int1
int inv_ixm42xxx_get_config_int1(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Retrieve interrupts configuration.
Definition: Ixm42xxxDriver_HL.c:620
IXM42XXX_DEFAULT_WOM_THS_MG
#define IXM42XXX_DEFAULT_WOM_THS_MG
Default value for the WOM threshold Resolution of the threshold is ~= 4mg.
Definition: Ixm42xxxDriver_HL.h:116
FIFO_TEMP_DATA_SIZE
#define FIFO_TEMP_DATA_SIZE
Definition: Ixm42xxxDefs.h:218
IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_4
@ IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_4
Definition: Ixm42xxxDefs.h:855
BIT_INT_WAKE_DET_INT_EN_POS
#define BIT_INT_WAKE_DET_INT_EN_POS
Definition: Ixm42xxxDefs.h:1892
inv_ixm42xxx_device_reset
int inv_ixm42xxx_device_reset(struct inv_ixm42xxx *s)
Perform a soft reset of the device.
Definition: Ixm42xxxDriver_HL.c:79
MPUREG_FIFO_DATA
#define MPUREG_FIFO_DATA
Definition: Ixm42xxxDefs.h:100
BIT_INT_SOURCE3_FIFO_FULL_INT2_EN
#define BIT_INT_SOURCE3_FIFO_FULL_INT2_EN
Definition: Ixm42xxxDefs.h:1186
IXM42XXX_INTF_CONFIG0_DATA_LITTLE_ENDIAN
@ IXM42XXX_INTF_CONFIG0_DATA_LITTLE_ENDIAN
Definition: Ixm42xxxDefs.h:587
IXM42XXX_ACCEL_CONFIG0_ODR_1_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_1_KHZ
Definition: Ixm42xxxDefs.h:783
BIT_INT_SOURCE6_SLEEP_DET_INT1_EN
#define BIT_INT_SOURCE6_SLEEP_DET_INT1_EN
Definition: Ixm42xxxDefs.h:1900
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_UI_DRDY
inv_ixm42xxx_interrupt_value INV_IXM42XXX_UI_DRDY
Definition: Ixm42xxxDriver_HL.h:232
MPUREG_TEMP_DATA0_UI
#define MPUREG_TEMP_DATA0_UI
Definition: Ixm42xxxDefs.h:90
BIT_INT_UI_DRDY_IBI_EN_POS
#define BIT_INT_UI_DRDY_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1921
IXM42XXX_PWR_MGMT_0_GYRO_MODE_LN
@ IXM42XXX_PWR_MGMT_0_GYRO_MODE_LN
Definition: Ixm42xxxDefs.h:666
IXM42XXX_ACCEL_CONFIG0_ODR_50_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_50_HZ
Definition: Ixm42xxxDefs.h:780
fifo_header_t
Definition: Ixm42xxxDefs.h:242
BIT_INT_SOURCE10_STEP_DET_IBI_EN
#define BIT_INT_SOURCE10_STEP_DET_IBI_EN
Definition: Ixm42xxxDefs.h:1959
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_WOM_Y
inv_ixm42xxx_interrupt_value INV_IXM42XXX_WOM_Y
Definition: Ixm42xxxDriver_HL.h:237
BIT_INT_SOURCE6_STEP_DET_INT1_EN
#define BIT_INT_SOURCE6_STEP_DET_INT1_EN
Definition: Ixm42xxxDefs.h:1896
BIT_INT_UI_FSYNC_INT_EN_POS
#define BIT_INT_UI_FSYNC_INT_EN_POS
Definition: Ixm42xxxDefs.h:1136
IXM42XXX_ACCEL_CONFIG0_ODR_25_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_25_HZ
Definition: Ixm42xxxDefs.h:779
BIT_INT_SOURCE3_UI_FSYNC_INT2_EN
#define BIT_INT_SOURCE3_UI_FSYNC_INT2_EN
Definition: Ixm42xxxDefs.h:1181
BIT_INT_SOURCE3_UI_DRDY_INT2_EN
#define BIT_INT_SOURCE3_UI_DRDY_INT2_EN
Definition: Ixm42xxxDefs.h:1184
BIT_FIFO_CONFIG1_ACCEL_MASK
#define BIT_FIFO_CONFIG1_ACCEL_MASK
Definition: Ixm42xxxDefs.h:1088
inv_ixm42xxx_sensor_event_t::accel
int16_t accel[3]
Definition: Ixm42xxxDriver_HL.h:155
BIT_INT_TAP_DET_IBI_EN_POS
#define BIT_INT_TAP_DET_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1957
MPUREG_INT_CONFIG
#define MPUREG_INT_CONFIG
Definition: Ixm42xxxDefs.h:88
BIT_INT_SOURCE0_FIFO_FULL_INT1_EN
#define BIT_INT_SOURCE0_FIFO_FULL_INT1_EN
Definition: Ixm42xxxDefs.h:1149
Ixm42xxxDriver_HL.h
inv_ixm42xxx::sensor_event_cb
void(* sensor_event_cb)(inv_ixm42xxx_sensor_event_t *event)
Definition: Ixm42xxxDriver_HL.h:168
BIT_FIFO_CONFIG1_GYRO_MASK
#define BIT_FIFO_CONFIG1_GYRO_MASK
Definition: Ixm42xxxDefs.h:1078
inv_ixm42xxx::avg_bw_setting
struct inv_ixm42xxx::@0 avg_bw_setting
BIT_PWR_MGMT_0_ACCEL_MODE_MASK
#define BIT_PWR_MGMT_0_ACCEL_MODE_MASK
Definition: Ixm42xxxDefs.h:673
fifo_header_t::timestamp_bit
unsigned char timestamp_bit
Definition: Ixm42xxxDefs.h:249
inv_ixm42xxx_get_gyro_fsr
int inv_ixm42xxx_get_gyro_fsr(struct inv_ixm42xxx *s, IXM42XXX_GYRO_CONFIG0_FS_SEL_t *gyro_fsr_dps)
Access gyro full scale range.
Definition: Ixm42xxxDriver_HL.c:1204
IXM42XXX_INT_CONFIG_INT1_POLARITY_HIGH
@ IXM42XXX_INT_CONFIG_INT1_POLARITY_HIGH
Definition: Ixm42xxxDefs.h:367
BIT_RTC_MODE_MASK
#define BIT_RTC_MODE_MASK
Definition: Ixm42xxxDefs.h:627
INV_IXM42XXX_DISABLE
@ INV_IXM42XXX_DISABLE
Definition: Ixm42xxxDriver_HL.h:224
IXM42XXX_PWR_MGMT_0_GYRO_MODE_t
IXM42XXX_PWR_MGMT_0_GYRO_MODE_t
Definition: Ixm42xxxDefs.h:665
BIT_ACCEL_CONFIG0_ODR_MASK
#define BIT_ACCEL_CONFIG0_ODR_MASK
Definition: Ixm42xxxDefs.h:768
BIT_INT_FIFO_FULL_IBI_EN_POS
#define BIT_INT_FIFO_FULL_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1923
FIFO_TS_FSYNC_SIZE
#define FIFO_TS_FSYNC_SIZE
Definition: Ixm42xxxDefs.h:219
BIT_INT_SOURCE3_FIFO_THS_INT2_EN
#define BIT_INT_SOURCE3_FIFO_THS_INT2_EN
Definition: Ixm42xxxDefs.h:1185
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_TAP_DET
inv_ixm42xxx_interrupt_value INV_IXM42XXX_TAP_DET
Definition: Ixm42xxxDriver_HL.h:244
inv_ixm42xxx_get_current_timestamp
int inv_ixm42xxx_get_current_timestamp(struct inv_ixm42xxx *s, uint32_t *icm_time)
Get the timestamp value of ixm42xxx from register.
Definition: Ixm42xxxDriver_HL.c:1341
IXM42XXX_TMST_CONFIG_RESOL_1us
@ IXM42XXX_TMST_CONFIG_RESOL_1us
Definition: Ixm42xxxDefs.h:901
BIT_INT_SOURCE6_STEP_CNT_OVFL_INT1_EN
#define BIT_INT_SOURCE6_STEP_CNT_OVFL_INT1_EN
Definition: Ixm42xxxDefs.h:1897
inv_ixm42xxx_serif
basesensor serial interface
Definition: Ixm42xxxTransport.h:61
IXM42XXX_INTF_CONFIG1_RTC_MODE_EN
@ IXM42XXX_INTF_CONFIG1_RTC_MODE_EN
Definition: Ixm42xxxDefs.h:632
inv_ixm42xxx_disable_timestamp_to_register
int inv_ixm42xxx_disable_timestamp_to_register(struct inv_ixm42xxx *s)
Disable the 20bits-timestamp register access. Register read always return 0's.
Definition: Ixm42xxxDriver_HL.c:1324
IXM42XXX_SMD_CONFIG_WOM_MODE_CMP_PREV
@ IXM42XXX_SMD_CONFIG_WOM_MODE_CMP_PREV
Definition: Ixm42xxxDefs.h:1013
IXM42XXX_ACCEL_CONFIG0_ODR_6_25_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_6_25_HZ
Definition: Ixm42xxxDefs.h:777
IXM42XXX_DEVICE_CONFIG_RESET_EN
@ IXM42XXX_DEVICE_CONFIG_RESET_EN
Definition: Ixm42xxxDefs.h:316
MPUREG_SMD_CONFIG
#define MPUREG_SMD_CONFIG
Definition: Ixm42xxxDefs.h:120
IXM42XXX_SIGNAL_PATH_RESET_FIFO_FLUSH_EN
@ IXM42XXX_SIGNAL_PATH_RESET_FIFO_FLUSH_EN
Definition: Ixm42xxxDefs.h:541
IXM42XXX_ACCEL_CONFIG0_ODR_200_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_200_HZ
Definition: Ixm42xxxDefs.h:782
IXM42XXX_ACCEL_CONFIG0_ODR_3_125_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_3_125_HZ
Definition: Ixm42xxxDefs.h:776
IXM42XXX_FIFO_CONFIG1_GYRO_EN
@ IXM42XXX_FIFO_CONFIG1_GYRO_EN
Definition: Ixm42xxxDefs.h:1082
inv_ixm42xxx_get_who_am_i
int inv_ixm42xxx_get_who_am_i(struct inv_ixm42xxx *s, uint8_t *who_am_i)
return WHOAMI value
Definition: Ixm42xxxDriver_HL.c:138
MPUREG_FSYNC_CONFIG
#define MPUREG_FSYNC_CONFIG
Definition: Ixm42xxxDefs.h:123
BIT_INT_SOURCE4_WOM_X_INT2_EN
#define BIT_INT_SOURCE4_WOM_X_INT2_EN
Definition: Ixm42xxxDefs.h:1196
MPUREG_PWR_MGMT_0
#define MPUREG_PWR_MGMT_0
Definition: Ixm42xxxDefs.h:112
FIFO_GYRO_DATA_SIZE
#define FIFO_GYRO_DATA_SIZE
Definition: Ixm42xxxDefs.h:217
BIT_INT_SOURCE7_TILT_DET_INT2_EN
#define BIT_INT_SOURCE7_TILT_DET_INT2_EN
Definition: Ixm42xxxDefs.h:1909
inv_ixm42xxx_transport::serif
struct inv_ixm42xxx_serif serif
Definition: Ixm42xxxTransport.h:74
IXM42XXX_ACCEL_CONFIG0_ODR_16_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_16_KHZ
Definition: Ixm42xxxDefs.h:787
IXM42XXX_TMST_CONFIG_TMST_TO_REGS_DIS
@ IXM42XXX_TMST_CONFIG_TMST_TO_REGS_DIS
Definition: Ixm42xxxDefs.h:891
MPUREG_FIFO_CONFIG
#define MPUREG_FIFO_CONFIG
Definition: Ixm42xxxDefs.h:89
MPUREG_INT_SOURCE8_B4
#define MPUREG_INT_SOURCE8_B4
Definition: Ixm42xxxDefs.h:191
FIFO_ACCEL_GYRO_HIGH_RES_SIZE
#define FIFO_ACCEL_GYRO_HIGH_RES_SIZE
Definition: Ixm42xxxDefs.h:221
BIT_INT_SOURCE9_WOM_X_IBI_EN
#define BIT_INT_SOURCE9_WOM_X_IBI_EN
Definition: Ixm42xxxDefs.h:1946
BIT_INT_WOM_Z_INT_EN_POS
#define BIT_INT_WOM_Z_INT_EN_POS
Definition: Ixm42xxxDefs.h:1157
inv_ixm42xxx_set_gyro_frequency
int inv_ixm42xxx_set_gyro_frequency(struct inv_ixm42xxx *s, const IXM42XXX_GYRO_CONFIG0_ODR_t frequency)
Configure gyro Output Data Rate.
Definition: Ixm42xxxDriver_HL.c:1153
BIT_INTF_CONFIG5_GPIO_PAD_SEL_MASK
#define BIT_INTF_CONFIG5_GPIO_PAD_SEL_MASK
Definition: Ixm42xxxDefs.h:1322
BIT_INTF_CONFIG6_I3C_IBI_BYTE_EN_MASK
#define BIT_INTF_CONFIG6_I3C_IBI_BYTE_EN_MASK
Definition: Ixm42xxxDefs.h:1344
BIT_INT_STEP_DET_INT_EN_POS
#define BIT_INT_STEP_DET_INT_EN_POS
Definition: Ixm42xxxDefs.h:1889
BIT_INT_TILT_DET_INT_EN_POS
#define BIT_INT_TILT_DET_INT_EN_POS
Definition: Ixm42xxxDefs.h:1891
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_16
@ IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_16
Definition: Ixm42xxxDefs.h:839
IXM42XXX_SIGNAL_PATH_RESET_TMST_STROBE_EN
@ IXM42XXX_SIGNAL_PATH_RESET_TMST_STROBE_EN
Definition: Ixm42xxxDefs.h:531
BIT_INT_SMD_IBI_EN_POS
#define BIT_INT_SMD_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1938
inv_ixm42xxx::fsync_to_be_ignored
uint8_t fsync_to_be_ignored
Definition: Ixm42xxxDriver_HL.h:195
BIT_INT_SOURCE0_UI_FSYNC_INT1_EN
#define BIT_INT_SOURCE0_UI_FSYNC_INT1_EN
Definition: Ixm42xxxDefs.h:1144
inv_ixm42xxx_serif::configure
int(* configure)(struct inv_ixm42xxx_serif *serif)
Definition: Ixm42xxxTransport.h:65
IXM42XXX_INTF_CONFIG1_RTC_MODE_DIS
@ IXM42XXX_INTF_CONFIG1_RTC_MODE_DIS
Definition: Ixm42xxxDefs.h:631
inv_ixm42xxx::transport
struct inv_ixm42xxx_transport transport
Definition: Ixm42xxxDriver_HL.h:165
fifo_header_t::fsync_bit
unsigned char fsync_bit
Definition: Ixm42xxxDefs.h:248
IXM42XXX_GYRO_CONFIG0_ODR_t
IXM42XXX_GYRO_CONFIG0_ODR_t
Gyroscope ODR selection.
Definition: Ixm42xxxDefs.h:723
inv_ixm42xxx_disable_high_resolution_fifo
int inv_ixm42xxx_disable_high_resolution_fifo(struct inv_ixm42xxx *s)
Disable 20 bits raw acc and raw gyr data in fifo.
Definition: Ixm42xxxDriver_HL.c:1425
BIT_INT_WOM_Z_IBI_EN_POS
#define BIT_INT_WOM_Z_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1939
inv_ixm42xxx::gyr_ln_bw
uint8_t gyr_ln_bw
Definition: Ixm42xxxDriver_HL.h:216
BIT_GYRO_ACCEL_CONFIG0_GYRO_FILT_MASK
#define BIT_GYRO_ACCEL_CONFIG0_GYRO_FILT_MASK
Definition: Ixm42xxxDefs.h:845
BIT_FSYNC_CONFIG_UI_SEL_MASK
#define BIT_FSYNC_CONFIG_UI_SEL_MASK
Definition: Ixm42xxxDefs.h:1103
IXM42XXX_GYRO_CONFIG0_FS_SEL_2000dps
@ IXM42XXX_GYRO_CONFIG0_FS_SEL_2000dps
Definition: Ixm42xxxDefs.h:712
BIT_ACCEL_CONFIG0_FS_SEL_MASK
#define BIT_ACCEL_CONFIG0_FS_SEL_MASK
Definition: Ixm42xxxDefs.h:745
INVALID_VALUE_FIFO_1B
#define INVALID_VALUE_FIFO_1B
Definition: Ixm42xxxDefs.h:238
inv_ixm42xxx_get_data_from_fifo
int inv_ixm42xxx_get_data_from_fifo(struct inv_ixm42xxx *s)
Read all available packets from the FIFO. For each packet function builds a sensor event containing p...
Definition: Ixm42xxxDriver_HL.c:877
MPUREG_INT_SOURCE7_B4
#define MPUREG_INT_SOURCE7_B4
Definition: Ixm42xxxDefs.h:190
MPUREG_ACCEL_CONFIG1
#define MPUREG_ACCEL_CONFIG1
Definition: Ixm42xxxDefs.h:117
MPUREG_INT_SOURCE6_B4
#define MPUREG_INT_SOURCE6_B4
Definition: Ixm42xxxDefs.h:189
MPUREG_INTF_CONFIG1
#define MPUREG_INTF_CONFIG1
Definition: Ixm42xxxDefs.h:111
inv_ixm42xxx_get_config_ibi
int inv_ixm42xxx_get_config_ibi(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Retrieve interrupts configuration.
Definition: Ixm42xxxDriver_HL.c:590
IXM42XXX_FIFO_CONFIG1_HIRES_EN
@ IXM42XXX_FIFO_CONFIG1_HIRES_EN
Definition: Ixm42xxxDefs.h:1052
BIT_INT_SOURCE10_STEP_CNT_OVFL_IBI_EN
#define BIT_INT_SOURCE10_STEP_CNT_OVFL_IBI_EN
Definition: Ixm42xxxDefs.h:1960
BIT_FIFO_CONFIG1_TMST_FSYNC_MASK
#define BIT_FIFO_CONFIG1_TMST_FSYNC_MASK
Definition: Ixm42xxxDefs.h:1058
IXM42XXX_TMST_CONFIG_TMST_EN
@ IXM42XXX_TMST_CONFIG_TMST_EN
Definition: Ixm42xxxDefs.h:920
MPUREG_INT_SOURCE3
#define MPUREG_INT_SOURCE3
Definition: Ixm42xxxDefs.h:129
BIT_INT_SOURCE8_UI_FSYNC_IBI_EN
#define BIT_INT_SOURCE8_UI_FSYNC_IBI_EN
Definition: Ixm42xxxDefs.h:1927
MPUREG_FIFO_CONFIG1
#define MPUREG_FIFO_CONFIG1
Definition: Ixm42xxxDefs.h:121
IXM42XXX_ACCEL_CONFIG0_ODR_t
IXM42XXX_ACCEL_CONFIG0_ODR_t
Accelerometer ODR selection.
Definition: Ixm42xxxDefs.h:773
BIT_GYRO_CONFIG1_GYRO_UI_FILT_ORD_MASK
#define BIT_GYRO_CONFIG1_GYRO_UI_FILT_ORD_MASK
Definition: Ixm42xxxDefs.h:802
BIT_INT_WOM_Y_IBI_EN_POS
#define BIT_INT_WOM_Y_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1940
IXM42XXX_UI_SPI4
@ IXM42XXX_UI_SPI4
Definition: Ixm42xxxTransport.h:52
IXM42XXX_TMST_CONFIG_TMST_FSYNC_EN
@ IXM42XXX_TMST_CONFIG_TMST_FSYNC_EN
Definition: Ixm42xxxDefs.h:910
IXM42XXX_ACCEL_CONFIG0_FS_SEL_t
IXM42XXX_ACCEL_CONFIG0_FS_SEL_t
Accelerometer FSR selection.
Definition: Ixm42xxxDefs.h:750
BIT_INT_SOURCE8_FIFO_THS_IBI_EN
#define BIT_INT_SOURCE8_FIFO_THS_IBI_EN
Definition: Ixm42xxxDefs.h:1930
inv_ixm42xxx_enable_gyro_low_noise_mode
int inv_ixm42xxx_enable_gyro_low_noise_mode(struct inv_ixm42xxx *s)
Enable/put gyro in low noise mode.
Definition: Ixm42xxxDriver_HL.c:391
IXM42XXX_FIFO_CONFIG1_WM_GT_TH_EN
@ IXM42XXX_FIFO_CONFIG1_WM_GT_TH_EN
Definition: Ixm42xxxDefs.h:1042
INV_IXM42XXX_FIFO_ENABLED
@ INV_IXM42XXX_FIFO_ENABLED
Definition: Ixm42xxxDriver_HL.h:147
BIT_INT_SOURCE6_TILT_DET_INT1_EN
#define BIT_INT_SOURCE6_TILT_DET_INT1_EN
Definition: Ixm42xxxDefs.h:1898
IXM42XXX_UI_I3C
@ IXM42XXX_UI_I3C
Definition: Ixm42xxxTransport.h:53
BIT_INT_SOURCE6_TAP_DET_INT1_EN
#define BIT_INT_SOURCE6_TAP_DET_INT1_EN
Definition: Ixm42xxxDefs.h:1901
inv_ixm42xxx_write_reg
int inv_ixm42xxx_write_reg(struct inv_ixm42xxx *s, uint8_t reg, uint32_t len, const uint8_t *buf)
Writes data to a register on Ixm42xxx.
Definition: Ixm42xxxTransport.c:86
IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF
@ IXM42XXX_PWR_MGMT_0_GYRO_MODE_OFF
Definition: Ixm42xxxDefs.h:668
inv_ixm42xxx_sensor_event_t::temperature
int16_t temperature
Definition: Ixm42xxxDriver_HL.h:157
IXM42XXX_ACCEL_CONFIG0_ODR_2_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_2_KHZ
Definition: Ixm42xxxDefs.h:784
inv_ixm42xxx_convert_odr_bitfield_to_us
uint32_t inv_ixm42xxx_convert_odr_bitfield_to_us(uint32_t odr_bitfield)
Converts IXM42XXX_ACCEL_CONFIG0_ODR_t or IXM42XXX_GYRO_CONFIG0_ODR_t enums to period expressed in us.
Definition: Ixm42xxxDriver_HL.c:1085
inv_ixm42xxx_set_config_int2
int inv_ixm42xxx_set_config_int2(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Configure which interrupt source can trigger INT2.
Definition: Ixm42xxxDriver_HL.c:780
MPUREG_GYRO_CONFIG0
#define MPUREG_GYRO_CONFIG0
Definition: Ixm42xxxDefs.h:113
MPUREG_SIGNAL_PATH_RESET
#define MPUREG_SIGNAL_PATH_RESET
Definition: Ixm42xxxDefs.h:109
IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t
IXM42XXX_PWR_MGMT_0_ACCEL_MODE_t
Definition: Ixm42xxxDefs.h:676
inv_ixm42xxx_set_gyro_ln_bw
int inv_ixm42xxx_set_gyro_ln_bw(struct inv_ixm42xxx *s, IXM42XXX_GYRO_ACCEL_CONFIG0_GYRO_FILT_BW_t gyr_bw)
Set gyro Low-Noise bandwidth value.
Definition: Ixm42xxxDriver_HL.c:1253
BIT_INT_SOURCE7_WAKE_DET_INT2_EN
#define BIT_INT_SOURCE7_WAKE_DET_INT2_EN
Definition: Ixm42xxxDefs.h:1910
BIT_INT_TILT_DET_IBI_EN_POS
#define BIT_INT_TILT_DET_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1954
FIFO_HEADER_SIZE
#define FIFO_HEADER_SIZE
Definition: Ixm42xxxDefs.h:215
IXM42XXX_ACCEL_CONFIG_ACCEL_UI_FILT_ORD_2ND_ORDER
@ IXM42XXX_ACCEL_CONFIG_ACCEL_UI_FILT_ORD_2ND_ORDER
Definition: Ixm42xxxDefs.h:871
BIT_INT_SOURCE1_SMD_INT1_EN
#define BIT_INT_SOURCE1_SMD_INT1_EN
Definition: Ixm42xxxDefs.h:1161
IXM42XXX_FIFO_CONFIG1_ACCEL_EN
@ IXM42XXX_FIFO_CONFIG1_ACCEL_EN
Definition: Ixm42xxxDefs.h:1092
MPUREG_TMST_VAL0_B1
#define MPUREG_TMST_VAL0_B1
Definition: Ixm42xxxDefs.h:145
BIT_TMST_CONFIG_RESOL_MASK
#define BIT_TMST_CONFIG_RESOL_MASK
Definition: Ixm42xxxDefs.h:896
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_4
@ IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_BW_4
Definition: Ixm42xxxDefs.h:833
BIT_INT_SOURCE8_FIFO_FULL_IBI_EN
#define BIT_INT_SOURCE8_FIFO_FULL_IBI_EN
Definition: Ixm42xxxDefs.h:1931
inv_ixm42xxx_set_reg_bank
int inv_ixm42xxx_set_reg_bank(struct inv_ixm42xxx *s, uint8_t bank)
Set register bank index.
Definition: Ixm42xxxDriver_HL.c:35
inv_ixm42xxx_get_time_us
uint64_t inv_ixm42xxx_get_time_us(void)
Hook for low-level high res system get_time() function to be implemented by upper layer Timer should ...
FIFO_TEMP_HIGH_RES_SIZE
#define FIFO_TEMP_HIGH_RES_SIZE
Definition: Ixm42xxxDefs.h:220
BIT_INTF_CONFIG6_I3C_DDR_EN_MASK
#define BIT_INTF_CONFIG6_I3C_DDR_EN_MASK
Definition: Ixm42xxxDefs.h:1331
IXM42XXX_TMST_CONFIG_RESOL_t
IXM42XXX_TMST_CONFIG_RESOL_t
Definition: Ixm42xxxDefs.h:899
fifo_header_t::accel_bit
unsigned char accel_bit
Definition: Ixm42xxxDefs.h:252
fifo_header_t::gyro_bit
unsigned char gyro_bit
Definition: Ixm42xxxDefs.h:251
inv_ixm42xxx_read_reg
int inv_ixm42xxx_read_reg(struct inv_ixm42xxx *s, uint8_t reg, uint32_t len, uint8_t *buf)
Reads data from a register on Ixm42xxx.
Definition: Ixm42xxxTransport.c:54
inv_ixm42xxx_sensor_event_t::timestamp_fsync
uint16_t timestamp_fsync
Definition: Ixm42xxxDriver_HL.h:154
MPUREG_DEVICE_CONFIG
#define MPUREG_DEVICE_CONFIG
Definition: Ixm42xxxDefs.h:85
MPUREG_FIFO_CONFIG2
#define MPUREG_FIFO_CONFIG2
Definition: Ixm42xxxDefs.h:122
inv_ixm42xxx_enable_timestamp_to_register
int inv_ixm42xxx_enable_timestamp_to_register(struct inv_ixm42xxx *s)
Enable the 20bits-timestamp register access to read in a reliable way the strobed timestamp....
Definition: Ixm42xxxDriver_HL.c:1303
MPUREG_ACCEL_DATA_X0_UI
#define MPUREG_ACCEL_DATA_X0_UI
Definition: Ixm42xxxDefs.h:91
BIT_TMST_CONFIG_TMST_FSYNC_MASK
#define BIT_TMST_CONFIG_TMST_FSYNC_MASK
Definition: Ixm42xxxDefs.h:906
INV_IXM42XXX_VERSION_STRING
#define INV_IXM42XXX_VERSION_STRING
Definition: Ixm42xxxVersion.h:31
IXM42XXX_ACCEL_CONFIG0_ODR_500_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_500_HZ
Definition: Ixm42xxxDefs.h:774
inv_ixm42xxx_get_reg_timestamp_resolution_us_q24
uint32_t inv_ixm42xxx_get_reg_timestamp_resolution_us_q24(struct inv_ixm42xxx *s)
Get register timestamp resolution.
Definition: Ixm42xxxDriver_HL.c:1604
BIT_INT_SOURCE4_SMD_INT2_EN
#define BIT_INT_SOURCE4_SMD_INT2_EN
Definition: Ixm42xxxDefs.h:1193
BIT_TMST_CONFIG_TMST_TO_REGS_EN_MASK
#define BIT_TMST_CONFIG_TMST_TO_REGS_EN_MASK
Definition: Ixm42xxxDefs.h:886
BIT_ACCEL_LP_CLK_SEL_MASK
#define BIT_ACCEL_LP_CLK_SEL_MASK
Definition: Ixm42xxxDefs.h:617
IXM42XXX_ACCEL_CONFIG0_FS_SEL_4g
@ IXM42XXX_ACCEL_CONFIG0_FS_SEL_4g
Definition: Ixm42xxxDefs.h:760
IXM42XXX_INTF_CONFIG0_DATA_BIG_ENDIAN
@ IXM42XXX_INTF_CONFIG0_DATA_BIG_ENDIAN
Definition: Ixm42xxxDefs.h:586
BIT_INT_WOM_X_IBI_EN_POS
#define BIT_INT_WOM_X_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1941
IXM42XXX_ACC_STARTUP_TIME_US
#define IXM42XXX_ACC_STARTUP_TIME_US
Ixm42xxx Accelerometer start-up time before having correct data.
Definition: Ixm42xxxDriver_HL.h:120
inv_ixm42xxx_get_data_from_registers
int inv_ixm42xxx_get_data_from_registers(struct inv_ixm42xxx *s)
Read all registers containing data (tempereature, accelerometer and gyroscope). Then it calls sensor_...
Definition: Ixm42xxxDriver_HL.c:830
IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC
@ IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_RCOSC
Definition: Ixm42xxxDefs.h:622
inv_ixm42xxx_serif::serif_type
IXM42XXX_SERIAL_IF_TYPE_t serif_type
Definition: Ixm42xxxTransport.h:68
inv_ixm42xxx::gyro_start_time_us
uint64_t gyro_start_time_us
Definition: Ixm42xxxDriver_HL.h:183
BIT_INT_WOM_X_INT_EN_POS
#define BIT_INT_WOM_X_INT_EN_POS
Definition: Ixm42xxxDefs.h:1159
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_t
IXM42XXX_GYRO_ACCEL_CONFIG0_ACCEL_FILT_AVG_t
Definition: Ixm42xxxDefs.h:838
MPUREG_INTF_CONFIG0
#define MPUREG_INTF_CONFIG0
Definition: Ixm42xxxDefs.h:110
IXM42XXX_INTF_CONFIG0_FIFO_COUNT_REC_RECORD
@ IXM42XXX_INTF_CONFIG0_FIFO_COUNT_REC_RECORD
Definition: Ixm42xxxDefs.h:566
BIT_INT_UI_DRDY_INT_EN_POS
#define BIT_INT_UI_DRDY_INT_EN_POS
Definition: Ixm42xxxDefs.h:1139
IXM42XXX_ACCEL_CONFIG0_ODR_100_HZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_100_HZ
Definition: Ixm42xxxDefs.h:781
BIT_INT_SOURCE9_WOM_Y_IBI_EN
#define BIT_INT_SOURCE9_WOM_Y_IBI_EN
Definition: Ixm42xxxDefs.h:1945
inv_ixm42xxx_get_fifo_timestamp_resolution_us_q24
uint32_t inv_ixm42xxx_get_fifo_timestamp_resolution_us_q24(struct inv_ixm42xxx *s)
Get FIFO timestamp resolution.
Definition: Ixm42xxxDriver_HL.c:1572
IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP
@ IXM42XXX_PWR_MGMT_0_ACCEL_MODE_LP
Definition: Ixm42xxxDefs.h:678
BIT_INT_SMD_INT_EN_POS
#define BIT_INT_SMD_INT_EN_POS
Definition: Ixm42xxxDefs.h:1156
IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC
@ IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_WUOSC
Definition: Ixm42xxxDefs.h:621
INV_IXM42XXX_SENSOR_FSYNC_EVENT
@ INV_IXM42XXX_SENSOR_FSYNC_EVENT
Definition: Ixm42xxxDriver_HL.h:131
inv_ixm42xxx_init
int inv_ixm42xxx_init(struct inv_ixm42xxx *s, struct inv_ixm42xxx_serif *serif, void(*sensor_event_cb)(inv_ixm42xxx_sensor_event_t *event))
Configure the serial interface used to access the device and execute hardware initialization.
Definition: Ixm42xxxDriver_HL.c:40
inv_ixm42xxx::gyro_power_off_tmst
uint64_t gyro_power_off_tmst
Definition: Ixm42xxxDriver_HL.h:219
inv_ixm42xxx::endianess_data
uint8_t endianess_data
Definition: Ixm42xxxDriver_HL.h:185
BIT_INT_TAP_DET_INT_EN_POS
#define BIT_INT_TAP_DET_INT_EN_POS
Definition: Ixm42xxxDefs.h:1894
IXM42XXX_FIFO_CONFIG_MODE_STOP_ON_FULL
@ IXM42XXX_FIFO_CONFIG_MODE_STOP_ON_FULL
Definition: Ixm42xxxDefs.h:382
IXM42XXX_UI_I2C
@ IXM42XXX_UI_I2C
Definition: Ixm42xxxTransport.h:51
INV_IXM42XXX_SENSOR_GYRO
@ INV_IXM42XXX_SENSOR_GYRO
Definition: Ixm42xxxDriver_HL.h:130
BIT_INT_STEP_CNT_OVFL_INT_EN_POS
#define BIT_INT_STEP_CNT_OVFL_INT_EN_POS
Definition: Ixm42xxxDefs.h:1890
inv_ixm42xxx_set_config_int1
int inv_ixm42xxx_set_config_int1(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Configure which interrupt source can trigger INT1.
Definition: Ixm42xxxDriver_HL.c:730
inv_ixm42xxx_enable_high_resolution_fifo
int inv_ixm42xxx_enable_high_resolution_fifo(struct inv_ixm42xxx *s)
Enable 20 bits raw acc and raw gyr data in fifo.
Definition: Ixm42xxxDriver_HL.c:1408
BIT_INT_SOURCE6_WAKE_DET_INT1_EN
#define BIT_INT_SOURCE6_WAKE_DET_INT1_EN
Definition: Ixm42xxxDefs.h:1899
GYRO_DATA_SIZE
#define GYRO_DATA_SIZE
Definition: Ixm42xxxDefs.h:212
MPUREG_INTF_CONFIG4_B1
#define MPUREG_INTF_CONFIG4_B1
Definition: Ixm42xxxDefs.h:146
BIT_INT_SOURCE4_WOM_Z_INT2_EN
#define BIT_INT_SOURCE4_WOM_Z_INT2_EN
Definition: Ixm42xxxDefs.h:1194
IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF
@ IXM42XXX_PWR_MGMT_0_ACCEL_MODE_OFF
Definition: Ixm42xxxDefs.h:679
IXM42XXX_FIFO_CONFIG_MODE_BYPASS
@ IXM42XXX_FIFO_CONFIG_MODE_BYPASS
Definition: Ixm42xxxDefs.h:384
BIT_INT_SOURCE7_SLEEP_DET_INT2_EN
#define BIT_INT_SOURCE7_SLEEP_DET_INT2_EN
Definition: Ixm42xxxDefs.h:1911
IXM42XXX_ACCEL_CONFIG0_ODR_32_KHZ
@ IXM42XXX_ACCEL_CONFIG0_ODR_32_KHZ
Definition: Ixm42xxxDefs.h:788
inv_ixm42xxx_set_config_ibi
int inv_ixm42xxx_set_config_ibi(struct inv_ixm42xxx *s, inv_ixm42xxx_interrupt_parameter_t *interrupt_to_configure)
Configure which interrupt source can trigger ibi interruptions.
Definition: Ixm42xxxDriver_HL.c:686
inv_ixm42xxx_enable_clkin_rtc
int inv_ixm42xxx_enable_clkin_rtc(struct inv_ixm42xxx *s, uint8_t enable)
Enable or disable CLKIN/RTC capability.
Definition: Ixm42xxxDriver_HL.c:1359
inv_ixm42xxx_force_clock_source
int inv_ixm42xxx_force_clock_source(struct inv_ixm42xxx *s, IXM42XXX_INTF_CONFIG1_ACCEL_LP_CLK_t clk_src)
Configure Accel clock source.
Definition: Ixm42xxxDriver_HL.c:143
inv_ixm42xxx_sensor_event_t::gyro
int16_t gyro[3]
Definition: Ixm42xxxDriver_HL.h:156
BIT_INT_UI_FSYNC_IBI_EN_POS
#define BIT_INT_UI_FSYNC_IBI_EN_POS
Definition: Ixm42xxxDefs.h:1919
inv_ixm42xxx_interrupt_parameter_t::INV_IXM42XXX_STEP_DET
inv_ixm42xxx_interrupt_value INV_IXM42XXX_STEP_DET
Definition: Ixm42xxxDriver_HL.h:239