GCC Code Coverage Report


Directory: ../../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.5% 216 / 0 / 236
Functions: 89.5% 17 / 0 / 19
Branches: 47.4% 18 / 0 / 38

driver/baro/baro.c
Line Branch Exec Source
1 /*******************************************************************************
2 *
3 * FILE:
4 * baro.c
5 *
6 * DESCRIPTION:
7 * Contains API functions for the barometric pressure sensor
8 *
9 * COPYRIGHT:
10 * Copyright (c) 2025 Sun Devil Rocketry.
11 * All rights reserved.
12 *
13 * This software is licensed under terms that can be found in the LICENSE
14 * file in the root directory of this software component.
15 * If no LICENSE file comes with this software, it is covered under the
16 * BSD-3-Clause.
17 *
18 * https://opensource.org/license/bsd-3-clause
19 *
20 *******************************************************************************/
21
22
23 /*------------------------------------------------------------------------------
24 Standard Includes
25 ------------------------------------------------------------------------------*/
26 #include <stdbool.h>
27 #include <string.h>
28 #include <math.h>
29 #include <stdatomic.h>
30
31 /*------------------------------------------------------------------------------
32 Project Includes
33 ------------------------------------------------------------------------------*/
34 #include "main.h"
35 #include "sdr_pin_defines_A0002.h"
36 #include "baro.h"
37
38 /*------------------------------------------------------------------------------
39 Global Variables
40 ------------------------------------------------------------------------------*/
41
42 /* Current Baro Sensor configuration */
43 static BARO_CONFIG baro_configuration;
44
45 /* Baro calibration coefficients for measurement compensation */
46 static BARO_CAL_DATA baro_cal_data;
47
48 uint8_t baro_raw_buffer[6];
49 float baro_pres_proc = NAN;
50 float baro_temp_proc = NAN;
51 static atomic_bool baro_data_ready = false;
52
53
54 /*------------------------------------------------------------------------------
55 Internal function prototypes
56 ------------------------------------------------------------------------------*/
57
58 /* Converts two bytes to uint16_t format */
59 static uint16_t bytes_to_uint16_t
60 (
61 uint8_t lsb_byte, /* In: Least significant byte */
62 uint8_t msb_byte /* In: Most significant byte */
63 );
64
65 /* Converts two bytes to int16_t format */
66 static int16_t bytes_to_int16_t
67 (
68 uint8_t lsb_byte, /* In: Least significant byte */
69 uint8_t msb_byte /* In: Most significant byte */
70 );
71
72 /* Read from the baro's registers at a specified address */
73 static BARO_STATUS read_regs
74 (
75 uint8_t reg_addr, /* In: Register address */
76 uint8_t num_regs, /* In: Number of registers to read */
77 uint8_t* pData /* Out: Register contents */
78 );
79
80
81 /* Write to one of the baro's registers at a specified address */
82 static BARO_STATUS write_reg
83 (
84 uint8_t reg_addr, /* In: Register address */
85 uint8_t data /* In: Register contents */
86 );
87
88 /* Load the compensation data from the baro sensor */
89 static BARO_STATUS load_cal_data
90 (
91 void
92 );
93
94 /* Apply the compensation formula to raw temperature readouts */
95 static float temp_compensate
96 (
97 uint32_t raw_readout
98 );
99
100 /* Apply the compensation formula to raw pressure readouts */
101 static float press_compensate
102 (
103 uint32_t raw_readout
104 );
105
106 /* Reset the baro sensor */
107 static BARO_STATUS baro_reset
108 (
109 void
110 );
111
112 /* Flush the FIFO buffer */
113 static BARO_STATUS baro_flush_fifo
114 (
115 void
116 );
117
118
119 /*------------------------------------------------------------------------------
120 API Functions
121 ------------------------------------------------------------------------------*/
122
123
124 /*******************************************************************************
125 * *
126 * PROCEDURE: *
127 * baro_init *
128 * *
129 * DESCRIPTION: *
130 * Intialize the barometric pressure sensor *
131 * *
132 *******************************************************************************/
133 2 BARO_STATUS baro_init
134 (
135 BARO_CONFIG* config_ptr
136 )
137 {
138 /*------------------------------------------------------------------------------
139 Local variables
140 ------------------------------------------------------------------------------*/
141 2 BARO_STATUS baro_status; /* Status code from Baro API calls */
142 2 uint8_t baro_device_id; /* Baro device id */
143 2 uint8_t baro_err_reg; /* Contents of error register */
144 2 float init_temp; /* Temperature read after init */
145
146
147 /*------------------------------------------------------------------------------
148 Initializations
149 ------------------------------------------------------------------------------*/
150 2 baro_status = BARO_OK;
151 2 baro_device_id = 0;
152 2 baro_err_reg = 0xFF;
153 2 init_temp = 0;
154
155
156 /*------------------------------------------------------------------------------
157 API Function Implementation
158 ------------------------------------------------------------------------------*/
159
160 /* Disable IRQ */
161 2 HAL_NVIC_DisableIRQ(I2C1_EV_IRQn);
162
163 /* Verify functional I2C connection to sensor */
164 2 baro_status = baro_get_device_id( &baro_device_id );
165
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
166 {
167 return BARO_I2C_ERROR;
168 }
169
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if ( baro_device_id != BMP390_DEVICE_ID &&
170 baro_device_id != BMP388_DEVICE_ID )
171 {
172 return BARO_UNRECOGNIZED_CHIP_ID;
173 }
174
175 /* Reset the sensor */
176 2 baro_status = baro_reset();
177
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
178 {
179 return BARO_CANNOT_RESET;
180 }
181 2 HAL_Delay( 10 );
182
183 /* Check the Baro error register */
184 2 baro_status = read_regs( BARO_REG_ERR_REG ,
185 sizeof( baro_err_reg ),
186 &baro_err_reg );
187
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
188 {
189 return BARO_I2C_ERROR;
190 }
191
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if ( baro_err_reg )
192 {
193 return BARO_ERROR;
194 }
195
196 /* Load the calibration coefficients */
197 2 baro_status = load_cal_data();
198
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
199 {
200 return BARO_CAL_ERROR;
201 }
202
203 /* Flush the sensor FIFO buffer */
204 2 baro_status = baro_flush_fifo();
205
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
206 {
207 return BARO_FIFO_ERROR;
208 }
209
210 /* Initialize the compensation temperature */
211 2 baro_status = baro_get_temp( &init_temp );
212
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
213 {
214 return baro_status;
215 }
216
217 /* Configure the sensor */
218 2 baro_status = baro_config( config_ptr );
219
220 /* Set up double buffer */
221 2 baro_data_ready = false;
222 2 memset( baro_raw_buffer, 0, sizeof( baro_raw_buffer ) );
223 2 HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
224
225 2 return baro_status;
226
227 } /* baro_init */
228
229
230 /*******************************************************************************
231 * *
232 * PROCEDURE: *
233 * baro_config *
234 * *
235 * DESCRIPTION: *
236 * Configure the barometric pressure sensor *
237 * *
238 *******************************************************************************/
239 2 BARO_STATUS baro_config
240 (
241 BARO_CONFIG* config_ptr
242 )
243 {
244 /*------------------------------------------------------------------------------
245 Local variables
246 ------------------------------------------------------------------------------*/
247 2 BARO_STATUS baro_status; /* Baro API call return codes */
248 2 uint8_t pwr_ctrl; /* Contents of PWR_CTRL register */
249 2 uint8_t osr; /* Contents of OSR register */
250 2 uint8_t odr; /* Contents of ODR register */
251 2 uint8_t iir; /* Contents of CONFIG register (IIR Filter) */
252
253
254 /*------------------------------------------------------------------------------
255 Initializations
256 ------------------------------------------------------------------------------*/
257 2 baro_status = BARO_OK;
258 2 pwr_ctrl = 0;
259 2 osr = 0;
260 2 odr = 0;
261 2 iir = 0;
262
263
264 /*------------------------------------------------------------------------------
265 Extract Baro settings from config struct
266 ------------------------------------------------------------------------------*/
267
268 /* Set register contents */
269 2 pwr_ctrl |= config_ptr -> enable; /* Enable sensors */
270 2 pwr_ctrl |= config_ptr -> mode << 4; /* Set operating mode */
271 2 osr |= config_ptr -> press_OSR_setting; /* Pressure oversampling */
272 2 osr |= config_ptr -> temp_OSR_setting << 3; /* Temperature oversampling */
273 2 odr |= config_ptr -> ODR_setting; /* Sampling Frequency */
274 2 iir |= config_ptr -> IIR_setting; /* IIR Filter Selection */
275
276 /* Set global baro configuration */
277 2 baro_configuration.enable = config_ptr -> enable;
278 2 baro_configuration.mode = config_ptr -> mode;
279 2 baro_configuration.press_OSR_setting = config_ptr -> press_OSR_setting;
280 2 baro_configuration.temp_OSR_setting = config_ptr -> temp_OSR_setting;
281 2 baro_configuration.ODR_setting = config_ptr -> ODR_setting;
282 2 baro_configuration.IIR_setting = config_ptr -> IIR_setting;
283
284
285 /*------------------------------------------------------------------------------
286 API function implementation
287 ------------------------------------------------------------------------------*/
288
289 /* Write to the PWR_CTRL register -> Operating mode and enable sensors */
290 2 baro_status = write_reg( BARO_REG_PWR_CTRL, pwr_ctrl );
291
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
292 {
293 return BARO_I2C_ERROR;
294 }
295
296 /* Write to the OSR register -> set the oversampling rate */
297 2 baro_status = write_reg( BARO_REG_OSR, osr );
298
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
299 {
300 return BARO_I2C_ERROR;
301 }
302
303 /* Write to the ODR register -> set the sampling frequency */
304 2 baro_status = write_reg( BARO_REG_ODR, odr );
305
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
306 {
307 return BARO_I2C_ERROR;
308 }
309
310 /* Write to the CONFIG register -> Configure the IIR filter */
311 2 baro_status = write_reg( BARO_REG_CONFIG, iir );
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( baro_status != BARO_OK )
313 {
314 ✗ return BARO_I2C_ERROR;
315 }
316
317 /* Configuration complete */
318 return BARO_OK;
319
320 } /* baro_config */
321
322
323 /*******************************************************************************
324 * *
325 * PROCEDURE: *
326 * baro_get_device_id *
327 * *
328 * DESCRIPTION: *
329 * Gets the device ID of the barometric pressure sensor, primarily used *
330 * to verify that the sensor can be accessed by the MCU *
331 * *
332 *******************************************************************************/
333 2 BARO_STATUS baro_get_device_id
334 (
335 uint8_t* baro_id_ptr /* Out: Baro device id */
336 )
337 {
338 /*------------------------------------------------------------------------------
339 Local Variables
340 ------------------------------------------------------------------------------*/
341 2 BARO_STATUS baro_status; /* Status codes returned from baro API calls */
342
343
344 /*------------------------------------------------------------------------------
345 API Function implementation
346 ------------------------------------------------------------------------------*/
347
348 /* Read baro register with I2C */
349 2 baro_status = read_regs( BARO_REG_CHIP_ID,
350 sizeof( uint8_t ),
351 baro_id_ptr );
352 2 return baro_status;
353 } /* baro_get_device_id */
354
355
356 /*******************************************************************************
357 * *
358 * PROCEDURE: *
359 * baro_get_pressure *
360 * *
361 * DESCRIPTION: *
362 * retrieves a pressure reading from the sensor *
363 * *
364 *******************************************************************************/
365 ✗ BARO_STATUS baro_get_pressure
366 (
367 float* pressure_ptr /* Out: Baro pressure */
368 )
369 {
370 /*------------------------------------------------------------------------------
371 Local variables
372 ------------------------------------------------------------------------------*/
373 ✗ uint8_t pressure_bytes[3]; /* Pressure raw readout bytes, LSB first */
374 ✗ uint32_t raw_pressure; /* Pressure raw readout in uint32_t format */
375 ✗ float comp_temp; /* Compensation temperature */
376 ✗ BARO_STATUS baro_status; /* Return codes for baro API calls */
377
378
379 /*------------------------------------------------------------------------------
380 Initializations
381 ------------------------------------------------------------------------------*/
382 ✗ raw_pressure = 0;
383 ✗ comp_temp = 0;
384 ✗ baro_status = BARO_OK;
385 ✗ memset( &pressure_bytes[0], 0, sizeof( pressure_bytes ) );
386
387
388 /*------------------------------------------------------------------------------
389 API function implementation
390 ------------------------------------------------------------------------------*/
391
392 /* Read 3 consecutive pressure data registers */
393 ✗ baro_status = read_regs( BARO_REG_PRESS_DATA,
394 sizeof( pressure_bytes ),
395 &pressure_bytes[0] );
396 ✗ if ( baro_status != BARO_OK )
397 {
398 return BARO_I2C_ERROR;
399 }
400
401 /* Combine all bytes value to 24 bit value */
402 ✗ raw_pressure = ( ( (uint32_t) pressure_bytes[2] << 16 ) |
403 ✗ ( (uint32_t) pressure_bytes[1] << 8 ) |
404 ✗ ( (uint32_t) pressure_bytes[0] ) );
405
406 /* Get compensation temperature for pressure compensation calculation */
407 ✗ baro_status = baro_get_temp( &comp_temp );
408
409 /* Compensate using calibration data */
410 ✗ *pressure_ptr = press_compensate( raw_pressure );
411
412 ✗ return BARO_OK;
413 } /* baro_get_pressure */
414
415
416 /*******************************************************************************
417 * *
418 * PROCEDURE: *
419 * baro_get_temp *
420 * *
421 * DESCRIPTION: *
422 * retrieves a temperature reading from the sensor *
423 * *
424 *******************************************************************************/
425 2 BARO_STATUS baro_get_temp
426 (
427 float* temp_ptr
428 )
429 {
430 /*------------------------------------------------------------------------------
431 Local variables
432 ------------------------------------------------------------------------------*/
433 2 uint8_t temp_bytes[3]; /* Raw temperature readout bytes, LSB first */
434 2 uint32_t raw_temp; /* Raw temperature readout in uint32_t format */
435 2 BARO_STATUS baro_status; /* Status codes returned from baro API calls */
436
437
438 /*------------------------------------------------------------------------------
439 Initializations
440 ------------------------------------------------------------------------------*/
441 2 raw_temp = 0;
442 2 baro_status = BARO_OK;
443 2 memset( &temp_bytes[0], 0, sizeof( temp_bytes ) );
444
445
446 /*------------------------------------------------------------------------------
447 API function implementation
448 ------------------------------------------------------------------------------*/
449
450 /* Read 3 consecutive temperature data registers */
451 2 baro_status = read_regs( BARO_REG_TEMP_DATA ,
452 sizeof( temp_bytes ),
453 &temp_bytes[0] );
454
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
455 {
456 return BARO_I2C_ERROR;
457 }
458
459 /* Combine all bytes value to 24 bit value */
460 2 raw_temp = ( ( (uint32_t) temp_bytes[2] << 16 ) |
461 2 ( (uint32_t) temp_bytes[1] << 8 ) |
462 2 ( (uint32_t) temp_bytes[0] ) );
463
464 /* Adjust using calibration data */
465 2 *temp_ptr = temp_compensate( raw_temp );
466
467 2 return BARO_OK;
468
469 } /* baro_get_temp */
470
471
472 /*******************************************************************************
473 * *
474 * PROCEDURE: *
475 * baro_get_altitude *
476 * *
477 * DESCRIPTION: *
478 * gets the altitude of the rocket from the sensor readouts *
479 * *
480 *******************************************************************************/
481 ✗ BARO_STATUS baro_get_altitude
482 (
483 void
484 )
485 {
486 ✗ return BARO_OK;
487 } /* baro_get_altitude */
488
489
490 /*------------------------------------------------------------------------------
491 Internal procedures
492 ------------------------------------------------------------------------------*/
493
494
495 /*******************************************************************************
496 * *
497 * PROCEDURE: *
498 * bytes_to_uin16_t *
499 * *
500 * DESCRIPTION: *
501 * Converts two bytes to uint16_t format *
502 * *
503 *******************************************************************************/
504 8 static uint16_t bytes_to_uint16_t
505 (
506 uint8_t lsb_byte, /* In: Least significant byte */
507 uint8_t msb_byte /* In: Most significant byte */
508 )
509 {
510 8 return ( ( (uint16_t) lsb_byte ) |
511 ( (uint16_t) msb_byte << 8 ) );
512 } /* bytes_to_uint16_t */
513
514
515 /*******************************************************************************
516 * *
517 * PROCEDURE: *
518 * bytes_to_in16_t *
519 * *
520 * DESCRIPTION: *
521 * Converts two bytes to int16_t format *
522 * *
523 *******************************************************************************/
524 6 static int16_t bytes_to_int16_t
525 (
526 uint8_t lsb_byte, /* In: Least significant byte */
527 uint8_t msb_byte /* In: Most significant byte */
528 )
529 {
530 6 uint16_t bytes_comb = ( ( (uint16_t) lsb_byte ) |
531 ( (uint16_t) msb_byte << 8 ) );
532 6 return ( (int16_t) bytes_comb );
533 } /* bytes_to_uint16_t */
534
535
536 /*******************************************************************************
537 * *
538 * PROCEDURE: *
539 * read_regs *
540 * *
541 * DESCRIPTION: *
542 * Read from the baro's registers at a specified address *
543 * *
544 *******************************************************************************/
545 8 static BARO_STATUS read_regs
546 (
547 uint8_t reg_addr, /* In: Register address */
548 uint8_t num_regs, /* In: Number of registers to read */
549 uint8_t* pData /* Out: Register contents */
550 )
551 {
552 /*------------------------------------------------------------------------------
553 Local variables
554 ------------------------------------------------------------------------------*/
555 8 HAL_StatusTypeDef hal_status; /* HAL API Return codes */
556 8 uint32_t i2c_timeout; /* I2C read timeout */
557
558
559 /*------------------------------------------------------------------------------
560 Initializations
561 ------------------------------------------------------------------------------*/
562 8 hal_status = HAL_OK;
563 8 i2c_timeout = BARO_DEFAULT_TIMEOUT*num_regs;
564
565
566 /*------------------------------------------------------------------------------
567 Implementation
568 ------------------------------------------------------------------------------*/
569
570 /* Read I2C register*/
571 8 hal_status = HAL_I2C_Mem_Read( &( BARO_I2C ) ,
572 BARO_I2C_ADDR ,
573 reg_addr ,
574 I2C_MEMADD_SIZE_8BIT,
575 pData ,
576 num_regs ,
577 i2c_timeout );
578
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ( hal_status != HAL_OK )
579 {
580 return BARO_I2C_ERROR;
581 }
582 else
583 {
584 8 return BARO_OK;
585 }
586
587 } /* read_reg */
588
589
590 /*******************************************************************************
591 * *
592 * PROCEDURE: *
593 * write_reg *
594 * *
595 * DESCRIPTION: *
596 * Write to one of the baro's registers at a specified address *
597 * *
598 *******************************************************************************/
599 12 static BARO_STATUS write_reg
600 (
601 uint8_t reg_addr, /* In: Register address */
602 uint8_t data /* In: Register contents */
603 )
604 {
605 /*------------------------------------------------------------------------------
606 Local variables
607 ------------------------------------------------------------------------------*/
608 12 HAL_StatusTypeDef hal_status; /* HAL API Return codes */
609
610
611 /*------------------------------------------------------------------------------
612 Implementation
613 ------------------------------------------------------------------------------*/
614
615 /* Write to register with I2C */
616 12 hal_status = HAL_I2C_Mem_Write( &( BARO_I2C ) ,
617 BARO_I2C_ADDR ,
618 reg_addr ,
619 I2C_MEMADD_SIZE_8BIT,
620 &data ,
621 sizeof( uint8_t ) ,
622 BARO_DEFAULT_TIMEOUT );
623
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if ( hal_status != HAL_OK )
624 {
625 return BARO_I2C_ERROR;
626 }
627 else
628 {
629 12 return BARO_OK;
630 }
631
632 } /* write_reg */
633
634
635 /*******************************************************************************
636 * *
637 * PROCEDURE: *
638 * load_cal_data *
639 * *
640 * DESCRIPTION: *
641 * Load the compensation data from the baro sensor *
642 * *
643 *******************************************************************************/
644 2 static BARO_STATUS load_cal_data
645 (
646 void
647 )
648 {
649 /*------------------------------------------------------------------------------
650 Local variables
651 ------------------------------------------------------------------------------*/
652 2 BARO_CAL_DATA_INT cal_data_int; /* Raw calibration data from baro */
653 2 uint8_t buffer[BARO_CAL_BUFFER_SIZE]; /* Buffer for cal data */
654 2 BARO_STATUS baro_status; /* Baro API return codes */
655
656
657 /*------------------------------------------------------------------------------
658 Initializations
659 ------------------------------------------------------------------------------*/
660 2 memset( &cal_data_int, 0, sizeof( cal_data_int ) );
661 2 memset( &buffer[0] , 0, sizeof( buffer ) );
662
663
664 /*------------------------------------------------------------------------------
665 Read Baro Registers
666 ------------------------------------------------------------------------------*/
667
668 /* Get Data */
669 2 baro_status = read_regs( BARO_REG_NVM_PAR_T1,
670 BARO_CAL_BUFFER_SIZE,
671 &buffer[0] );
672
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( baro_status != BARO_OK )
673 {
674 return baro_status;
675 }
676
677 /* Convert to proper integer format */
678 2 cal_data_int.par_t1 = bytes_to_uint16_t( buffer[0], buffer[1] );
679 2 cal_data_int.par_t2 = bytes_to_uint16_t( buffer[2], buffer[3] );
680 2 cal_data_int.par_t3 = (int8_t) buffer[4];
681 2 cal_data_int.par_p1 = bytes_to_int16_t( buffer[5], buffer[6] );
682 2 cal_data_int.par_p2 = bytes_to_int16_t( buffer[7], buffer[8] );
683 2 cal_data_int.par_p3 = (int8_t) buffer[9];
684 2 cal_data_int.par_p4 = (int8_t) buffer[10];
685 2 cal_data_int.par_p5 = bytes_to_uint16_t( buffer[11], buffer[12] );
686 2 cal_data_int.par_p6 = bytes_to_uint16_t( buffer[13], buffer[14] );
687 2 cal_data_int.par_p7 = (int8_t) buffer[15];
688 2 cal_data_int.par_p8 = (int8_t) buffer[16];
689 2 cal_data_int.par_p9 = bytes_to_int16_t( buffer[17], buffer[18] );
690 2 cal_data_int.par_p10 = (int8_t) buffer[19];
691 2 cal_data_int.par_p11 = (int8_t) buffer[20];
692
693
694 /*------------------------------------------------------------------------------
695 Convert to floating point format ( BMP390 Datasheet pg. 55 )
696 ------------------------------------------------------------------------------*/
697
698 /* Temp Compensation */
699 2 baro_cal_data.par_t1 = ( ( (float) cal_data_int.par_t1 )/( 0.00390625f ) );
700 2 baro_cal_data.par_t2 = ( ( (float) cal_data_int.par_t2 )/( 1073741824.0f ) );
701 2 baro_cal_data.par_t3 = ( ( (float) cal_data_int.par_t3 )/( 281474976710656.0f ) );
702
703 /* Pressure Compensation */
704 2 baro_cal_data.par_p1 = ( (float) ( cal_data_int.par_p1 - 16384 ) );
705 2 baro_cal_data.par_p1 /= ( 1048576.0f );
706 2 baro_cal_data.par_p2 = ( (float) ( cal_data_int.par_p2 - 16384 ) );
707 2 baro_cal_data.par_p2 /= ( 536870912.0f );
708 2 baro_cal_data.par_p3 = ( ( (float) cal_data_int.par_p3 )/( 4294967296.0f ) );
709 2 baro_cal_data.par_p4 = ( ( (float) cal_data_int.par_p4 )/( 137438953472.0f ) );
710 2 baro_cal_data.par_p5 = ( ( (float) cal_data_int.par_p5 )/( 0.125f ) );
711 2 baro_cal_data.par_p6 = ( ( (float) cal_data_int.par_p6 )/( 64.0f ) );
712 2 baro_cal_data.par_p7 = ( ( (float) cal_data_int.par_p7 )/( 256.0f ) );
713 2 baro_cal_data.par_p8 = ( ( (float) cal_data_int.par_p8 )/( 32768.0f ) );
714 2 baro_cal_data.par_p9 = ( ( (float) cal_data_int.par_p9 )/( 281474976710656.0f ) );
715 2 baro_cal_data.par_p10 = ( ( (float) cal_data_int.par_p10 )/( 281474976710656.0f ) );
716 2 baro_cal_data.par_p11 = ( ( (float) cal_data_int.par_p11 )/( 36893488147419103232.0f ) );
717
718 /* Load Successful */
719 2 return BARO_OK;
720
721 } /* load_cal_data */
722
723
724 /*******************************************************************************
725 * *
726 * PROCEDURE: *
727 * temp_compensate *
728 * *
729 * DESCRIPTION: *
730 * Apply the compensation formula to raw temperature readout *
731 * *
732 *******************************************************************************/
733 4 static float temp_compensate
734 (
735 uint32_t raw_readout
736 )
737 {
738 /*------------------------------------------------------------------------------
739 Local variables
740 ------------------------------------------------------------------------------*/
741 4 float partial_data1; /* Intermediate compensation results */
742 4 float partial_data2;
743
744
745 /*------------------------------------------------------------------------------
746 Initializations
747 ------------------------------------------------------------------------------*/
748 4 partial_data1 = 0;
749 4 partial_data2 = 0;
750
751
752 /*------------------------------------------------------------------------------
753 Calculations
754 ------------------------------------------------------------------------------*/
755 4 partial_data1 = (float)( raw_readout - baro_cal_data.par_t1 );
756 4 partial_data2 = (float)( partial_data1*baro_cal_data.par_t2 );
757 4 baro_cal_data.comp_temp = (float)( partial_data2 +
758 4 powf( partial_data1, 2)*baro_cal_data.par_t3 );
759 4 return baro_cal_data.comp_temp;
760
761 } /* temp_compensate */
762
763
764 /*******************************************************************************
765 * *
766 * PROCEDURE: *
767 * press_compensate *
768 * *
769 * DESCRIPTION: *
770 * Apply the compensation formula to raw pressure readouts *
771 * *
772 *******************************************************************************/
773 2 static float press_compensate
774 (
775 uint32_t raw_readout
776 )
777 {
778 /*------------------------------------------------------------------------------
779 Local variables
780 ------------------------------------------------------------------------------*/
781 2 float partial_data1; /* Intermediate compensation results */
782 2 float partial_data2;
783 2 float partial_data3;
784 2 float partial_data4;
785 2 float partial_out1;
786 2 float partial_out2;
787
788
789 /*------------------------------------------------------------------------------
790 Initializations
791 ------------------------------------------------------------------------------*/
792 2 partial_data1 = 0;
793 2 partial_data2 = 0;
794 2 partial_data3 = 0;
795 2 partial_data3 = 0;
796 2 partial_out1 = 0;
797 2 partial_out2 = 0;
798
799
800 /*------------------------------------------------------------------------------
801 Calculations
802 ------------------------------------------------------------------------------*/
803 2 partial_data1 = baro_cal_data.par_p6*baro_cal_data.comp_temp;
804 2 partial_data2 = baro_cal_data.par_p7*powf( baro_cal_data.comp_temp, 2 );
805 2 partial_data3 = baro_cal_data.par_p8*powf( baro_cal_data.comp_temp, 3 );
806 2 partial_out1 = ( baro_cal_data.par_p5 + partial_data1 +
807 partial_data2 + partial_data3 );
808
809 2 partial_data1 = baro_cal_data.par_p2*baro_cal_data.comp_temp;
810 2 partial_data2 = baro_cal_data.par_p3*powf( baro_cal_data.comp_temp, 2 );
811 2 partial_data3 = baro_cal_data.par_p4*powf( baro_cal_data.comp_temp, 3 );
812 2 partial_out2 = (float) raw_readout*( baro_cal_data.par_p1 +
813 2 partial_data1 +
814 2 partial_data2 +
815 partial_data3 );
816
817 2 partial_data1 = powf( ( (float) raw_readout ), 2 );
818 2 partial_data2 = ( baro_cal_data.par_p9 +
819 2 baro_cal_data.par_p10*baro_cal_data.comp_temp );
820 2 partial_data3 = partial_data1*partial_data2;
821 2 partial_data4 = ( partial_data3 +
822 2 powf( ( (float) raw_readout ), 3 )*baro_cal_data.par_p11 );
823
824 2 return partial_out1 + partial_out2 + partial_data4;
825
826 } /* press_compensate */
827
828
829 /*******************************************************************************
830 * *
831 * PROCEDURE: *
832 * baro_reset *
833 * *
834 * DESCRIPTION: *
835 * Performs a soft reset of the barometric pressure sensor *
836 * *
837 *******************************************************************************/
838 2 static BARO_STATUS baro_reset
839 (
840 void
841 )
842 {
843 2 return write_reg( BARO_REG_CMD, BARO_CMD_RESET );
844 } /* baro_reset */
845
846
847 /*******************************************************************************
848 * *
849 * PROCEDURE: *
850 * baro_flush_fifo *
851 * *
852 * DESCRIPTION: *
853 * Flushes the barometric pressure sensor FIFO buffer *
854 * *
855 *******************************************************************************/
856 2 static BARO_STATUS baro_flush_fifo
857 (
858 void
859 )
860 {
861 2 return write_reg( BARO_REG_CMD, BARO_CMD_FIFO_FLUSH );
862 } /* baro_flush_fifo */
863
864
865 /*******************************************************************************
866 * *
867 * PROCEDURE: *
868 * baro_get_baro_data_ready *
869 * *
870 * DESCRIPTION: *
871 * Returns the baro_data_ready flag *
872 * *
873 *******************************************************************************/
874 2 bool baro_get_baro_data_ready
875 (
876 void
877 )
878 {
879 2 return baro_data_ready;
880
881 } /* baro_get_baro_data_ready */
882
883
884 /*******************************************************************************
885 * *
886 * PROCEDURE: *
887 * start_baro_read_IT *
888 * *
889 * DESCRIPTION: *
890 * Receive baro data in interrupt mode. *
891 * *
892 *******************************************************************************/
893 4 BARO_STATUS start_baro_read_IT
894 (
895 void
896 )
897 {
898 /*------------------------------------------------------------------------------
899 Local variables
900 ------------------------------------------------------------------------------*/
901 4 HAL_StatusTypeDef hal_status; /* HAL API Return codes */
902 4 BARO_STATUS baro_status; /* Return codes for baro API calls */
903
904 /*------------------------------------------------------------------------------
905 Initializations
906 ------------------------------------------------------------------------------*/
907 4 hal_status = HAL_OK;
908 4 baro_status = BARO_OK;
909 4 memset( baro_raw_buffer, 0, sizeof( baro_raw_buffer ) );
910 4 baro_pres_proc = NAN;
911 4 baro_temp_proc = NAN;
912
913 /*------------------------------------------------------------------------------
914 Implementation
915 ------------------------------------------------------------------------------*/
916
917 /* Set ready flag to false */
918 4 baro_data_ready = false;
919
920 /* Read I2C register*/
921 4 hal_status = HAL_I2C_Mem_Read_IT( &( BARO_I2C ) ,
922 BARO_I2C_ADDR ,
923 BARO_REG_PRESS_DATA ,
924 I2C_MEMADD_SIZE_8BIT,
925 baro_raw_buffer ,
926 6 /* pres + temp */ );
927
928
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( hal_status != HAL_OK )
929 {
930 return BARO_I2C_ERROR;
931 }
932 else
933 {
934 4 return baro_status;
935 }
936
937 } /* start_baro_read_IT */
938
939
940 /*******************************************************************************
941 * *
942 * PROCEDURE: *
943 * baro_IT_handler *
944 * *
945 * DESCRIPTION: *
946 * ISR for baro data reception. Heavy ISR. Consider moving processing to *
947 * get_baro_IT. *
948 * *
949 *******************************************************************************/
950 2 BARO_STATUS baro_IT_handler
951 (
952 void
953 )
954 {
955 /*------------------------------------------------------------------------------
956 Local variables
957 ------------------------------------------------------------------------------*/
958 2 uint32_t raw_pressure; /* Pressure raw readout in uint32_t format */
959 2 uint32_t raw_temp; /* Temp raw readout in uint32_t format*/
960 2 BARO_STATUS baro_status; /* Return codes for baro API calls */
961
962
963 /*------------------------------------------------------------------------------
964 Initializations
965 ------------------------------------------------------------------------------*/
966 2 raw_pressure = 0;
967 2 raw_temp = 0;
968 2 baro_status = BARO_OK;
969
970
971 /*------------------------------------------------------------------------------
972 API function implementation
973 ------------------------------------------------------------------------------*/
974
975 /* Combine all bytes value to 24 bit value */
976 2 raw_pressure = ( ( (uint32_t) baro_raw_buffer[2] << 16 ) |
977 2 ( (uint32_t) baro_raw_buffer[1] << 8 ) |
978 2 ( (uint32_t) baro_raw_buffer[0] ) );
979
980 /* Combine all bytes value to 24 bit value */
981 2 raw_temp = ( ( (uint32_t) baro_raw_buffer[5] << 16 ) |
982 2 ( (uint32_t) baro_raw_buffer[4] << 8 ) |
983 2 ( (uint32_t) baro_raw_buffer[3] ) );
984
985 /* Adjust using calibration data */
986 2 baro_temp_proc = temp_compensate( raw_temp );
987
988 /* Compensate using calibration data */
989 2 baro_pres_proc = press_compensate( raw_pressure );
990
991 2 baro_data_ready = true;
992
993 2 return baro_status;
994 } /* baro_start_pressure_IT */
995
996
997 /*******************************************************************************
998 * *
999 * PROCEDURE: *
1000 * get_baro_it *
1001 * *
1002 * DESCRIPTION: *
1003 * Getter function for IT baro data. *
1004 * *
1005 *******************************************************************************/
1006 2 BARO_STATUS get_baro_it
1007 (
1008 float* pres_ptr, /* o: pressure */
1009 float* temp_ptr /* o: temperature */
1010 )
1011 {
1012
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if( !baro_data_ready )
1013 {
1014 return BARO_BUSY;
1015 }
1016
1017 2 *pres_ptr = baro_pres_proc;
1018 2 *temp_ptr = baro_temp_proc;
1019
1020 2 return BARO_OK;
1021 } /* get_baro_it */
1022
1023
1024 /*******************************************************************************
1025 * END OF FILE *
1026 *******************************************************************************/
1027