Mercurial > public > ostc4
annotate Small_CPU/Src/pressure.c @ 261:cc2406b835ff bm-3
Bugfix: do not reset saturation on surfacing
Commit 822416168585 introduced a subtle bug. On surfacing, the value of
saturation was reset to 0. This is prefect proof why global data is a
dangerous thing, and subtle changes can introduce seemingly unrelated
bugs.
While it would be much better to factor out as much as possible global
data, the fix here does not do that. Simply, the bug is fixed without
touching the rather complex gTissue_nitrogen_bar/gTissue_helium_bar
handling.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Tue, 23 Apr 2019 13:05:20 +0200 |
parents | 2b9775f71e30 |
children | 8e9c502c0b06 |
rev | line source |
---|---|
38 | 1 /** |
2 ****************************************************************************** | |
3 * @file pressure.c | |
4 * @author heinrichs weikamp gmbh | |
5 * @date 2014 | |
6 * @version V0.0.2 | |
7 * @since 20-Oct-2016 | |
8 * @brief | |
9 * | |
10 @verbatim | |
11 ============================================================================== | |
12 ##### How to use ##### | |
13 ============================================================================== | |
14 V0.0.2 18-Oct-2016 pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015 | |
15 | |
16 @endverbatim | |
17 ****************************************************************************** | |
18 * @attention | |
19 * | |
20 * <h2><center>© COPYRIGHT(c) 2016 heinrichs weikamp</center></h2> | |
21 * | |
22 ****************************************************************************** | |
23 */ | |
24 | |
25 | |
26 | |
27 /* surface time | |
28 the last 30 minutes will be saved once per minute in a endless loop | |
29 at the beginning of a dive the oldest value will be used | |
30 */ | |
31 | |
241
2b9775f71e30
cleanup: factor out I2C1_Status() and cleanup type
Jan Mulder <jlmulder@xs4all.nl>
parents:
186
diff
changeset
|
32 #include "scheduler.h" |
38 | 33 #include "pressure.h" |
34 #include "i2c.h" | |
35 #include "rtc.h" | |
36 | |
37 #define CMD_RESET 0x1E // ADC reset command | |
38 #define CMD_ADC_READ 0x00 // ADC read command | |
39 #define CMD_ADC_CONV 0x40 // ADC conversion command | |
40 #define CMD_ADC_D1 0x00 // ADC D1 conversion | |
41 #define CMD_ADC_D2 0x10 // ADC D2 conversion | |
42 #define CMD_ADC_256 0x00 // ADC OSR=256 | |
43 #define CMD_ADC_512 0x02 // ADC OSR=512 | |
44 #define CMD_ADC_1024 0x04 // ADC OSR=1024 | |
45 #define CMD_ADC_2048 0x06 // ADC OSR=2056 | |
46 #define CMD_ADC_4096 0x08 // ADC OSR=4096 | |
47 #define CMD_PROM_RD 0xA0 // Prom read command | |
48 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
49 static uint16_t get_ci_by_coef_num(uint8_t coef_num); |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
50 //void pressure_calculation_new(void); |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
51 //void pressure_calculation_old(void); |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
52 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
53 static uint8_t crc4(uint16_t n_prom[]); |
38 | 54 |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
55 static HAL_StatusTypeDef pressure_sensor_get_data(void); |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
56 static uint32_t get_adc(void); |
38 | 57 uint8_t pressureSensorInitSuccess = 0; |
58 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
59 static uint16_t C[8] = { 1 }; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
60 static uint32_t D1 = 1; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
61 static uint32_t D2 = 1; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
62 static uint8_t n_crc; |
38 | 63 |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
64 static int64_t C5_x_2p8 = 1; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
65 static int64_t C2_x_2p16 = 1; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
66 static int64_t C1_x_2p15 = 1; |
38 | 67 |
68 /* | |
69 short C2plus10000 = -1; | |
70 short C3plus200 = -1; | |
71 short C4minus250 = -1; | |
72 short UT1 = -1; | |
73 short C6plus100 = -1; | |
74 */ | |
75 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
76 static float ambient_temperature = 0; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
77 static float ambient_pressure_mbar = 0; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
78 static float surface_pressure_mbar = 1000; |
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
79 static float surface_ring_mbar[31] = { 0 }; |
38 | 80 |
81 uint8_t secondCounterSurfaceRing = 0; | |
82 | |
83 float get_temperature(void) | |
84 { | |
85 return ambient_temperature; | |
86 } | |
87 | |
88 float get_pressure_mbar(void) | |
89 { | |
90 return ambient_pressure_mbar; | |
91 } | |
92 | |
93 float get_surface_mbar(void) | |
94 { | |
95 return surface_pressure_mbar; | |
96 } | |
97 | |
98 | |
99 void init_surface_ring(void) | |
100 { | |
101 surface_ring_mbar[0] = 0; | |
102 for(int i=1; i<31; i++) | |
103 surface_ring_mbar[i] = ambient_pressure_mbar; | |
104 surface_pressure_mbar = ambient_pressure_mbar; | |
105 } | |
106 | |
107 | |
108 /* the ring has one place with 0 | |
109 * after that comes the oldest value | |
110 * the new pressure is written in this hole | |
111 * the oldest value is read and then the new hole | |
112 */ | |
113 void update_surface_pressure(uint8_t call_rhythm_seconds) | |
114 { | |
115 secondCounterSurfaceRing += call_rhythm_seconds; | |
116 | |
117 if(secondCounterSurfaceRing < 60) | |
118 return; | |
119 | |
120 secondCounterSurfaceRing = 0; | |
121 | |
122 int hole; | |
123 for(hole=30;hole>0;hole--) | |
124 if(surface_ring_mbar[hole] == 0) { break; } | |
125 | |
126 surface_ring_mbar[hole] = ambient_pressure_mbar; | |
127 | |
128 hole++; | |
129 if(hole > 30) | |
130 hole = 0; | |
131 surface_pressure_mbar = surface_ring_mbar[hole]; | |
132 surface_ring_mbar[hole] = 0; | |
133 } | |
134 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
135 #ifdef DEMOMODE |
38 | 136 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) |
137 { | |
138 const float temperature_surface = 31.0; | |
139 const float temperature_bottom = 14.0; | |
140 | |
141 const float temperature_difference = temperature_bottom - temperature_surface; | |
142 | |
143 // range 0.0 - 1.0 | |
144 float position_now = (ambient_pressure_mbar - surface_pressure_mbar) / bottom_mbar_diff_to_surface; | |
145 | |
146 if(position_now <= 0) | |
147 return temperature_surface; | |
148 | |
149 if(position_now >= 1) | |
150 return temperature_bottom; | |
151 | |
152 return temperature_surface + (temperature_difference * position_now); | |
153 } | |
154 | |
155 | |
156 uint32_t demo_modify_temperature_and_pressure(int32_t divetime_in_seconds, uint8_t subseconds, float ceiling_mbar) | |
157 { | |
158 | |
159 const float descent_rate = 4000/60; | |
160 const float ascent_rate = 1000/60; | |
161 const uint32_t seconds_descend = (1 * 60) + 30; | |
162 const uint32_t turbo_seconds_at_bottom_start = (0 * 60) + 0; | |
163 const uint32_t seconds_descend_and_bottomtime = seconds_descend + turbo_seconds_at_bottom_start + (2 * 60) + 0; | |
164 uint32_t time_elapsed_in_seconds; | |
165 static float ambient_pressure_mbar_memory = 0; | |
166 static uint32_t time_last_call = 0; | |
167 | |
168 if(divetime_in_seconds <= seconds_descend) | |
169 { | |
170 ambient_pressure_mbar = (divetime_in_seconds * descent_rate) + ((float)(subseconds) * descent_rate) + surface_pressure_mbar; | |
171 ambient_temperature = demo_modify_temperature_helper(descent_rate * seconds_descend); | |
172 | |
173 time_last_call = divetime_in_seconds; | |
174 return 0; | |
175 } | |
176 else | |
177 if(divetime_in_seconds <= seconds_descend + turbo_seconds_at_bottom_start) | |
178 { | |
179 ambient_pressure_mbar = (seconds_descend * descent_rate) + surface_pressure_mbar; | |
180 ambient_temperature = demo_modify_temperature_helper(descent_rate * seconds_descend); | |
181 ambient_pressure_mbar_memory = ambient_pressure_mbar; | |
182 time_last_call = divetime_in_seconds; | |
183 return turbo_seconds_at_bottom_start; | |
184 } | |
185 else | |
186 if(divetime_in_seconds <= seconds_descend_and_bottomtime) | |
187 { | |
188 ambient_pressure_mbar = (seconds_descend * descent_rate) + surface_pressure_mbar; | |
189 ambient_temperature = demo_modify_temperature_helper(descent_rate * seconds_descend); | |
190 ambient_pressure_mbar_memory = ambient_pressure_mbar; | |
191 time_last_call = divetime_in_seconds; | |
192 return 0; | |
193 } | |
194 else | |
195 { | |
196 time_elapsed_in_seconds = divetime_in_seconds - time_last_call; | |
197 ambient_pressure_mbar = ambient_pressure_mbar_memory - time_elapsed_in_seconds * ascent_rate; | |
198 | |
199 if(ambient_pressure_mbar < surface_pressure_mbar) | |
200 ambient_pressure_mbar = surface_pressure_mbar; | |
201 else if(ambient_pressure_mbar < ceiling_mbar) | |
202 ambient_pressure_mbar = ceiling_mbar; | |
203 | |
204 ambient_temperature = demo_modify_temperature_helper(descent_rate * seconds_descend); | |
205 ambient_pressure_mbar_memory = ambient_pressure_mbar; | |
206 time_last_call = divetime_in_seconds; | |
207 return 0; | |
208 } | |
209 } | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
210 #endif |
38 | 211 |
212 | |
213 /* called just once on power on */ | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
214 /* TBD old DR5 code? */ |
38 | 215 void init_pressure_DRx(void) |
216 { | |
217 uint8_t resetCommand[1] = {0x1E}; | |
218 | |
219 I2C_Master_Transmit( DEVICE_PRESSURE, resetCommand, 1); | |
220 HAL_Delay(3); | |
221 | |
222 C[1] = get_ci_by_coef_num(0x02); | |
223 C[2] = get_ci_by_coef_num(0x04); | |
224 C[3] = get_ci_by_coef_num(0x06); | |
225 C[4] = get_ci_by_coef_num(0x08); | |
226 C[5] = get_ci_by_coef_num(0x0A); | |
227 C[6] = get_ci_by_coef_num(0x0C); | |
228 | |
229 C5_x_2p8 = C[5] * 256; | |
230 C2_x_2p16 = C[2] * 65536; | |
231 C1_x_2p15 = C[1] * 32768; | |
232 pressure_update(); | |
233 } | |
234 | |
235 uint8_t is_init_pressure_done(void) | |
236 { | |
237 return pressureSensorInitSuccess; | |
238 } | |
239 | |
240 uint8_t init_pressure(void) | |
241 { | |
242 uint8_t buffer[1]; | |
243 buffer[0] = 0x1e; | |
244 uint8_t retValue = 0xFF; | |
245 | |
246 | |
247 retValue = I2C_Master_Transmit( DEVICE_PRESSURE, buffer, 1); | |
248 if(retValue != HAL_OK) | |
249 { | |
250 return (HAL_StatusTypeDef)retValue; | |
251 } | |
252 HAL_Delay(3); | |
253 | |
254 for(uint8_t i=0;i<8;i++) | |
255 { | |
256 C[i] = get_ci_by_coef_num(i); | |
257 } | |
258 n_crc = crc4(C); // no evaluation at the moment hw 151026 | |
259 | |
260 C5_x_2p8 = C[5] * 256; | |
261 C2_x_2p16 = C[2] * 65536; | |
262 C1_x_2p15 = C[1] * 32768; | |
263 | |
241
2b9775f71e30
cleanup: factor out I2C1_Status() and cleanup type
Jan Mulder <jlmulder@xs4all.nl>
parents:
186
diff
changeset
|
264 if(global.I2C_SystemStatus == HAL_OK) |
38 | 265 { |
266 pressureSensorInitSuccess = 1; | |
267 } | |
268 return pressure_update(); | |
269 } | |
270 | |
271 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
272 static uint32_t get_adc(void) |
38 | 273 { |
274 uint8_t buffer[1]; | |
275 uint8_t resivebuf[4]; | |
276 uint32_t answer = 0; | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
277 |
38 | 278 buffer[0] = 0x00; // Get ADC |
279 I2C_Master_Transmit( DEVICE_PRESSURE, buffer, 1); | |
280 I2C_Master_Receive( DEVICE_PRESSURE, resivebuf, 4); | |
281 resivebuf[3] = 0; | |
282 answer = 256*256 *(uint32_t)resivebuf[0] + 256 * (uint32_t)resivebuf[1] + (uint32_t)resivebuf[2]; | |
283 | |
284 return answer; | |
285 } | |
286 | |
287 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
288 static uint16_t get_ci_by_coef_num(uint8_t coef_num) |
38 | 289 { |
290 uint8_t resivebuf[2]; | |
291 | |
292 uint8_t cmd = CMD_PROM_RD+coef_num*2; | |
293 I2C_Master_Transmit( DEVICE_PRESSURE, &cmd, 1); | |
294 I2C_Master_Receive( DEVICE_PRESSURE, resivebuf, 2); | |
295 return (256*(uint16_t)resivebuf[0]) + (uint16_t)resivebuf[1]; | |
296 } | |
297 | |
298 | |
299 | |
300 uint8_t pressure_update(void) | |
301 { | |
302 HAL_StatusTypeDef statusReturn = HAL_TIMEOUT; | |
303 | |
304 statusReturn = pressure_sensor_get_data(); | |
305 pressure_calculation(); | |
306 return (uint8_t)statusReturn; | |
307 } | |
308 | |
309 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
310 static uint32_t pressure_sensor_get_one_value(uint8_t cmd, HAL_StatusTypeDef *statusReturn) |
38 | 311 { |
312 uint8_t command = CMD_ADC_CONV + cmd; | |
313 HAL_StatusTypeDef statusReturnTemp = HAL_TIMEOUT; | |
314 | |
315 statusReturnTemp = I2C_Master_Transmit( DEVICE_PRESSURE, &command, 1); | |
316 | |
317 if(statusReturn) | |
318 { | |
319 *statusReturn = statusReturnTemp; | |
320 } | |
321 | |
322 switch (cmd & 0x0f) // wait necessary conversion time | |
323 { | |
324 case CMD_ADC_256 : HAL_Delay(1); break; | |
325 case CMD_ADC_512 : HAL_Delay(3); break; | |
326 case CMD_ADC_1024: HAL_Delay(4); break; | |
327 case CMD_ADC_2048: HAL_Delay(6); break; | |
328 case CMD_ADC_4096: HAL_Delay(10); break; | |
329 } | |
330 return get_adc(); | |
331 } | |
332 | |
333 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
334 static HAL_StatusTypeDef pressure_sensor_get_data(void) |
38 | 335 { |
336 HAL_StatusTypeDef statusReturn1 = HAL_TIMEOUT; | |
337 HAL_StatusTypeDef statusReturn2 = HAL_TIMEOUT; | |
338 | |
339 D2 = pressure_sensor_get_one_value(CMD_ADC_D2 + CMD_ADC_4096, &statusReturn1); | |
340 D1 = pressure_sensor_get_one_value(CMD_ADC_D1 + CMD_ADC_4096, &statusReturn2); | |
341 | |
342 if(statusReturn2 > statusReturn1) // if anything is not HAL_OK (0x00) or worse | |
343 return statusReturn2; | |
344 else | |
345 return statusReturn1; | |
346 } | |
347 | |
348 | |
349 void pressure_sensor_get_pressure_raw(void) | |
350 { | |
351 D1 = pressure_sensor_get_one_value(CMD_ADC_D1 + CMD_ADC_4096, 0); | |
352 } | |
353 | |
354 | |
355 void pressure_sensor_get_temperature_raw(void) | |
356 { | |
357 D2 = pressure_sensor_get_one_value(CMD_ADC_D2 + CMD_ADC_4096, 0); | |
358 } | |
359 | |
360 | |
361 void pressure_calculation(void) | |
362 { | |
241
2b9775f71e30
cleanup: factor out I2C1_Status() and cleanup type
Jan Mulder <jlmulder@xs4all.nl>
parents:
186
diff
changeset
|
363 if(global.I2C_SystemStatus != HAL_OK) |
38 | 364 return; |
365 | |
366 pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(); | |
367 } | |
368 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
369 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) |
38 | 370 { |
371 uint32_t local_D1; // ADC value of the pressure conversion | |
372 uint32_t local_D2; // ADC value of the temperature conversion | |
373 int32_t local_Px10; // compensated pressure value | |
374 int32_t local_Tx100; // compensated temperature value | |
375 int64_t local_dT; // int32_t, difference between actual and measured temperature | |
376 int64_t local_OFF; // offset at actual temperature | |
377 int64_t local_SENS; // sensitivity at actual temperature | |
378 | |
379 int64_t T2; | |
380 int64_t OFF2; | |
381 int64_t SENS2; | |
382 | |
383 local_D1 = D1; | |
384 local_D2 = D2; | |
385 | |
386 local_dT = ((int64_t)local_D2) - ((int64_t)C[5]) * 256; //pow(2,8); | |
387 local_OFF = ((int64_t)C[2]) * 65536 + local_dT * ((int64_t)C[4]) / 128; // pow(2,16), pow(2,7) | |
388 local_SENS = ((int64_t)C[1]) * 32768 + local_dT * ((int64_t)C[3]) / 256; // pow(2,15), pow(2,8) | |
389 | |
390 local_Tx100 = (int32_t)(2000 + (local_dT * ((int64_t)C[6])) / 8388608);// pow(2,23) | |
391 | |
392 | |
393 if(local_Tx100 < 2000) // low temperature | |
394 { | |
395 T2 = 3 * local_dT; | |
396 T2 *= local_dT; | |
397 T2 /= 8589934592; | |
398 | |
399 OFF2 = ((int64_t)local_Tx100) - 2000; | |
400 OFF2 *= OFF2; | |
401 OFF2 *= 3; | |
402 OFF2 /= 2; | |
403 | |
404 SENS2 = ((int64_t)local_Tx100) - 2000; | |
405 SENS2 *= SENS2; | |
406 SENS2 *= 5; | |
407 SENS2 /= 8; | |
408 | |
409 local_Tx100 -= (int32_t)T2; | |
410 local_OFF -= OFF2; | |
411 local_SENS -= SENS2; | |
412 } | |
413 else | |
414 { | |
415 T2 = 7 * local_dT; | |
416 T2 *= local_dT; | |
417 T2 /= 137438953472; | |
418 | |
419 OFF2 = ((int64_t)local_Tx100) - 2000; | |
420 OFF2 *= OFF2; | |
421 OFF2 /= 16; | |
422 | |
423 local_Tx100 -= (int32_t)T2; | |
424 local_OFF -= OFF2; | |
425 } | |
426 | |
427 local_Px10 = (int32_t)( | |
428 (((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF) | |
429 / 8192 );// )) / 10; // pow(2,21), pow(2,13) | |
430 | |
431 ambient_temperature = ((float)local_Tx100) / 100; | |
432 ambient_pressure_mbar = ((float)local_Px10) / 10; | |
433 } | |
434 | |
435 | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
436 /* |
38 | 437 void pressure_calculation_new(void) |
438 { | |
439 #define POW2_8 (256) | |
440 #define POW2_17 (131072) | |
441 #define POW2_6 (64) | |
442 #define POW2_16 (65536) | |
443 #define POW2_7 (128) | |
444 #define POW2_23 (8388608) | |
445 #define POW2_21 (2097152) | |
446 #define POW2_15 (32768) | |
447 #define POW2_13 (8192) | |
448 #define POW2_37 (137438953472) | |
449 #define POW2_4 (16) | |
450 #define POW2_33 (8589934592) | |
451 #define POW2_3 (8) | |
452 | |
453 int32_t P; // compensated pressure value | |
454 int32_t T; // compensated temperature value | |
455 int32_t dT; // difference between actual and measured temperature | |
456 int64_t OFF; // offset at actual temperature | |
457 int64_t SENS; | |
458 | |
459 int32_t T2; | |
460 int64_t OFF2; | |
461 int64_t SENS2; | |
462 | |
463 dT = ((int32_t)D2) - ((int32_t)C[5]) * POW2_8; | |
464 OFF = ((int64_t)C[2]) * POW2_16 + ((int64_t)dT) * ((int64_t)C[4]) / POW2_7; | |
465 SENS = ((int64_t)C[1]) * POW2_15 + ((int64_t)dT) * ((int64_t)C[3]) / POW2_8; | |
466 | |
467 T = 2000 + (dT * ((int32_t)C[6])) / POW2_23; | |
468 | |
469 | |
470 if(T < 2000) // low temperature | |
471 { | |
472 T2 = 3 * dT * dT; | |
473 T2 /= POW2_33; | |
474 OFF2 = ((int64_t)T) - 2000; | |
475 OFF2 *= OFF2; | |
476 OFF2 *= 3; | |
477 OFF2 /= 2; | |
478 SENS2 = ((int64_t)T) - 2000; | |
479 SENS2 *= SENS2; | |
480 SENS2 *= 5; | |
481 SENS2 /= POW2_3; | |
482 } | |
483 else // high temperature | |
484 { | |
485 T2 = 7 * dT * dT; | |
486 T2 /= POW2_37; | |
487 OFF2 = ((int64_t)T) - 2000; | |
488 OFF2 *= OFF2; | |
489 OFF2 /= POW2_4; | |
490 SENS2 = 0; | |
491 } | |
492 | |
493 T = T - T2; | |
494 OFF = OFF - OFF2; | |
495 SENS = SENS - SENS2; | |
496 | |
497 P = (int32_t)(((((int64_t)D1) * SENS) / POW2_21 - OFF) / POW2_13); | |
498 | |
499 ambient_temperature = ((float)T) / 100; | |
500 ambient_pressure_mbar = ((float)P) / 10; | |
501 } | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
502 */ |
38 | 503 |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
504 /* |
38 | 505 void pressure_calculation_old(void) { |
506 // | |
507 double ambient_temperature_centigrad = 0; | |
508 double ambient_pressure_decimbar = 0; | |
509 | |
510 // static for debug | |
511 static int64_t dt = 0; | |
512 static int64_t temp = 0; | |
513 static int64_t ms_off = 0; | |
514 static int64_t sens = 0; | |
515 // | |
516 static int64_t ms_off2 = 0; | |
517 static int64_t sens2 = 0; | |
518 static int64_t t2 = 0; | |
519 | |
520 if((D2 == 0) || (D1 == 0)) | |
521 return; | |
522 // | |
523 | |
524 // dT = D2 - C[5] * POW2_8; | |
525 // T = 2000 + (dT * C[6]) / POW2_23; | |
526 dt = (int64_t)D2 - C5_x_2p8; | |
527 //temp ; // in 10 milliGrad Celcius | |
528 ambient_temperature_centigrad = 2000 + dt * C[6] / 8388608; | |
529 | |
530 | |
531 if(ambient_temperature_centigrad < 2000) // low temperature | |
532 { | |
533 t2 = 3 * dt; | |
534 t2 *= dt; | |
535 t2 /= 8589934592; | |
536 ms_off2 = ambient_temperature_centigrad - 2000; | |
537 ms_off2 *= ms_off2; | |
538 sens2 = ms_off2; | |
539 ms_off2 *= 3; | |
540 ms_off2 /= 2; | |
541 sens2 *= 5; | |
542 sens2 /= 8; | |
543 } | |
544 else // high temperature | |
545 { | |
546 t2 = 7 * dt; | |
547 t2 *= dt; | |
548 t2 /= 137438953472; | |
549 ms_off2 = ambient_temperature_centigrad - 2000; | |
550 ms_off2 *= ms_off2; | |
551 ms_off2 /= 16; | |
552 sens2 = 0; | |
553 } | |
554 | |
555 | |
556 // | |
557 | |
558 // pressure | |
559 // OFF = C[2] * POW2_16 + dT * C[4] / POW2_7; | |
560 // SENS = C[1] * POW2_15 + dT * C[3] / POW2_8; | |
561 ms_off = C[4] * dt; | |
562 ms_off /= 128; | |
563 ms_off += C2_x_2p16; | |
564 // | |
565 sens = C[3] * dt; | |
566 sens /= 256; | |
567 sens += C1_x_2p15; | |
568 | |
569 // 2nd order correction | |
570 ambient_temperature_centigrad -= t2; | |
571 ms_off -= ms_off2; | |
572 sens -= sens2; | |
573 | |
574 ambient_temperature = ambient_temperature_centigrad / 100; | |
575 // P = (D1 * SENS / POW2_21 - OFF) / POW2_13; | |
576 temp = D1 * sens; | |
577 temp /= 2097152; | |
578 temp -= ms_off; | |
579 temp /= 8192; | |
580 ambient_pressure_decimbar = temp; // to float/double | |
581 ambient_pressure_mbar = ambient_pressure_decimbar / 10; | |
582 } | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
583 */ |
38 | 584 |
585 | |
586 /* taken from AN520 by meas-spec.com dated 9. Aug. 2011 | |
587 * short and int are both 16bit according to AVR/GCC google results | |
588 */ | |
186
f11f0bf6ef2d
cleanup: remove obsolete code, make static, etc.
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
589 static uint8_t crc4(uint16_t n_prom[]) |
38 | 590 { |
591 uint16_t cnt; // simple counter | |
592 uint16_t n_rem; // crc reminder | |
593 uint16_t crc_read; // original value of the crc | |
594 uint8_t n_bit; | |
595 n_rem = 0x00; | |
596 crc_read=n_prom[7]; //save read CRC | |
597 n_prom[7]=(0xFF00 & (n_prom[7])); //CRC byte is replaced by 0 | |
598 for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes | |
599 { // choose LSB or MSB | |
600 if (cnt%2==1) n_rem ^= (uint16_t) ((n_prom[cnt>>1]) & 0x00FF); | |
601 else n_rem ^= (uint16_t) (n_prom[cnt>>1]>>8); | |
602 for (n_bit = 8; n_bit > 0; n_bit--) | |
603 { | |
604 if (n_rem & (0x8000)) | |
605 { | |
606 n_rem = (n_rem << 1) ^ 0x3000; | |
607 } | |
608 else | |
609 { | |
610 n_rem = (n_rem << 1); | |
611 } | |
612 } | |
613 } | |
614 n_rem= (0x000F & (n_rem >> 12)); // // final 4-bit reminder is CRC code | |
615 n_prom[7]=crc_read; // restore the crc_read to its original place | |
616 return (n_rem ^ 0x00); | |
617 } | |
618 /* | |
619 void test_calculation(void) | |
620 { | |
621 C1 = 29112; | |
622 C2 = 26814; | |
623 C3 = 19125; | |
624 C4 = 17865; | |
625 C5 = 32057; | |
626 C6 = 31305; | |
627 | |
628 C2_x_2p16 = C2 * 65536; | |
629 C1_x_2p15 = C1 * 32768; | |
630 | |
631 D1 = 4944364; | |
632 D2 = 8198974; | |
633 pressure_calculation() ; | |
634 }; | |
635 */ | |
636 |