1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "sensor.h"
8 
9 /* Calculate the compensated temperature */
calculate_temperature(uint32_t adc_temp,int32_t * t_fine,struct calibration_coeffs * cal_coeffs)10 int32_t calculate_temperature(uint32_t adc_temp, int32_t *t_fine,
11 			      struct calibration_coeffs *cal_coeffs)
12 {
13 	int16_t temperature_compensated = 0;
14 	int64_t var1, var2, var3;
15 
16 	var1 = ((int32_t)adc_temp >> 3) - ((int32_t)cal_coeffs->par_t1 << 1);
17 	var2 = (var1 * (int32_t)cal_coeffs->par_t2) >> 11;
18 	var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
19 	var3 = ((var3) * ((int32_t)cal_coeffs->par_t3 << 4)) >> 14;
20 	*t_fine = var2 + var3;
21 	temperature_compensated = (int16_t)(((*t_fine * 5) + 128) >> 8);
22 	return temperature_compensated;
23 }
24 
25 /* Calculate the compensated pressure
26  * Note: temperature must be calculated first
27  * to obtain the 't_fine'
28  */
calculate_pressure(uint32_t pres_adc,int32_t t_fine,struct calibration_coeffs * cal_coeffs)29 uint32_t calculate_pressure(uint32_t pres_adc, int32_t t_fine,
30 			    struct calibration_coeffs *cal_coeffs)
31 {
32 	int32_t var1;
33 	int32_t var2;
34 	int32_t var3;
35 	int32_t pressure_comp;
36 	const int32_t pres_ovf_check = INT32_C(0x40000000);
37 
38 	var1 = (((int32_t)t_fine) >> 1) - 64000;
39 	var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)cal_coeffs->par_p6) >> 2;
40 	var2 = var2 + ((var1 * (int32_t)cal_coeffs->par_p5) << 1);
41 	var2 = (var2 >> 2) + ((int32_t)cal_coeffs->par_p4 << 16);
42 	var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * ((int32_t)cal_coeffs->par_p3 << 5)) >> 3) +
43 	       (((int32_t)cal_coeffs->par_p2 * var1) >> 1);
44 	var1 = var1 >> 18;
45 	var1 = ((32768 + var1) * (int32_t)cal_coeffs->par_p1) >> 15;
46 	pressure_comp = 1048576 - pres_adc;
47 	pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125));
48 	if (pressure_comp >= pres_ovf_check) {
49 		pressure_comp = ((pressure_comp / var1) << 1);
50 	} else {
51 		pressure_comp = ((pressure_comp << 1) / var1);
52 	}
53 
54 	var1 = ((int32_t)cal_coeffs->par_p9 *
55 		(int32_t)(((pressure_comp >> 3) * (pressure_comp >> 3)) >> 13)) >>
56 	       12;
57 	var2 = ((int32_t)(pressure_comp >> 2) * (int32_t)cal_coeffs->par_p8) >> 13;
58 	var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) *
59 		(int32_t)(pressure_comp >> 8) * (int32_t)cal_coeffs->par_p10) >>
60 	       17;
61 	pressure_comp = (int32_t)(pressure_comp) +
62 			((var1 + var2 + var3 + ((int32_t)cal_coeffs->par_p7 << 7)) >> 4);
63 
64 	return (uint32_t)pressure_comp;
65 }
66 
67 /* Calculate the relative humidity
68  * Note: temperature must be calculated first
69  * to obtain the 't_fine'
70  */
calculate_humidity(uint16_t hum_adc,int32_t t_fine,struct calibration_coeffs * cal_coeffs)71 uint32_t calculate_humidity(uint16_t hum_adc, int32_t t_fine, struct calibration_coeffs *cal_coeffs)
72 {
73 	int32_t var1;
74 	int32_t var2;
75 	int32_t var3;
76 	int32_t var4;
77 	int32_t var5;
78 	int32_t var6;
79 	int32_t temp_scaled;
80 	int32_t calc_hum;
81 
82 	temp_scaled = (((int32_t)t_fine * 5) + 128) >> 8;
83 	var1 = (int32_t)(hum_adc - ((int32_t)((int32_t)cal_coeffs->par_h1 * 16))) -
84 	       (((temp_scaled * (int32_t)cal_coeffs->par_h3) / ((int32_t)100)) >> 1);
85 	var2 = ((int32_t)cal_coeffs->par_h2 *
86 		(((temp_scaled * (int32_t)cal_coeffs->par_h4) / ((int32_t)100)) +
87 		 (((temp_scaled * ((temp_scaled * (int32_t)cal_coeffs->par_h5) / ((int32_t)100))) >>
88 		   6) /
89 		  ((int32_t)100)) +
90 		 (int32_t)(1 << 14))) >>
91 	       10;
92 	var3 = var1 * var2;
93 	var4 = (int32_t)cal_coeffs->par_h6 << 7;
94 	var4 = ((var4) + ((temp_scaled * (int32_t)cal_coeffs->par_h7) / ((int32_t)100))) >> 4;
95 	var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
96 	var6 = (var4 * var5) >> 1;
97 	calc_hum = (((var3 + var6) >> 10) * ((int32_t)1000)) >> 12;
98 	if (calc_hum > 100000) {
99 		calc_hum = 100000;
100 	} else if (calc_hum < 0) {
101 		calc_hum = 0;
102 	}
103 
104 	return (uint32_t)calc_hum;
105 }
106