GCC Code Coverage Report


Directory: ../../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 70.7% 191 / 0 / 270
Functions: 80.0% 16 / 0 / 20
Branches: 46.7% 42 / 0 / 90

driver/imu/imu_legacy.c
Line Branch Exec Source
1 /**
2 ******************************************************************************
3 * @file : imu_legacy.c
4 * @brief : BMI270/BMM150 IMU Driver Implementation (A0002 Rev2)
5 * @author : Sun Devil Rocketry Firmware Team
6 *
7 * @note Two data-retrieval paths are provided:
8 * - Blocking: imu_get_accel_xyz() / imu_get_gyro_xyz() /
9 * imu_get_accel_and_gyro() / imu_get_mag_xyz() poll the I2C bus
10 * directly and return once the transfer completes.
11 * - Interrupt-mode: start_imu_read_IT() kicks off a non-blocking
12 * I2C read; imu_it_handler() (called from the I2C memory-rx ISR)
13 * chains the accel/gyro read into a magnetometer read and marks
14 * the result ready; get_imu_it() is the non-blocking consumer.
15 *
16 ******************************************************************************
17 * @attention
18 * Copyright (c) 2026 Sun Devil Rocketry. All rights reserved.
19 * This software is licensed under terms that can be found in the LICENSE
20 * file in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is covered under the
22 * BSD-3-Clause (https://opensource.org/license/bsd-3-clause).
23 ******************************************************************************
24 */
25
26 #if defined( A0002_REV1 )
27 #error "A0002_REV1 support has been removed."
28 #endif
29
30
31 /*------------------------------------------------------------------------------
32 Standard Includes
33 ------------------------------------------------------------------------------*/
34 #include <string.h>
35 #include <stdatomic.h>
36
37 /*------------------------------------------------------------------------------
38 Project Includes
39 ------------------------------------------------------------------------------*/
40 #include "main.h"
41 #include "sdr_pin_defines_A0002.h"
42 #include "imu_legacy.h"
43
44 #include <math.h>
45
46 /*------------------------------------------------------------------------------
47 Global Variables
48 ------------------------------------------------------------------------------*/
49
50 /** @brief BMI270 configuration, loaded into the device during imu_init() */
51 uint8_t bmi270_init_file[] = {
52 #include "bmi270_init_file.tbin"
53 };
54
55 /*------------------------------------------------------------------------------
56 Local Variables
57 ------------------------------------------------------------------------------*/
58
59 /** @brief Raw double-buffer target for interrupt-mode accel/gyro reads */
60 uint8_t imu_raw_buffer[12];
61 /** @brief Parsed interrupt-mode accel/gyro/mag sample, published by imu_it_handler() */
62 IMU_RAW imu_raw_processed;
63 /** @brief Set true by imu_it_handler() once imu_raw_processed's accel/gyro fields are valid */
64 static atomic_bool imu_data_ready;
65
66 /** @brief Raw double-buffer target for interrupt-mode magnetometer reads */
67 uint8_t mag_raw_buffer[8];
68 /** @brief Set true by imu_it_handler() once imu_raw_processed's mag fields are valid */
69 static atomic_bool mag_data_ready;
70
71 /** @brief BMM150 factory trim coefficients, populated by mag_init() */
72 MAG_TRIM mag_trim;
73
74 /*------------------------------------------------------------------------------
75 Internal function prototypes
76 ------------------------------------------------------------------------------*/
77
78 /** @brief Initialize the magnetometer */
79 static IMU_STATUS mag_init
80 (
81 IMU_CONFIG* imu_config_ptr
82 );
83
84 /** @brief Read IMU registers (blocking) */
85 static IMU_STATUS read_imu_regs
86 (
87 uint8_t reg_addr, /* Register address */
88 uint8_t* data_ptr, /* Register data */
89 uint8_t num_regs /* Number of registers */
90 );
91
92 /** @brief Write to a specified IMU register (blocking) */
93 static IMU_STATUS write_imu_reg
94 (
95 uint8_t reg_addr, /* Register address */
96 uint8_t data /* Register data */
97 );
98
99 /** @brief Write IMU registers (blocking) */
100 static IMU_STATUS write_imu_regs
101 (
102 uint8_t reg_addr, /* Register address */
103 uint8_t* data_ptr, /* Register data */
104 uint32_t num_regs /* Number of registers */
105 );
106
107 /** @brief Read Magnetometer registers (blocking) */
108 static IMU_STATUS read_mag_regs
109 (
110 uint8_t reg_addr, /* Register address */
111 uint8_t* data_ptr, /* Register data */
112 uint8_t num_regs /* Number of registers */
113 );
114
115 /** @brief Write to a specified magnetometer register (blocking) */
116 static IMU_STATUS write_mag_reg
117 (
118 uint8_t reg_addr, /* Register address */
119 uint8_t data /* Register data */
120 );
121
122 /** @brief Read IMU registers (interrupt mode) */
123 static IMU_STATUS read_imu_regs_IT
124 (
125 uint8_t reg_addr, /* Register address */
126 uint8_t* data_ptr, /* Register data */
127 uint8_t num_regs /* Number of registers to read */
128 );
129
130 /** @brief Read Magnetometer registers (interrupt mode) */
131 static IMU_STATUS read_mag_regs_IT
132 (
133 uint8_t reg_addr,
134 uint8_t* data_ptr,
135 uint8_t num_regs
136 );
137
138
139 /*------------------------------------------------------------------------------
140 Procedures
141 ------------------------------------------------------------------------------*/
142
143 /**
144 * @brief Initializes the IMU (BMI270 config load + sensor config + BMM150 mag_init).
145 * @param imu_config_ptr: Pointer to user configuration struct.
146 * @return IMU_STATUS
147 */
148 3 IMU_STATUS imu_init
149 (
150 IMU_CONFIG* imu_config_ptr /* IMU Configuration */
151 )
152 {
153 /*------------------------------------------------------------------------------
154 Local variables
155 ------------------------------------------------------------------------------*/
156 3 IMU_STATUS imu_status; /* IMU API call return codes */
157 3 uint8_t imu_dev_id; /* IMU identification code */
158 3 uint8_t imu_status_reg; /* Contents of IMU status register */
159 3 uint8_t imu_acc_conf; /* IMU ACC_CONF Register contents */
160 3 uint8_t imu_gyr_conf; /* IMU GYR_CONF Register contents */
161 3 uint8_t imu_sensor_data[12]; /* IMU Sensor Data */
162
163
164 /*------------------------------------------------------------------------------
165 Initializations
166 ------------------------------------------------------------------------------*/
167 3 imu_status = IMU_OK;
168 3 imu_dev_id = 0;
169 3 imu_status_reg = 0;
170 3 imu_acc_conf = ( imu_config_ptr -> acc_odr ) |
171 3 ( imu_config_ptr -> acc_filter ) |
172 3 ( imu_config_ptr -> acc_filter_mode );
173 3 imu_gyr_conf = ( imu_config_ptr -> gyro_odr ) |
174 3 ( imu_config_ptr -> gyro_filter ) |
175 ( 1 << 7 );
176 3 memset( &imu_sensor_data[0], 0, sizeof( imu_sensor_data ) );
177
178 /* clear double buffer if using IMU with IT */
179 3 memset( &imu_raw_buffer, 0, sizeof( imu_raw_buffer ) );
180 3 imu_data_ready = false;
181
182
183 /*------------------------------------------------------------------------------
184 Implementation
185 ------------------------------------------------------------------------------*/
186
187 /* disable interrupts while initializing */
188 3 HAL_NVIC_DisableIRQ(I2C2_EV_IRQn);
189
190 /* Read IMU ID and verify correct ID */
191 3 imu_status = imu_get_device_id( &imu_dev_id );
192
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
193 {
194 return imu_status;
195 }
196
197 /* BMI270 Initialization Sequence */
198 /* Disable advanced power save */
199 3 imu_status = write_imu_reg( IMU_REG_PWR_CONF, 0x00 );
200
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
201 {
202 return IMU_INIT_FAIL;
203 }
204 3 HAL_Delay( 1 );
205
206 /* Prepare Config Load */
207 3 imu_status = write_imu_reg( IMU_REG_INIT_CTRL, 0x00 );
208
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
209 {
210 return IMU_INIT_FAIL;
211 }
212
213 /* Load the initialization data */
214 3 imu_status = write_imu_regs( IMU_REG_INIT_DATA ,
215 &bmi270_init_file[0],
216 sizeof( bmi270_init_file ) );
217
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
218 {
219 return IMU_INIT_FAIL;
220 }
221
222 /* Complete config load */
223 3 imu_status = write_imu_reg( IMU_REG_INIT_CTRL, 0x01 );
224
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
225 {
226 return IMU_INIT_FAIL;
227 }
228
229 /* Check if Initialization was Successful */
230 3 HAL_Delay( 150 );
231 3 imu_status = read_imu_regs( IMU_REG_INTERNAL_STATUS,
232 &imu_status_reg ,
233 sizeof( imu_status_reg ) );
234
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if ( imu_status != IMU_OK || !( imu_status_reg & 0b00000001 ) )
235 {
236 return IMU_INIT_FAIL;
237 }
238
239 /* Initial IMU Configuration */
240 /* Enable Sensors */
241 6 imu_status = write_imu_reg( IMU_REG_PWR_CTRL,
242 3 imu_config_ptr -> sensor_enable );
243
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
244 {
245 return IMU_CONFIG_FAIL;
246 }
247
248 /* Configure the Accelerometer */
249 3 imu_status = write_imu_reg( IMU_REG_ACC_CONF, imu_acc_conf );
250
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
251 {
252 return IMU_CONFIG_FAIL;
253 }
254 6 imu_status = write_imu_reg( IMU_REG_ACC_RANGE,
255 3 imu_config_ptr -> acc_range );
256
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
257 {
258 return IMU_CONFIG_FAIL;
259 }
260
261 /* Configure the Gyroscope */
262 3 imu_status = write_imu_reg( IMU_REG_GYR_CONF, imu_gyr_conf );
263
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
264 {
265 return IMU_CONFIG_FAIL;
266 }
267 6 imu_status = write_imu_reg( IMU_REG_GYR_RANGE,
268 3 imu_config_ptr -> gyro_range );
269
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
270 {
271 return IMU_CONFIG_FAIL;
272 }
273
274 /* Disable Advanced Power Save */
275 3 imu_status = write_imu_reg( IMU_REG_PWR_CONF, 0x02 );
276
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
277 {
278 return IMU_CONFIG_FAIL;
279 }
280
281 /* Readout sensor registers */
282 3 imu_status = read_imu_regs( IMU_REG_DATA_8 ,
283 &imu_sensor_data[0],
284 sizeof( imu_sensor_data ) );
285
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
286 {
287 return IMU_CONFIG_FAIL;
288 }
289
290 /* Initialize the magnetometer */
291 3 imu_status = mag_init( imu_config_ptr );
292
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
293 {
294 return IMU_MAG_INIT_FAIL;
295 }
296
297 /* re-enable interrupts while initializing */
298 3 HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
299
300 /* IMU Inititialization Successful */
301 3 return IMU_OK;
302 } /* imu_init */
303
304
305 /**
306 * @brief Blocking read of accelerometer X/Y/Z.
307 * @param pIMU: Destination struct for the accel readout (size: 12 bytes).
308 * @return IMU_STATUS
309 */
310 ✗ IMU_STATUS imu_get_accel_xyz
311 (
312 IMU_RAW *pIMU /* size: 12 bytes */
313 )
314 {
315 /*------------------------------------------------------------------------------
316 Local variables
317 ------------------------------------------------------------------------------*/
318 ✗ uint8_t regAccel[6]; /* Bytes from accelerometer registers */
319 ✗ uint16_t accel_x_raw ; /* Raw sensor readouts */
320 ✗ uint16_t accel_y_raw ;
321 ✗ uint16_t accel_z_raw ;
322 ✗ IMU_STATUS imu_status; /* IMU status codes */
323
324
325 /*------------------------------------------------------------------------------
326 API function implementation
327 ------------------------------------------------------------------------------*/
328
329 /* Read ACCEL_X, ACCEL_Y, ACCEL_Z high byte and low byte registers */
330 ✗ imu_status = read_imu_regs( IMU_REG_DATA_8,
331 &regAccel[0] ,
332 sizeof( regAccel ) );
333
334 /* Check for HAL IMU error */
335 ✗ if ( imu_status != IMU_OK )
336 {
337 return imu_status;
338 }
339
340 /* Combine high byte and low byte to 16 bit data */
341 ✗ accel_x_raw = ( (uint16_t) regAccel[1] ) << 8 | regAccel[0];
342 ✗ accel_y_raw = ( (uint16_t) regAccel[3] ) << 8 | regAccel[2];
343 ✗ accel_z_raw = ( (uint16_t) regAccel[5] ) << 8 | regAccel[4];
344
345 /* Export data to IMU sstruct */
346 ✗ pIMU->accel_x = accel_x_raw;
347 ✗ pIMU->accel_y = accel_y_raw;
348 ✗ pIMU->accel_z = accel_z_raw;
349
350 ✗ return IMU_OK;
351 } /* imu_get_accel_xyz */
352
353
354 /**
355 * @brief Blocking read of gyroscope X/Y/Z.
356 * @param pIMU: Destination struct for the gyro readout.
357 * @return IMU_STATUS
358 */
359 ✗ IMU_STATUS imu_get_gyro_xyz
360 (
361 IMU_RAW *pIMU
362 )
363 {
364 /*------------------------------------------------------------------------------
365 Local variables
366 ------------------------------------------------------------------------------*/
367 ✗ uint8_t regGyro[6]; /* Bytes from gyro registers */
368 ✗ int16_t gyro_x_raw; /* Raw gyro sensor readouts */
369 ✗ int16_t gyro_y_raw;
370 ✗ int16_t gyro_z_raw;
371 ✗ IMU_STATUS imu_status; /* IMU status return codes */
372
373
374 /*------------------------------------------------------------------------------
375 API function implementation
376 ------------------------------------------------------------------------------*/
377
378 /* Read GYRO_X, GYRO_Y, GYRO_Z high byte and low byte registers */
379 ✗ imu_status = read_imu_regs( IMU_REG_DATA_14,
380 &regGyro[0] ,
381 sizeof( regGyro ) );
382
383 /* Check for HAL IMU error */
384 ✗ if ( imu_status != IMU_OK )
385 {
386 return imu_status;
387 }
388
389 /* Combine high byte and low byte to 16 bit data */
390 ✗ gyro_x_raw = (int16_t) ( (uint16_t) regGyro[1] << 8 | regGyro[0] );
391 ✗ gyro_y_raw = (int16_t) ( (uint16_t) regGyro[3] << 8 | regGyro[2] );
392 ✗ gyro_z_raw = (int16_t) ( (uint16_t) regGyro[5] << 8 | regGyro[4] );
393
394 /* Export Sensor Readouts */
395 ✗ pIMU->gyro_x = gyro_x_raw;
396 ✗ pIMU->gyro_y = gyro_y_raw;
397 ✗ pIMU->gyro_z = gyro_z_raw;
398
399 ✗ return IMU_OK;
400 } /* imu_get_gyro_xyz */
401
402
403 /**
404 * @brief Blocking read of accelerometer and gyroscope X/Y/Z in a single burst.
405 * @param pIMU: Destination struct for the accel + gyro readout.
406 * @return IMU_STATUS
407 */
408 ✗ IMU_STATUS imu_get_accel_and_gyro
409 (
410 IMU_RAW *pIMU
411 )
412 {
413 /*------------------------------------------------------------------------------
414 Local variables
415 ------------------------------------------------------------------------------*/
416 ✗ uint8_t regRaw[12]; /* Bytes from raw registers */
417 ✗ int16_t accel_x_raw; /* Raw accel sensor readouts */
418 ✗ int16_t accel_y_raw;
419 ✗ int16_t accel_z_raw;
420 ✗ int16_t gyro_x_raw; /* Raw gyro sensor readouts */
421 ✗ int16_t gyro_y_raw;
422 ✗ int16_t gyro_z_raw;
423 ✗ IMU_STATUS imu_status; /* IMU status return codes */
424
425
426 /*------------------------------------------------------------------------------
427 API function implementation
428 ------------------------------------------------------------------------------*/
429
430 /* Read ACCEL and GYRO high byte and low byte registers */
431 ✗ imu_status = read_imu_regs( IMU_REG_DATA_8,
432 &regRaw[0] ,
433 sizeof( regRaw ) );
434
435
436 /* Check for HAL IMU error */
437 ✗ if ( imu_status != IMU_OK )
438 {
439 return imu_status;
440 }
441
442 /* Combine high byte and low byte to 16 bit data */
443 ✗ accel_x_raw = (int16_t) ( (uint16_t) regRaw[1] << 8 | regRaw[0] );
444 ✗ accel_y_raw = (int16_t) ( (uint16_t) regRaw[3] << 8 | regRaw[2] );
445 ✗ accel_z_raw = (int16_t) ( (uint16_t) regRaw[5] << 8 | regRaw[4] );
446 ✗ gyro_x_raw = (int16_t) ( (uint16_t) regRaw[7] << 8 | regRaw[6] );
447 ✗ gyro_y_raw = (int16_t) ( (uint16_t) regRaw[9] << 8 | regRaw[8] );
448 ✗ gyro_z_raw = (int16_t) ( (uint16_t) regRaw[11] << 8 | regRaw[10] );
449
450 /* Export Sensor Readouts */
451 ✗ pIMU->accel_x = accel_x_raw;
452 ✗ pIMU->accel_y = accel_y_raw;
453 ✗ pIMU->accel_z = accel_z_raw;
454 ✗ pIMU->gyro_x = gyro_x_raw;
455 ✗ pIMU->gyro_y = gyro_y_raw;
456 ✗ pIMU->gyro_z = gyro_z_raw;
457
458 ✗ return IMU_OK;
459 } /* imu_get_accel_and_gyro */
460
461
462 /**
463 * @brief Blocking read of magnetometer X/Y/Z.
464 * @param pIMU: Destination struct for the magnetometer readout.
465 * @return IMU_STATUS
466 */
467 ✗ IMU_STATUS imu_get_mag_xyz
468 (
469 IMU_RAW *pIMU
470 )
471 {
472 /*------------------------------------------------------------------------------
473 Local variables
474 ------------------------------------------------------------------------------*/
475 ✗ uint8_t regMag[8]; /* Magnetometer register bytes */
476 ✗ int16_t mag_x_raw; /* Raw magnetometer sensor readouts */
477 ✗ int16_t mag_y_raw;
478 ✗ int16_t mag_z_raw;
479 ✗ uint16_t mag_hall_raw;
480 ✗ IMU_STATUS imu_status; /* IMU status return codes */
481
482
483 /*------------------------------------------------------------------------------
484 API function implementation
485 ------------------------------------------------------------------------------*/
486
487 /* Read MAG_X, MAG_Y, MAG_Z high byte and low byte registers */
488 ✗ imu_status = read_mag_regs( MAG_REG_DATAX_L,
489 &regMag[0] ,
490 sizeof( regMag ) );
491
492 /* Check for HAL IMU error */
493 ✗ if ( imu_status == IMU_TIMEOUT )
494 {
495 return IMU_TIMEOUT;
496 }
497
498 /* Combine high byte and low byte to 16 bit data */
499 ✗ mag_x_raw = ( (uint16_t) regMag[1] << MAG_XY_MSB_BITSHIFT ) |
500 ✗ ( ( (uint16_t) regMag[0] & MAG_XY_LSB_BITMASK ) >> MAG_XY_LSB_BITSHIFT );
501 ✗ mag_y_raw = ( (uint16_t) regMag[3] << MAG_XY_MSB_BITSHIFT ) |
502 ✗ ( ( (uint16_t) regMag[2] & MAG_XY_LSB_BITMASK ) >> MAG_XY_LSB_BITSHIFT );
503 ✗ mag_z_raw = ( (uint16_t) regMag[5] << MAG_Z_MSB_BITSHIFT ) |
504 ✗ ( ( (uint16_t) regMag[4] & MAG_Z_LSB_BITMASK ) >> MAG_Z_LSB_BITSHIFT );
505 ✗ mag_hall_raw = ( (uint16_t) regMag[7] << MAG_RHALL_MSB_BITSHIFT ) |
506 ✗ ( ( (uint16_t) regMag[6] & MAG_RHALL_LSB_BITMASK ) >> MAG_RHALL_LSB_BITSHIFT );
507
508 /* Export sensor data */
509 ✗ pIMU->mag_x = mag_x_raw;
510 ✗ pIMU->mag_y = mag_y_raw;
511 ✗ pIMU->mag_z = mag_z_raw;
512 ✗ pIMU->mag_hall = mag_hall_raw;
513
514 ✗ return IMU_OK;
515 } /* imu_get_mag_xyz */
516
517
518 /**
519 * @brief Reads and verifies the IMU's CHIP_ID register.
520 * @param pdevice_id: Destination for the returned device ID.
521 * @return IMU_STATUS: IMU_UNRECOGNIZED_OP if the ID doesn't match IMU_ID.
522 */
523 3 IMU_STATUS imu_get_device_id
524 (
525 uint8_t* pdevice_id
526 )
527 {
528 /*------------------------------------------------------------------------------
529 Local variables
530 ------------------------------------------------------------------------------*/
531 3 IMU_STATUS imu_status;
532
533
534 /*------------------------------------------------------------------------------
535 API function implementation
536 ------------------------------------------------------------------------------*/
537
538 /* Read Device ID register */
539 3 imu_status = read_imu_regs( IMU_REG_CHIP_ID, pdevice_id, sizeof( uint8_t ) );
540
541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if ( *pdevice_id != IMU_ID )
542 {
543 ✗ imu_status = IMU_UNRECOGNIZED_OP;
544 }
545
546 3 return imu_status;
547 } /* imu_get_device_id */
548
549
550 /*------------------------------------------------------------------------------
551 Internal procedures
552 ------------------------------------------------------------------------------*/
553
554 /**
555 * @brief Initialize the magnetometer.
556 *
557 * @copyright Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.
558 *
559 * This function is heavily derived from the official Bosch BMM150
560 * driver, which is protected by the BSD-3-Clause license. This
561 * function is exempt from any licensing that may be applied to a
562 * current/future Sun Devil Rocketry project. Per the terms of the
563 * BSD-3-Clause license, the following notice is retained from the
564 * source project and applies to the procedure below.
565 *
566 * BSD-3-Clause
567 *
568 * Redistribution and use in source and binary forms, with or
569 * without modification, are permitted provided that the following
570 * conditions are met:
571 *
572 * 1. Redistributions of source code must retain the above
573 * copyright notice, this list of conditions and the following
574 * disclaimer.
575 *
576 * 2. Redistributions in binary form must reproduce the above
577 * copyright notice, this list of conditions and the following
578 * disclaimer in the documentation and/or other materials provided
579 * with the distribution.
580 *
581 * 3. Neither the name of the copyright holder nor the names of its
582 * contributors may be used to endorse or promote products derived
583 * from this software without specific prior written permission.
584 *
585 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
586 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
587 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
588 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
589 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
590 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
591 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
592 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
593 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
594 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
595 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
596 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
597 * POSSIBILITY OF SUCH DAMAGE.
598 *
599 * @param imu_config_ptr: Pointer to user configuration struct.
600 * @return IMU_STATUS
601 */
602 3 static IMU_STATUS mag_init
603 (
604 IMU_CONFIG* imu_config_ptr
605 )
606 {
607 /*------------------------------------------------------------------------------
608 Local variables
609 ------------------------------------------------------------------------------*/
610 3 IMU_STATUS imu_status; /* Status return codes from IMU API */
611 3 uint8_t device_id; /* Magnetometer Device ID */
612 3 uint8_t num_reps_xy_reg; /* Content of XY repetititions register */
613 3 uint8_t num_reps_z_reg; /* Content of Z repititions register */
614 3 uint8_t buffer[10]; /* Mag trim read buffer */
615 3 uint16_t temp_msb; /* Temp variable */
616
617
618 /*------------------------------------------------------------------------------
619 Initializations
620 ------------------------------------------------------------------------------*/
621 3 imu_status = IMU_OK;
622 3 device_id = 0;
623 3 num_reps_xy_reg = ( ( imu_config_ptr -> mag_xy_repititions ) - 1 ) >> 2;
624 3 num_reps_z_reg = ( ( imu_config_ptr -> mag_z_repititions ) - 1 );
625
626
627 /*------------------------------------------------------------------------------
628 API function implementation
629 ------------------------------------------------------------------------------*/
630
631 /* Put the Magnetometer into sleep mode from suspend mode */
632 3 imu_status = write_mag_reg( MAG_REG_PWR_CTRL, 0x01 );
633
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
634 {
635 return imu_status;
636 }
637
638 /* Check Device ID */
639 3 HAL_Delay( 5 );
640 3 imu_status = read_mag_regs( MAG_REG_CHIP_ID, &device_id, sizeof( device_id ) );
641
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
642 {
643 return imu_status;
644 }
645
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 else if ( device_id != MAG_ID )
646 {
647 return IMU_MAG_UNRECOGNIZED_ID;
648 }
649
650 /* Set the magnetometer operating mode and output data rate */
651 6 imu_status = write_mag_reg( MAG_REG_CTRL1,
652 3 ( imu_config_ptr -> mag_op_mode ) |
653 3 ( imu_config_ptr -> mag_odr ) );
654
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
655 {
656 return imu_status;
657 }
658
659 /* Set the magnetometer measurement repetitions */
660 3 imu_status = write_mag_reg( MAG_REG_REP_CTRL_XY, num_reps_xy_reg );
661
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
662 {
663 return imu_status;
664 }
665 3 imu_status = write_mag_reg( MAG_REG_REP_CTRL_Z, num_reps_z_reg );
666
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
667 {
668 return imu_status;
669 }
670
671 /* Set magnetometer trim */
672
673 /* ---- Read X1, Y1 ---- */
674 3 imu_status = read_mag_regs(MAG_TRIM_REG_X1, buffer, 2);
675
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
676 {
677 return imu_status;
678 }
679 3 mag_trim.dig_x1 = (int8_t)buffer[0];
680 3 mag_trim.dig_y1 = (int8_t)buffer[1];
681
682 /* ---- Read Z4_LSB -> Z4_MSB and X2,Y2 ---- */
683 3 imu_status = read_mag_regs(MAG_TRIM_REG_Z4_LSB, buffer, 4);
684
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
685 {
686 return imu_status;
687 }
688 3 mag_trim.dig_z4 = (int16_t)(((uint16_t)buffer[1] << 8) | buffer[0]);
689 3 mag_trim.dig_x2 = (int8_t)buffer[2];
690 3 mag_trim.dig_y2 = (int8_t)buffer[3];
691
692 /* ---- Read Z2_LSB -> Z1_MSB (10 bytes) ---- */
693 3 imu_status = read_mag_regs(MAG_TRIM_REG_Z2_LSB, buffer, 10);
694
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( imu_status != IMU_OK )
695 {
696 return imu_status;
697 }
698 3 temp_msb = ((uint16_t)buffer[3]) << 8;
699 3 mag_trim.dig_z1 = (uint16_t)(temp_msb | buffer[2]);
700 3 temp_msb = ((uint16_t)buffer[1]) << 8;
701 3 mag_trim.dig_z2 = (int16_t)(temp_msb | buffer[0]);
702 3 temp_msb = ((uint16_t)buffer[7]) << 8;
703 3 mag_trim.dig_z3 = (int16_t)(temp_msb | buffer[6]);
704 3 mag_trim.dig_xy1 = buffer[9];
705 3 mag_trim.dig_xy2 = (int8_t)buffer[8];
706 3 temp_msb = ((uint16_t)(buffer[5] & 0x7F)) << 8;
707 3 mag_trim.dig_xyz1 = (uint16_t)(temp_msb | buffer[4]);
708
709 /* Successful magnetometer Initialization */
710 3 return IMU_OK;
711 } /* mag_init */
712
713
714 /**
715 * @brief Read the specified number of registers at one time from the
716 * magnetometer module in the IMU (blocking).
717 * @param reg_addr: Starting register address.
718 * @param data_ptr: Destination buffer.
719 * @param num_regs: Number of registers to read.
720 * @return IMU_STATUS
721 */
722 12 static IMU_STATUS read_mag_regs
723 (
724 uint8_t reg_addr,
725 uint8_t* data_ptr,
726 uint8_t num_regs
727 )
728 {
729
730 /*------------------------------------------------------------------------------
731 Local variables
732 ------------------------------------------------------------------------------*/
733 12 HAL_StatusTypeDef hal_status; /* Status return code of I2C HAL */
734
735
736 /*------------------------------------------------------------------------------
737 API function implementation
738 ------------------------------------------------------------------------------*/
739
740 /* Read I2C registers */
741 12 hal_status = HAL_I2C_Mem_Read( &( IMU_I2C ) ,
742 IMU_MAG_ADDR ,
743 reg_addr ,
744 I2C_MEMADD_SIZE_8BIT,
745 data_ptr ,
746 num_regs ,
747 HAL_IMU_TIMEOUT );
748
749 /* Return status code of I2C HAL */
750
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if ( hal_status != HAL_OK )
751 {
752 return IMU_MAG_ERROR;
753 }
754 else
755 {
756 12 return IMU_OK;
757 }
758
759 } /* read_mag_regs */
760
761
762 /**
763 * @brief Read the specified number of registers at one time from the
764 * accelerometer and gyroscope module in the IMU (blocking).
765 * @param reg_addr: Starting register address.
766 * @param data_ptr: Destination buffer.
767 * @param num_regs: Number of registers to read.
768 * @return IMU_STATUS
769 */
770 9 static IMU_STATUS read_imu_regs
771 (
772 uint8_t reg_addr, /* Register address */
773 uint8_t* data_ptr, /* Register data */
774 uint8_t num_regs /* Number of registers to read */
775 )
776 {
777 /*------------------------------------------------------------------------------
778 Local variables
779 ------------------------------------------------------------------------------*/
780 9 HAL_StatusTypeDef hal_status; /* Status of I2C HAL */
781
782
783 /*------------------------------------------------------------------------------
784 Implementation
785 ------------------------------------------------------------------------------*/
786
787 /* Read I2C register */
788 9 hal_status = HAL_I2C_Mem_Read( &( IMU_I2C ) ,
789 IMU_ADDR ,
790 reg_addr ,
791 I2C_MEMADD_SIZE_8BIT,
792 data_ptr ,
793 num_regs ,
794 HAL_MAX_DELAY );
795
796
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if ( hal_status != HAL_OK )
797 {
798 return IMU_ERROR;
799 }
800 else
801 {
802 9 return IMU_OK;
803 }
804 } /* read_imu_regs */
805
806
807 /** @brief Returns the imu_data_ready flag. */
808 1049867175 bool imu_get_imu_data_ready
809 (
810 void
811 )
812 {
813 1049867175 return imu_data_ready;
814
815 } /* imu_get_imu_data_ready */
816
817
818 /** @brief Returns the mag_data_ready flag. */
819 521741377 bool imu_get_mag_data_ready
820 (
821 void
822 )
823 {
824 521741377 return mag_data_ready;
825
826 } /* imu_get_mag_data_ready */
827
828
829 /**
830 * @brief Write to a specified IMU register (blocking).
831 * @param reg_addr: Register address.
832 * @param data: Register data.
833 * @return IMU_STATUS
834 */
835 27 static IMU_STATUS write_imu_reg
836 (
837 uint8_t reg_addr, /* Register address */
838 uint8_t data /* Register data */
839 )
840 {
841 /*------------------------------------------------------------------------------
842 Local variables
843 ------------------------------------------------------------------------------*/
844 27 HAL_StatusTypeDef hal_status; /* Status of I2C HAL */
845
846
847 /*------------------------------------------------------------------------------
848 Initializations
849 ------------------------------------------------------------------------------*/
850 27 hal_status = HAL_OK;
851
852
853 /*------------------------------------------------------------------------------
854 Implementation
855 ------------------------------------------------------------------------------*/
856 27 hal_status = HAL_I2C_Mem_Write( &( IMU_I2C ) ,
857 IMU_ADDR ,
858 reg_addr ,
859 I2C_MEMADD_SIZE_8BIT,
860 &data ,
861 sizeof( uint8_t ) ,
862 HAL_IMU_TIMEOUT );
863
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if ( hal_status != HAL_OK )
864 {
865 return IMU_I2C_ERROR;
866 }
867 else
868 {
869 27 return IMU_OK;
870 }
871 } /* write_imu_reg */
872
873
874 /**
875 * @brief Write to specified IMU registers (blocking).
876 * @param reg_addr: Starting register address.
877 * @param data_ptr: Source data buffer.
878 * @param num_regs: Number of registers to write.
879 * @return IMU_STATUS
880 */
881 3 static IMU_STATUS write_imu_regs
882 (
883 uint8_t reg_addr, /* Register address */
884 uint8_t* data_ptr, /* Register data */
885 uint32_t num_regs /* Number of registers */
886 )
887 {
888 /*------------------------------------------------------------------------------
889 Local variables
890 ------------------------------------------------------------------------------*/
891 3 HAL_StatusTypeDef hal_status; /* Status of I2C HAL */
892
893
894 /*------------------------------------------------------------------------------
895 Initializations
896 ------------------------------------------------------------------------------*/
897 3 hal_status = HAL_OK;
898
899
900 /*------------------------------------------------------------------------------
901 Implementation
902 ------------------------------------------------------------------------------*/
903 3 hal_status = HAL_I2C_Mem_Write( &( IMU_I2C ),
904 IMU_ADDR ,
905 reg_addr ,
906 I2C_MEMADD_SIZE_8BIT,
907 data_ptr ,
908 num_regs ,
909 HAL_MAX_DELAY );
910
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( hal_status != HAL_OK )
911 {
912 return IMU_I2C_ERROR;
913 }
914 else
915 {
916 3 return IMU_OK;
917 }
918 } /* write_imu_regs */
919
920
921 /**
922 * @brief Write to a specified magnetometer register (blocking).
923 * @param reg_addr: Register address.
924 * @param data: Register data.
925 * @return IMU_STATUS
926 */
927 12 static IMU_STATUS write_mag_reg
928 (
929 uint8_t reg_addr, /* Register address */
930 uint8_t data /* Register data */
931 )
932 {
933 /*------------------------------------------------------------------------------
934 Local variables
935 ------------------------------------------------------------------------------*/
936 12 HAL_StatusTypeDef hal_status; /* Status of I2C HAL */
937
938
939 /*------------------------------------------------------------------------------
940 Initializations
941 ------------------------------------------------------------------------------*/
942 12 hal_status = HAL_OK;
943
944
945 /*------------------------------------------------------------------------------
946 Implementation
947 ------------------------------------------------------------------------------*/
948 12 hal_status = HAL_I2C_Mem_Write( &( IMU_I2C ) ,
949 IMU_MAG_ADDR ,
950 reg_addr ,
951 I2C_MEMADD_SIZE_8BIT,
952 &data ,
953 sizeof( uint8_t ) ,
954 HAL_IMU_TIMEOUT );
955
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if ( hal_status != HAL_OK )
956 {
957 return IMU_I2C_ERROR;
958 }
959 else
960 {
961 12 return IMU_OK;
962 }
963 } /* write_mag_reg */
964
965
966 /**
967 * @brief Kicks off a non-blocking read of the accel and gyro registers.
968 * @note Clears imu_data_ready/mag_data_ready; imu_it_handler() sets them
969 * once the chained accel/gyro + mag reads have both completed.
970 * @return IMU_STATUS
971 */
972 1180 IMU_STATUS start_imu_read_IT
973 (
974 void
975 )
976 {
977 1180 imu_data_ready = false;
978 1180 mag_data_ready = false;
979 1180 return read_imu_regs_IT( IMU_REG_DATA_8,
980 imu_raw_buffer,
981 sizeof( imu_raw_buffer ) );
982 } /* start_imu_read_IT */
983
984
985 /**
986 * @brief Read the IMU registers in interrupt mode.
987 * @param reg_addr: Starting register address.
988 * @param data_ptr: Destination buffer.
989 * @param num_regs: Number of registers to read.
990 * @return IMU_STATUS
991 */
992 1180 static IMU_STATUS read_imu_regs_IT
993 (
994 uint8_t reg_addr, /* Register address */
995 uint8_t* data_ptr, /* Register data */
996 uint8_t num_regs /* Number of registers to read */
997 )
998 {
999 /*------------------------------------------------------------------------------
1000 Local variables
1001 ------------------------------------------------------------------------------*/
1002 1180 HAL_StatusTypeDef hal_status;
1003
1004
1005 /*------------------------------------------------------------------------------
1006 Initializations
1007 ------------------------------------------------------------------------------*/
1008 1180 hal_status = HAL_OK;
1009
1010
1011 /*------------------------------------------------------------------------------
1012 Implementation
1013 ------------------------------------------------------------------------------*/
1014
1015 /* Read I2C register */
1016 1180 hal_status = HAL_I2C_Mem_Read_IT( &( IMU_I2C ) ,
1017 IMU_ADDR ,
1018 reg_addr ,
1019 I2C_MEMADD_SIZE_8BIT,
1020 data_ptr ,
1021 num_regs );
1022
1023
1/2
✓ Branch 0 taken 1180 times.
✗ Branch 1 not taken.
1180 if ( hal_status != HAL_OK )
1024 {
1025 return IMU_ERROR;
1026 }
1027 else
1028 {
1029 1180 return IMU_OK;
1030 }
1031 }
1032
1033
1034 /**
1035 * @brief Handle a memory_rx interrupt signal from the IMU.
1036 * @note Two-stage state machine driven by imu_data_ready/mag_data_ready:
1037 * 1. First call (neither flag set): parses the just-completed
1038 * accel/gyro burst into imu_raw_processed, marks
1039 * imu_data_ready, then kicks off the chained mag read.
1040 * 2. Second call (accel/gyro ready, mag not yet): parses the
1041 * completed mag burst, sign-extends the 13/15-bit fields,
1042 * and marks mag_data_ready.
1043 * @return IMU_STATUS
1044 */
1045 2359 IMU_STATUS imu_it_handler
1046 (
1047 void
1048 )
1049 {
1050 2359 IMU_STATUS imu_status = IMU_OK;
1051
3/4
✓ Branch 0 taken 1180 times.
✓ Branch 1 taken 1179 times.
✓ Branch 2 taken 1180 times.
✗ Branch 3 not taken.
2359 if( !imu_data_ready && !mag_data_ready )
1052 {
1053 /*------------------------------------------------------------------------------
1054 Handle IT signal
1055 ------------------------------------------------------------------------------*/
1056 /* Combine high byte and low byte to 16 bit data */
1057 1180 imu_raw_processed.accel_x = (int16_t) ( (uint16_t) imu_raw_buffer[1] << 8 | imu_raw_buffer[0] );
1058 1180 imu_raw_processed.accel_y = (int16_t) ( (uint16_t) imu_raw_buffer[3] << 8 | imu_raw_buffer[2] );
1059 1180 imu_raw_processed.accel_z = (int16_t) ( (uint16_t) imu_raw_buffer[5] << 8 | imu_raw_buffer[4] );
1060 1180 imu_raw_processed.gyro_x = (int16_t) ( (uint16_t) imu_raw_buffer[7] << 8 | imu_raw_buffer[6] );
1061 1180 imu_raw_processed.gyro_y = (int16_t) ( (uint16_t) imu_raw_buffer[9] << 8 | imu_raw_buffer[8] );
1062 1180 imu_raw_processed.gyro_z = (int16_t) ( (uint16_t) imu_raw_buffer[11] << 8 | imu_raw_buffer[10] );
1063
1064 1180 imu_data_ready = true;
1065
1066 /*------------------------------------------------------------------------------
1067 Trigger mag read
1068 ------------------------------------------------------------------------------*/
1069 1180 imu_status = read_mag_regs_IT( MAG_REG_DATAX_L,
1070 mag_raw_buffer,
1071 8 );
1072 1180 return imu_status;
1073 }
1074
2/4
✓ Branch 0 taken 1179 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1179 times.
✗ Branch 3 not taken.
1179 else if( imu_data_ready && !mag_data_ready )
1075 {
1076 1179 imu_raw_processed.mag_x
1077 1179 = ( (uint16_t) mag_raw_buffer[1] << MAG_XY_MSB_BITSHIFT ) |
1078 1179 ( ( (uint16_t) mag_raw_buffer[0] & MAG_XY_LSB_BITMASK ) >> MAG_XY_LSB_BITSHIFT );
1079 1179 imu_raw_processed.mag_y
1080 1179 = ( (uint16_t) mag_raw_buffer[3] << MAG_XY_MSB_BITSHIFT ) |
1081 1179 ( ( (uint16_t) mag_raw_buffer[2] & MAG_XY_LSB_BITMASK ) >> MAG_XY_LSB_BITSHIFT );
1082 1179 imu_raw_processed.mag_z
1083 1179 = ( (uint16_t) mag_raw_buffer[5] << MAG_Z_MSB_BITSHIFT ) |
1084 1179 ( ( (uint16_t) mag_raw_buffer[4] & MAG_Z_LSB_BITMASK ) >> MAG_Z_LSB_BITSHIFT );
1085 1179 imu_raw_processed.mag_hall
1086 1179 = ( (uint16_t) mag_raw_buffer[7] << MAG_RHALL_MSB_BITSHIFT ) |
1087 1179 ( ( (uint16_t) mag_raw_buffer[6] & MAG_RHALL_LSB_BITMASK ) >> MAG_RHALL_LSB_BITSHIFT );
1088
1089 /* Sign-extend 13-bit and 15-bit values */
1090
1/2
✓ Branch 0 taken 1179 times.
✗ Branch 1 not taken.
1179 if (imu_raw_processed.mag_x & (1 << 12))
1091 {
1092 1179 imu_raw_processed.mag_x |= ~((1 << 13) - 1);
1093 }
1094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1179 times.
1179 if (imu_raw_processed.mag_y & (1 << 12))
1095 {
1096 ✗ imu_raw_processed.mag_y |= ~((1 << 13) - 1);
1097 }
1098
1/2
✓ Branch 0 taken 1179 times.
✗ Branch 1 not taken.
1179 if (imu_raw_processed.mag_z & (1 << 14))
1099 {
1100 1179 imu_raw_processed.mag_z |= ~((1 << 15) - 1);
1101 }
1102
1103 1179 mag_data_ready = true;
1104
1105 1179 return imu_status;
1106 }
1107
1108 return IMU_FAIL;
1109 } /* imu_it_handler */
1110
1111
1112 /**
1113 * @brief Getter function for IMU sensor data (interrupt mode).
1114 * @param cpy_ptr: Destination struct for the copied sensor readout.
1115 * @return IMU_STATUS: IMU_BUSY until both imu_data_ready and mag_data_ready
1116 * are set by imu_it_handler().
1117 */
1118 1177 IMU_STATUS get_imu_it
1119 (
1120 IMU_RAW* cpy_ptr
1121 )
1122 {
1123
2/4
✓ Branch 0 taken 1177 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1177 times.
1177 if( !imu_data_ready || !mag_data_ready )
1124 {
1125 ✗ return IMU_BUSY;
1126 }
1127
1128 1177 memcpy( cpy_ptr, &imu_raw_processed, sizeof( IMU_RAW ) );
1129
1130 1177 return IMU_OK;
1131 } /* get_imu_it */
1132
1133
1134 /**
1135 * @brief Read the specified number of registers at one time from the
1136 * magnetometer module in the IMU (interrupt mode).
1137 * @param reg_addr: Starting register address.
1138 * @param data_ptr: Destination buffer.
1139 * @param num_regs: Number of registers to read.
1140 * @return IMU_STATUS
1141 */
1142 1180 static IMU_STATUS read_mag_regs_IT
1143 (
1144 uint8_t reg_addr,
1145 uint8_t* data_ptr,
1146 uint8_t num_regs
1147 )
1148 {
1149 /*------------------------------------------------------------------------------
1150 Local variables
1151 ------------------------------------------------------------------------------*/
1152 1180 HAL_StatusTypeDef hal_status; /* Status return code of I2C HAL */
1153
1154
1155 /*------------------------------------------------------------------------------
1156 API function implementation
1157 ------------------------------------------------------------------------------*/
1158
1159 /* Read I2C registers */
1160 1180 hal_status = HAL_I2C_Mem_Read_IT( &( IMU_I2C ) ,
1161 IMU_MAG_ADDR ,
1162 reg_addr ,
1163 I2C_MEMADD_SIZE_8BIT,
1164 data_ptr ,
1165 num_regs );
1166
1167 /* Return status code of I2C HAL */
1168
1/2
✓ Branch 0 taken 1180 times.
✗ Branch 1 not taken.
1180 if ( hal_status != HAL_OK )
1169 {
1170 return IMU_MAG_ERROR;
1171 }
1172 else
1173 {
1174 1180 return IMU_OK;
1175 }
1176
1177 } /* read_mag_regs_IT */
1178
1179
1180 /**
1181 * @brief Getter function for the magnetometer trim from mag_init().
1182 * @return MAG_TRIM
1183 */
1184 5893 MAG_TRIM imu_get_mag_trim
1185 (
1186 void
1187 )
1188 {
1189 5893 return mag_trim;
1190
1191 } /* imu_get_mag_trim */
1192
1193 /*******************************************************************************
1194 * END OF FILE *
1195 *******************************************************************************/
1196