1 | /*!
|
2 | * @brief This internal API is used to calculate the temperature value.
|
3 | */
|
4 | static int16_t calc_temperature(uint32_t temp_adc, struct bme680_dev *dev)
|
5 | {
|
6 | int64_t var1;
|
7 | int64_t var2;
|
8 | int64_t var3;
|
9 | int16_t calc_temp;
|
10 |
|
11 | var1 = ((int32_t) temp_adc >> 3) - ((int32_t) dev->calib.par_t1 << 1);
|
12 | var2 = (var1 * (int32_t) dev->calib.par_t2) >> 11;
|
13 | var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
|
14 | var3 = ((var3) * ((int32_t) dev->calib.par_t3 << 4)) >> 14;
|
15 | dev->calib.t_fine = (int32_t) (var2 + var3);
|
16 | calc_temp = (int16_t) (((dev->calib.t_fine * 5) + 128) >> 8);
|
17 |
|
18 | return calc_temp;
|
19 | }
|
20 |
|
21 | /*!
|
22 | * @brief This internal API is used to calculate the pressure value.
|
23 | */
|
24 | static uint32_t calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev)
|
25 | {
|
26 | int32_t var1;
|
27 | int32_t var2;
|
28 | int32_t var3;
|
29 | int32_t pressure_comp;
|
30 |
|
31 | var1 = (((int32_t)dev->calib.t_fine) >> 1) - 64000;
|
32 | var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) *
|
33 | (int32_t)dev->calib.par_p6) >> 2;
|
34 | var2 = var2 + ((var1 * (int32_t)dev->calib.par_p5) << 1);
|
35 | var2 = (var2 >> 2) + ((int32_t)dev->calib.par_p4 << 16);
|
36 | var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
|
37 | ((int32_t)dev->calib.par_p3 << 5)) >> 3) +
|
38 | (((int32_t)dev->calib.par_p2 * var1) >> 1);
|
39 | var1 = var1 >> 18;
|
40 | var1 = ((32768 + var1) * (int32_t)dev->calib.par_p1) >> 15;
|
41 | pressure_comp = 1048576 - pres_adc;
|
42 | pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125));
|
43 | if (pressure_comp >= BME680_MAX_OVERFLOW_VAL)
|
44 | pressure_comp = ((pressure_comp / var1) << 1);
|
45 | else
|
46 | pressure_comp = ((pressure_comp << 1) / var1);
|
47 | var1 = ((int32_t)dev->calib.par_p9 * (int32_t)(((pressure_comp >> 3) *
|
48 | (pressure_comp >> 3)) >> 13)) >> 12;
|
49 | var2 = ((int32_t)(pressure_comp >> 2) *
|
50 | (int32_t)dev->calib.par_p8) >> 13;
|
51 | var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) *
|
52 | (int32_t)(pressure_comp >> 8) *
|
53 | (int32_t)dev->calib.par_p10) >> 17;
|
54 |
|
55 | pressure_comp = (int32_t)(pressure_comp) + ((var1 + var2 + var3 +
|
56 | ((int32_t)dev->calib.par_p7 << 7)) >> 4);
|
57 |
|
58 | return (uint32_t)pressure_comp;
|
59 |
|
60 | }
|
61 |
|
62 | /*!
|
63 | * @brief This internal API is used to calculate the humidity value.
|
64 | */
|
65 | static uint32_t calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev)
|
66 | {
|
67 | int32_t var1;
|
68 | int32_t var2;
|
69 | int32_t var3;
|
70 | int32_t var4;
|
71 | int32_t var5;
|
72 | int32_t var6;
|
73 | int32_t temp_scaled;
|
74 | int32_t calc_hum;
|
75 |
|
76 | temp_scaled = (((int32_t) dev->calib.t_fine * 5) + 128) >> 8;
|
77 | var1 = (int32_t) (hum_adc - ((int32_t) ((int32_t) dev->calib.par_h1 * 16)))
|
78 | - (((temp_scaled * (int32_t) dev->calib.par_h3) / ((int32_t) 100)) >> 1);
|
79 | var2 = ((int32_t) dev->calib.par_h2
|
80 | * (((temp_scaled * (int32_t) dev->calib.par_h4) / ((int32_t) 100))
|
81 | + (((temp_scaled * ((temp_scaled * (int32_t) dev->calib.par_h5) / ((int32_t) 100))) >> 6)
|
82 | / ((int32_t) 100)) + (int32_t) (1 << 14))) >> 10;
|
83 | var3 = var1 * var2;
|
84 | var4 = (int32_t) dev->calib.par_h6 << 7;
|
85 | var4 = ((var4) + ((temp_scaled * (int32_t) dev->calib.par_h7) / ((int32_t) 100))) >> 4;
|
86 | var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
|
87 | var6 = (var4 * var5) >> 1;
|
88 | calc_hum = (((var3 + var6) >> 10) * ((int32_t) 1000)) >> 12;
|
89 |
|
90 | if (calc_hum > 100000) /* Cap at 100%rH */
|
91 | calc_hum = 100000;
|
92 | else if (calc_hum < 0)
|
93 | calc_hum = 0;
|
94 |
|
95 | return (uint32_t) calc_hum;
|
96 | }
|
97 |
|
98 | /*!
|
99 | * @brief This internal API is used to calculate the Gas Resistance value.
|
100 | */
|
101 | static uint32_t calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev)
|
102 | {
|
103 | int64_t var1;
|
104 | uint64_t var2;
|
105 | int64_t var3;
|
106 | uint32_t calc_gas_res;
|
107 | /**Look up table 1 for the possible gas range values */
|
108 | uint32_t lookupTable1[16] = { UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647),
|
109 | UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2130303777),
|
110 | UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2143188679), UINT32_C(2136746228),
|
111 | UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2147483647) };
|
112 | /**Look up table 2 for the possible gas range values */
|
113 | uint32_t lookupTable2[16] = { UINT32_C(4096000000), UINT32_C(2048000000), UINT32_C(1024000000), UINT32_C(512000000),
|
114 | UINT32_C(255744255), UINT32_C(127110228), UINT32_C(64000000), UINT32_C(32258064), UINT32_C(16016016),
|
115 | UINT32_C(8000000), UINT32_C(4000000), UINT32_C(2000000), UINT32_C(1000000), UINT32_C(500000),
|
116 | UINT32_C(250000), UINT32_C(125000) };
|
117 |
|
118 | var1 = (int64_t) ((1340 + (5 * (int64_t) dev->calib.range_sw_err)) *
|
119 | ((int64_t) lookupTable1[gas_range])) >> 16;
|
120 | var2 = (((int64_t) ((int64_t) gas_res_adc << 15) - (int64_t) (16777216)) + var1);
|
121 | var3 = (((int64_t) lookupTable2[gas_range] * (int64_t) var1) >> 9);
|
122 | calc_gas_res = (uint32_t) ((var3 + ((int64_t) var2 >> 1)) / (int64_t) var2);
|
123 |
|
124 | return calc_gas_res;
|
125 | }
|