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