Mercurial > public > ostc4
annotate Discovery/Src/data_central.c @ 271:1303747b5ba2 write-from-sim
cleanup: also write gas and setpoint changes in simulator mode
This is related to the previous commit. There is all kinds of logic around
that distinguishes real diving mode and simulator mode. This is valid in certain
cases. For example, we do not want a simulator session to act as a repetitive dive
for subsequent real dives.
What is simply wrong, is skipping relevant logic, like gas switches to act
differently in the simulator and in a real dive. The main advantage of this
commit is code simplicity. Normal users will never see the difference, as
simulator dives are not logged (unless compiled in by a developer).
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Sat, 27 Apr 2019 09:32:16 +0200 |
parents | 2e58a4094770 |
children | 54d14bc2083c |
rev | line source |
---|---|
38 | 1 /** |
2 ****************************************************************************** | |
3 * @copyright heinrichs weikamp | |
4 * @file data_central.c | |
5 * @author heinrichs weikamp gmbh | |
6 * @date 10-November-2014 | |
7 * @version V1.0.2 | |
8 * @since 10-Nov-2014 | |
9 * @brief All the data EXCEPT | |
10 * - settings (settings.c) | |
11 * feste Werte, die nur an der Oberfl�che ge�ndert werden | |
12 * - dataIn and dataOut (data_exchange.h and data_exchange_main.c) | |
13 * Austausch mit Small CPU | |
14 * @bug | |
15 * @warning | |
16 @verbatim | |
17 ============================================================================== | |
18 ##### SDiveState Real and Sim ##### | |
19 ============================================================================== | |
20 [..] SDiveSettings | |
21 copy of parts of Settings that are necessary during the dive | |
22 and could be modified during the dive without post dive changes. | |
23 | |
24 [..] SLifeData | |
25 written in DataEX_copy_to_LifeData(); | |
26 block 1 "lifedata" set by SmallCPU in stateReal | |
27 block 2 "actualGas" set by main CPU from user input and send to Small CPU | |
28 block 3 "calculated data" set by main CPU based on "lifedata" | |
29 | |
30 [..] SVpm | |
31 | |
32 [..] SEvents | |
33 | |
34 [..] SDecoinfo | |
35 | |
36 [..] mode | |
37 set by SmallCPU in stateReal, can be surface, dive, ... | |
38 | |
39 [..] data_old__lost_connection_to_slave | |
40 set by DataEX_copy_to_LifeData(); | |
41 | |
42 ============================================================================== | |
43 ##### SDiveState Deco ##### | |
44 ============================================================================== | |
45 [..] kjbkldafj�lasdfjasdf | |
46 | |
47 ============================================================================== | |
48 ##### decoLock ##### | |
49 ============================================================================== | |
50 [..] The handler that synchronizes the data between IRQ copy and main deco loop | |
51 | |
52 | |
53 @endverbatim | |
54 ****************************************************************************** | |
55 * @attention | |
56 * | |
57 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2> | |
58 * | |
59 ****************************************************************************** | |
60 */ | |
61 | |
62 /* Includes ------------------------------------------------------------------*/ | |
63 #include <string.h> | |
64 #include "data_central.h" | |
65 #include "calc_crush.h" | |
66 #include "decom.h" | |
67 #include "stm32f4xx_hal.h" | |
68 #include "settings.h" | |
69 #include "data_exchange_main.h" | |
70 #include "ostc.h" // for button adjust on hw testboard 1 | |
71 #include "tCCR.h" | |
72 #include "crcmodel.h" | |
73 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
149
diff
changeset
|
74 static SDiveState stateReal = { 0 }; |
38 | 75 SDiveState stateSim = { 0 }; |
76 SDiveState stateDeco = { 0 }; | |
77 | |
78 SDevice stateDevice = | |
79 { | |
80 /* max is 0x7FFFFFFF, min is 0x80000000 but also defined in stdint.h :-) */ | |
81 | |
82 /* count, use 0 */ | |
83 .batteryChargeCompleteCycles.value_int32 = 0, | |
84 .batteryChargeCycles.value_int32 = 0, | |
85 .diveCycles.value_int32 = 0, | |
86 .hoursOfOperation.value_int32 = 0, | |
87 | |
88 /* max values, use min. */ | |
89 .temperatureMaximum.value_int32 = INT32_MIN, | |
90 .depthMaximum.value_int32 = INT32_MIN, | |
91 | |
92 /* min values, use max. */ | |
93 .temperatureMinimum.value_int32 = INT32_MAX, | |
94 .voltageMinimum.value_int32 = INT32_MAX, | |
95 }; | |
96 | |
97 SVpmRepetitiveData stateVPM = | |
98 { | |
99 .repetitive_variables_not_valid = 1, | |
100 .is_data_from_RTE_CPU = 0, | |
101 }; | |
102 | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
103 const SDiveState *stateUsed = &stateReal; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
104 SDiveState *stateUsedWrite = &stateReal; |
38 | 105 |
106 void set_stateUsedToReal(void) | |
107 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
108 stateUsed = stateUsedWrite = &stateReal; |
38 | 109 } |
110 | |
111 void set_stateUsedToSim(void) | |
112 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
113 stateUsed = stateUsedWrite = &stateSim; |
38 | 114 } |
115 | |
116 _Bool is_stateUsedSetToSim(void) | |
117 { | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
149
diff
changeset
|
118 return stateUsed == &stateSim; |
38 | 119 } |
120 | |
121 const SDiveState * stateRealGetPointer(void) | |
122 { | |
123 return &stateReal; | |
124 } | |
125 | |
126 SDiveState * stateRealGetPointerWrite(void) | |
127 { | |
128 return &stateReal; | |
129 } | |
130 | |
131 | |
132 const SDiveState * stateSimGetPointer(void) | |
133 { | |
134 return &stateSim; | |
135 } | |
136 | |
137 | |
138 SDiveState * stateSimGetPointerWrite(void) | |
139 { | |
140 return &stateSim; | |
141 } | |
142 | |
143 | |
144 const SDevice * stateDeviceGetPointer(void) | |
145 { | |
146 return &stateDevice; | |
147 } | |
148 | |
149 | |
150 SDevice * stateDeviceGetPointerWrite(void) | |
151 { | |
152 return &stateDevice; | |
153 } | |
154 | |
155 | |
156 const SVpmRepetitiveData * stateVpmRepetitiveDataGetPointer(void) | |
157 { | |
158 return &stateVPM; | |
159 } | |
160 | |
161 | |
162 SVpmRepetitiveData * stateVpmRepetitiveDataGetPointerWrite(void) | |
163 { | |
164 return &stateVPM; | |
165 } | |
166 | |
167 | |
168 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow) | |
169 { | |
170 if(ticksstart <= ticksnow) | |
171 return ticksnow - ticksstart; | |
172 else | |
173 return 0xFFFFFFFF - ticksstart + ticksnow; | |
174 } | |
175 | |
176 | |
177 uint8_t decoLock = DECO_CALC_undefined; | |
178 int ascent_rate_meter_per_min = 12; | |
179 int descent_rate_meter_per_min = 20; | |
180 int max_depth = 70; | |
181 int bottom_time = 10; | |
182 | |
183 _Bool vpm_crush(SDiveState* pDiveState); | |
184 void setSimulationValues(int _ascent_rate_meter_per_min, int _descent_rate_meter_per_min, int _max_depth, int _bottom_time ) | |
185 { | |
186 ascent_rate_meter_per_min = _ascent_rate_meter_per_min; | |
187 descent_rate_meter_per_min = _descent_rate_meter_per_min; | |
188 max_depth = _max_depth; | |
189 bottom_time = _bottom_time; | |
190 } | |
191 | |
192 | |
193 | |
194 int current_second(void) { | |
195 | |
196 return HAL_GetTick() / 1000; | |
197 // printf("milliseconds: %lld\n", milliseconds); | |
198 //return milliseconds; | |
199 } | |
200 | |
201 | |
202 | |
203 #define OXY_ONE_SIXTIETH_PART 0.0166667f | |
204 | |
205 /*void oxygen_calculate_cns(float* oxygen_cns, float pressure_oxygen_real) | |
206 { | |
207 int cns_no_range = 0; | |
208 _Bool not_found = 1; | |
209 //for the cns calculation | |
210 const float cns_ppo2_ranges[60][2] = { {0.50, 0.00}, {0.60, 0.14}, {0.64, 0.15}, {0.66, 0.16}, {0.68, 0.17}, {0.70, 0.18}, | |
211 {0.74, 0.19}, {0.76, 0.20}, {0.78, 0.21}, {0.80, 0.22}, {0.82, 0.23}, {0.84, 0.24}, | |
212 {0.86, 0.25}, {0.88, 0.26}, {0.90, 0.28}, {0.92, 0.29}, {0.94, 0.30}, {0.96, 0.31}, | |
213 {0.98, 0.32}, {1.00, 0.33}, {1.02, 0.35}, {1.04, 0.36}, {1.06, 0.38}, {1.08, 0.40}, | |
214 {1.10, 0.42}, {1.12, 0.43}, {1.14, 0.43}, {1.16, 0.44}, {1.18, 0.46}, {1.20, 0.47}, | |
215 {1.22, 0.48}, {1.24, 0.51}, {1.26, 0.52}, {1.28, 0.54}, {1.30, 0.56}, {1.32, 0.57}, | |
216 {1.34, 0.60}, {1.36, 0.62}, {1.38, 0.63}, {1.40, 0.65}, {1.42, 0.68}, {1.44, 0.71}, | |
217 {1.46, 0.74}, {1.48, 0.78}, {1.50, 0.83}, {1.52, 0.93}, {1.54, 1.04}, {1.56, 1.19}, | |
218 {1.58, 1.47}, {1.60, 2.22}, {1.62, 5.00}, {1.65, 6.25}, {1.67, 7.69}, {1.70, 10.0}, | |
219 {1.72,12.50}, {1.74,20.00}, {1.77,25.00}, {1.79,31.25}, {1.80,50.00}, {1.82,100.0}}; | |
220 //find the correct cns range for the corresponding ppo2 | |
221 cns_no_range = 58; | |
222 while (cns_no_range && not_found) | |
223 { | |
224 if (pressure_oxygen_real > cns_ppo2_ranges[cns_no_range][0]) | |
225 { | |
226 cns_no_range++; | |
227 not_found = 0; | |
228 } | |
229 else | |
230 cns_no_range--; | |
231 } | |
232 | |
233 //calculate cns for the actual ppo2 for 1 second | |
234 *oxygen_cns += OXY_ONE_SIXTIETH_PART * cns_ppo2_ranges[cns_no_range][1]; | |
235 }*/ | |
236 | |
237 uint8_t calc_MOD(uint8_t gasId) | |
238 { | |
239 int16_t oxygen, maxppO2, result; | |
240 SSettings *pSettings; | |
241 | |
242 pSettings = settingsGetPointer(); | |
243 | |
244 oxygen = (int16_t)(pSettings->gas[gasId].oxygen_percentage); | |
245 | |
246 if(pSettings->gas[gasId].note.ub.deco > 0) | |
247 maxppO2 =(int16_t)(pSettings->ppO2_max_deco); | |
248 else | |
249 maxppO2 =(int16_t)(pSettings->ppO2_max_std); | |
250 | |
251 result = 10 * maxppO2; | |
252 result /= oxygen; | |
253 result -= 10; | |
254 | |
255 if(result < 0) | |
256 return 0; | |
257 | |
258 if(result > 255) | |
259 return 255; | |
260 | |
261 return result; | |
262 } | |
263 | |
264 uint8_t calc_MinOD(uint8_t gasId) | |
265 { | |
266 int16_t oxygen, minppO2, result; | |
267 SSettings *pSettings; | |
268 | |
269 pSettings = settingsGetPointer(); | |
270 | |
271 oxygen = (int16_t)(pSettings->gas[gasId].oxygen_percentage); | |
272 minppO2 =(int16_t)(pSettings->ppO2_min); | |
273 result = 10 * minppO2; | |
274 result += 9; | |
275 result /= oxygen; | |
276 result -= 10; | |
277 | |
278 if(result < 0) | |
279 return 0; | |
280 | |
281 if(result > 255) | |
282 return 255; | |
283 | |
284 return result; | |
285 } | |
286 /* | |
287 float calc_ppO2(float input_ambient_pressure_bar, SGas* pGas) | |
288 { | |
289 float percent_N2 = 0; | |
290 float percent_He = 0; | |
291 float percent_O2 = 0; | |
292 decom_get_inert_gases(input_ambient_pressure_bar, pGas, &percent_N2, &percent_He); | |
293 percent_O2 = 1 - percent_N2 - percent_He; | |
294 | |
295 return (input_ambient_pressure_bar - WATER_VAPOUR_PRESSURE) * percent_O2; | |
296 }*/ | |
297 | |
298 float get_ambiant_pressure_simulation(long dive_time_seconds, float surface_pressure_bar ) | |
299 { | |
300 static | |
301 long descent_time; | |
302 float depth_meter; | |
303 | |
304 descent_time = 60 * max_depth / descent_rate_meter_per_min; | |
305 | |
306 if(dive_time_seconds <= descent_time) | |
307 { | |
308 depth_meter = ((float)(dive_time_seconds * descent_rate_meter_per_min)) / 60; | |
309 return surface_pressure_bar + depth_meter / 10; | |
310 } | |
311 //else if(dive_time_seconds <= (descent_time + bottom_time * 60)) | |
312 return surface_pressure_bar + max_depth / 10; | |
313 | |
314 | |
315 | |
316 } | |
317 | |
318 void UpdateLifeDataTest(SDiveState * pDiveState) | |
319 { | |
320 static int last_second = -1; | |
321 int now = current_second(); | |
322 if(last_second == now) | |
323 return; | |
324 last_second = now; | |
325 | |
326 pDiveState->lifeData.dive_time_seconds += 1; | |
327 pDiveState->lifeData.pressure_ambient_bar = get_ambiant_pressure_simulation(pDiveState->lifeData.dive_time_seconds,pDiveState->lifeData.pressure_surface_bar); | |
328 | |
329 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; | |
330 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
331 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
332 decom_tissues_exposure(1, &pDiveState->lifeData); | |
333 pDiveState->lifeData.ppO2 = decom_calc_ppO2( pDiveState->lifeData.pressure_ambient_bar, &pDiveState->lifeData.actualGas); | |
334 decom_oxygen_calculate_cns(& pDiveState->lifeData.cns, pDiveState->lifeData.ppO2); | |
335 | |
336 vpm_crush(pDiveState); | |
337 } | |
338 | |
339 | |
340 _Bool vpm_crush(SDiveState* pDiveState) | |
341 { | |
342 int i = 0; | |
343 static float starting_ambient_pressure = 0; | |
344 static float ending_ambient_pressure = 0; | |
345 static float time_calc_begin = -1; | |
346 static float initial_helium_pressure[16]; | |
347 static float initial_nitrogen_pressure[16]; | |
348 ending_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
349 | |
350 if((pDiveState->lifeData.dive_time_seconds <= 4) || (starting_ambient_pressure >= ending_ambient_pressure)) | |
351 { | |
352 time_calc_begin = pDiveState->lifeData.dive_time_seconds; | |
353 starting_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
354 for( i = 0; i < 16; i++) | |
355 { | |
356 initial_helium_pressure[i] = pDiveState->lifeData.tissue_helium_bar[i] * 10; | |
357 initial_nitrogen_pressure[i] = pDiveState->lifeData.tissue_nitrogen_bar[i] * 10; | |
358 } | |
359 return false; | |
360 } | |
361 if(pDiveState->lifeData.dive_time_seconds - time_calc_begin >= 4) | |
362 { | |
363 if(ending_ambient_pressure > starting_ambient_pressure + 0.5f) | |
364 { | |
365 float rate = (ending_ambient_pressure - starting_ambient_pressure) * 60 / 4; | |
366 calc_crushing_pressure(&pDiveState->lifeData, &pDiveState->vpm, initial_helium_pressure, initial_nitrogen_pressure, starting_ambient_pressure, rate); | |
367 | |
368 time_calc_begin = pDiveState->lifeData.dive_time_seconds; | |
369 starting_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
370 for( i = 0; i < 16; i++) | |
371 { | |
372 initial_helium_pressure[i] = pDiveState->lifeData.tissue_helium_bar[i] * 10; | |
373 initial_nitrogen_pressure[i] = pDiveState->lifeData.tissue_nitrogen_bar[i] * 10; | |
374 } | |
375 | |
376 return true; | |
377 } | |
378 | |
379 } | |
380 return false; | |
381 }; | |
382 | |
383 | |
384 void createDiveSettings(void) | |
385 { | |
386 SSettings* pSettings = settingsGetPointer(); | |
387 | |
388 setActualGasFirst(&stateReal.lifeData); | |
389 | |
390 stateReal.diveSettings.compassHeading = pSettings->compassBearing; | |
391 stateReal.diveSettings.ascentRate_meterperminute = 10; | |
392 | |
393 stateReal.diveSettings.diveMode = pSettings->dive_mode; | |
394 stateReal.diveSettings.CCR_Mode = pSettings->CCR_Mode; | |
395 if(stateReal.diveSettings.diveMode == DIVEMODE_CCR) | |
396 stateReal.diveSettings.ccrOption = 1; | |
397 else | |
398 stateReal.diveSettings.ccrOption = 0; | |
399 memcpy(stateReal.diveSettings.gas, pSettings->gas,sizeof(pSettings->gas)); | |
400 memcpy(stateReal.diveSettings.setpoint, pSettings->setpoint,sizeof(pSettings->setpoint)); | |
401 stateReal.diveSettings.gf_high = pSettings->GF_high; | |
402 stateReal.diveSettings.gf_low = pSettings->GF_low; | |
403 stateReal.diveSettings.input_next_stop_increment_depth_bar = ((float)pSettings->stop_increment_depth_meter) / 10.0f; | |
404 stateReal.diveSettings.last_stop_depth_bar = ((float)pSettings->last_stop_depth_meter) / 10.0f; | |
405 stateReal.diveSettings.vpm_conservatism = pSettings->VPM_conservatism.ub.standard; | |
406 stateReal.diveSettings.deco_type.uw = pSettings->deco_type.uw; | |
407 stateReal.diveSettings.fallbackOption = pSettings->fallbackToFixedSetpoint; | |
408 stateReal.diveSettings.ppo2sensors_deactivated = pSettings->ppo2sensors_deactivated; | |
409 stateReal.diveSettings.future_TTS_minutes = pSettings->future_TTS; | |
410 | |
411 decom_CreateGasChangeList(&stateReal.diveSettings, &stateReal.lifeData); // decogaslist | |
412 stateReal.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
413 | |
414 /* for safety */ | |
415 stateReal.diveSettings.input_second_to_last_stop_depth_bar = stateReal.diveSettings.last_stop_depth_bar + stateReal.diveSettings.input_next_stop_increment_depth_bar; | |
416 /* and the proper calc */ | |
417 for(int i = 1; i <10; i++) | |
418 { | |
419 if(stateReal.diveSettings.input_next_stop_increment_depth_bar * i > stateReal.diveSettings.last_stop_depth_bar) | |
420 { | |
421 stateReal.diveSettings.input_second_to_last_stop_depth_bar = stateReal.diveSettings.input_next_stop_increment_depth_bar * i; | |
422 break; | |
423 } | |
424 } | |
425 } | |
426 | |
427 | |
428 void copyDiveSettingsToSim(void) | |
429 { | |
430 memcpy(&stateSim, &stateReal, sizeof(stateReal)); | |
431 } | |
432 | |
433 | |
434 void copyVpmRepetetiveDataToSim(void) | |
435 { | |
436 SDiveState * pSimData = stateSimGetPointerWrite(); | |
437 const SVpmRepetitiveData * pVpmData = stateVpmRepetitiveDataGetPointer(); | |
438 | |
439 if(pVpmData->is_data_from_RTE_CPU) | |
440 { | |
441 for(int i=0; i<16;i++) | |
442 { | |
443 pSimData->vpm.adjusted_critical_radius_he[i] = pVpmData->adjusted_critical_radius_he[i]; | |
444 pSimData->vpm.adjusted_critical_radius_n2[i] = pVpmData->adjusted_critical_radius_n2[i]; | |
445 | |
446 pSimData->vpm.adjusted_crushing_pressure_he[i] = pVpmData->adjusted_crushing_pressure_he[i]; | |
447 pSimData->vpm.adjusted_crushing_pressure_n2[i] = pVpmData->adjusted_crushing_pressure_n2[i]; | |
448 | |
449 pSimData->vpm.initial_allowable_gradient_he[i] = pVpmData->initial_allowable_gradient_he[i]; | |
450 pSimData->vpm.initial_allowable_gradient_n2[i] = pVpmData->initial_allowable_gradient_n2[i]; | |
451 | |
452 pSimData->vpm.max_actual_gradient[i] = pVpmData->max_actual_gradient[i]; | |
453 } | |
454 pSimData->vpm.repetitive_variables_not_valid = pVpmData->repetitive_variables_not_valid; | |
455 } | |
456 } | |
457 | |
458 | |
459 void updateSetpointStateUsed(void) | |
460 { | |
461 if(stateUsed->diveSettings.diveMode != DIVEMODE_CCR) | |
462 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
463 stateUsedWrite->lifeData.actualGas.setPoint_cbar = 0; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
464 stateUsedWrite->lifeData.ppO2 = decom_calc_ppO2(stateUsed->lifeData.pressure_ambient_bar, &stateUsed->lifeData.actualGas); |
38 | 465 } |
466 else | |
467 { | |
468 if(stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) | |
469 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
470 stateUsedWrite->lifeData.actualGas.setPoint_cbar = get_ppO2SensorWeightedResult_cbar(); |
38 | 471 } |
472 | |
473 if((stateUsed->lifeData.pressure_ambient_bar * 100) < stateUsed->lifeData.actualGas.setPoint_cbar) | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
474 stateUsedWrite->lifeData.ppO2 = stateUsed->lifeData.pressure_ambient_bar; |
38 | 475 else |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
476 stateUsedWrite->lifeData.ppO2 = ((float)stateUsed->lifeData.actualGas.setPoint_cbar) / 100; |
38 | 477 } |
478 } | |
479 | |
480 void setActualGasFirst(SLifeData *lifeData) | |
481 { | |
482 SSettings* pSettings = settingsGetPointer(); | |
483 uint8_t start = 0; | |
484 uint8_t gasId = 0; | |
485 uint8_t setpoint_cbar = 0; | |
486 | |
487 if(pSettings->dive_mode == DIVEMODE_CCR) | |
488 { | |
489 setpoint_cbar = pSettings->setpoint[1].setpoint_cbar; | |
490 start = NUM_OFFSET_DILUENT+1; | |
491 } | |
492 else | |
493 { | |
494 setpoint_cbar = 0; | |
495 start = 1; | |
496 } | |
497 | |
498 gasId = start; | |
499 for(int i=start;i<=NUM_GASES+start;i++) | |
500 { | |
501 if(pSettings->gas[i].note.ub.first) | |
502 { | |
503 gasId = i; | |
504 break; | |
505 } | |
506 } | |
507 setActualGas(lifeData, gasId, setpoint_cbar); | |
508 } | |
509 | |
510 void setActualGasAir(SLifeData *lifeData) | |
511 { | |
512 uint8_t nitrogen; | |
513 nitrogen = 79; | |
514 lifeData->actualGas.GasIdInSettings = 0; | |
515 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
516 lifeData->actualGas.helium_percentage =0; | |
517 lifeData->actualGas.setPoint_cbar = 0; | |
518 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
519 } | |
520 | |
521 | |
522 void setActualGas(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar) | |
523 { | |
524 SSettings* pSettings = settingsGetPointer(); | |
525 uint8_t nitrogen; | |
526 | |
527 nitrogen = 100; | |
528 nitrogen -= pSettings->gas[gasId].oxygen_percentage; | |
529 nitrogen -= pSettings->gas[gasId].helium_percentage; | |
530 | |
531 lifeData->actualGas.GasIdInSettings = gasId; | |
532 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
533 lifeData->actualGas.helium_percentage = pSettings->gas[gasId].helium_percentage; | |
534 lifeData->actualGas.setPoint_cbar = setpoint_cbar; | |
535 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
536 | |
537 if((pSettings->dive_mode == DIVEMODE_CCR) && (gasId > NUM_OFFSET_DILUENT)) | |
538 lifeData->lastDiluent_GasIdInSettings = gasId; | |
539 } | |
540 | |
541 | |
542 void setActualGas_DM(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar) | |
543 { | |
544 if(stateUsed->diveSettings.ccrOption && gasId < 6) | |
545 { | |
546 if(lifeData->actualGas.GasIdInSettings != gasId) | |
547 { | |
548 SSettings* pSettings = settingsGetPointer(); | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
549 stateUsedWrite->events.bailout = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
550 stateUsedWrite->events.info_bailoutO2 = pSettings->gas[gasId].oxygen_percentage; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
551 stateUsedWrite->events.info_bailoutHe = pSettings->gas[gasId].helium_percentage; |
38 | 552 } |
553 } | |
554 else | |
555 { | |
556 if(lifeData->actualGas.GasIdInSettings != gasId) | |
557 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
558 stateUsedWrite->events.gasChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
559 stateUsedWrite->events.info_GasChange = gasId; |
38 | 560 } |
561 if( lifeData->actualGas.setPoint_cbar != setpoint_cbar) | |
562 { | |
563 // setPoint_cbar = 255 -> change to sensor mode | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
564 stateUsedWrite->events.setpointChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
565 stateUsedWrite->events.info_SetpointChange = setpoint_cbar; |
38 | 566 } |
567 } | |
568 setActualGas(lifeData, gasId, setpoint_cbar); | |
569 } | |
570 | |
571 void setActualGas_ExtraGas(SLifeData *lifeData, uint8_t oxygen, uint8_t helium, uint8_t setpoint_cbar) | |
572 { | |
573 uint8_t nitrogen; | |
574 | |
575 nitrogen = 100; | |
576 nitrogen -= oxygen; | |
577 nitrogen -= helium; | |
578 | |
579 if((lifeData->actualGas.nitrogen_percentage != nitrogen) || (lifeData->actualGas.helium_percentage != helium)) | |
580 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
581 stateUsedWrite->events.manuelGasSet = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
582 stateUsedWrite->events.info_manuelGasSetHe = helium; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
583 stateUsedWrite->events.info_manuelGasSetO2 = oxygen; |
38 | 584 } |
585 if( lifeData->actualGas.setPoint_cbar != setpoint_cbar) | |
586 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
587 stateUsedWrite->events.setpointChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
588 stateUsedWrite->events.info_SetpointChange = setpoint_cbar; |
38 | 589 } |
590 lifeData->actualGas.GasIdInSettings = 0; | |
591 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
592 lifeData->actualGas.helium_percentage = helium; | |
593 lifeData->actualGas.setPoint_cbar = setpoint_cbar; | |
594 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
595 | |
596 } | |
597 | |
598 void setButtonResponsiveness(uint8_t *ButtonSensitivyList) | |
599 { | |
600 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
601 | |
602 for(int i=0; i<4; i++) | |
603 { | |
604 pDataOut->data.buttonResponsiveness[i] = settingsHelperButtonSens_translate_percentage_to_hwOS_values(ButtonSensitivyList[i]); | |
605 } | |
606 pDataOut->setButtonSensitivityNow = 1; | |
607 } | |
608 | |
609 | |
610 void setDate(RTC_DateTypeDef Sdate) | |
611 { | |
612 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
613 | |
614 pDataOut->data.newDate = Sdate; | |
615 pDataOut->setDateNow = 1; | |
616 } | |
617 | |
618 | |
619 void setTime(RTC_TimeTypeDef Stime) | |
620 { | |
621 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
622 | |
623 pDataOut->data.newTime = Stime; | |
624 pDataOut->setTimeNow = 1; | |
625 } | |
626 | |
627 | |
628 void setBatteryPercentage(uint8_t newChargePercentage) | |
629 { | |
630 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
631 | |
632 pDataOut->data.newBatteryGaugePercentageFloat = settingsGetPointer()->lastKnownBatteryPercentage; | |
633 pDataOut->setBatteryGaugeNow = 1; | |
634 } | |
635 | |
636 | |
637 void calibrateCompass(void) | |
638 { | |
639 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
640 pDataOut->calibrateCompassNow = 1; | |
641 } | |
642 | |
643 | |
644 void clearDeco(void) | |
645 { | |
646 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
647 pDataOut->clearDecoNow = 1; | |
648 | |
649 stateRealGetPointerWrite()->cnsHigh_at_the_end_of_dive = 0; | |
650 stateRealGetPointerWrite()->decoMissed_at_the_end_of_dive = 0; | |
651 } | |
652 | |
653 | |
654 int32_t helper_days_from_civil(int32_t y, uint32_t m, uint32_t d) | |
655 { | |
656 y += 2000; | |
657 y -= m <= 2; | |
658 int32_t era = (y >= 0 ? y : y-399) / 400; | |
659 uint32_t yoe = (uint32_t)(y - era * 400); // [0, 399] | |
660 uint32_t doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365] | |
661 uint32_t doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] | |
662 return era * 146097 + (int32_t)(doe) - 719468; | |
663 } | |
664 | |
665 | |
666 uint8_t helper_weekday_from_days(int32_t z) | |
667 { | |
668 return (uint8_t)(z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6); | |
669 } | |
670 | |
671 | |
672 void setWeekday(RTC_DateTypeDef *sDate) | |
673 { | |
674 uint8_t day; | |
675 // [0, 6] -> [Sun, Sat] | |
676 day = helper_weekday_from_days(helper_days_from_civil(sDate->Year, sDate->Month, sDate->Date)); | |
677 // [1, 7] -> [Mon, Sun] | |
678 if(day == 0) | |
679 day = 7; | |
680 sDate->WeekDay = day; | |
681 } | |
682 | |
683 | |
684 void translateDate(uint32_t datetmpreg, RTC_DateTypeDef *sDate) | |
685 { | |
686 datetmpreg = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK); | |
687 | |
688 /* Fill the structure fields with the read parameters */ | |
689 sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); | |
690 sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); | |
691 sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU)); | |
692 sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13); | |
693 | |
694 /* Convert the date structure parameters to Binary format */ | |
695 sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year); | |
696 sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month); | |
697 sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date); | |
698 } | |
699 | |
700 void translateTime(uint32_t tmpreg, RTC_TimeTypeDef *sTime) | |
701 { | |
702 tmpreg = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); | |
703 | |
704 /* Fill the structure fields with the read parameters */ | |
705 sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); | |
706 sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); | |
707 sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); | |
708 sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); | |
709 | |
710 /* Convert the time structure parameters to Binary format */ | |
711 sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); | |
712 sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); | |
713 sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); | |
714 sTime->SubSeconds = 0; | |
715 } | |
716 | |
717 | |
718 /* | |
719 void initDiveState(SDiveSettings * pDiveSettings, SVpm * pVpm) | |
720 { | |
721 SSettings* pSettings = settingsGetPointer(); | |
722 for(int i = 0; i< NUM_GASES; i++) | |
723 { | |
724 pDiveSettings->gas[i] = pSettings->gas[i]; | |
725 pDiveSettings->gas[NUM_OFFSET_DILUENT + i] = pSettings->gas[NUM_OFFSET_DILUENT + i]; | |
726 pDiveSettings->setpoint[i] = pSettings->setpoint[i]; | |
727 } | |
728 pDiveSettings->diveMode = pSettings->dive_mode; | |
729 | |
730 pDiveSettings->gf_high = pSettings->GF_high; | |
731 pDiveSettings->gf_low = pSettings->GF_low; | |
732 pDiveSettings->last_stop_depth_bar = ((float)pSettings->last_stop_depth_meter) / 10.0; | |
733 pDiveSettings->ascentRate_meterperminute = 10; | |
734 pDiveSettings->vpm_conservatism = 1; | |
735 | |
736 pDiveSettings->input_next_stop_increment_depth_bar = ((float)pSettings->stop_increment_depth_meter) / 10.0f; | |
737 | |
738 vpm_init(pVpm, pDiveSettings->vpm_conservatism, 0, 0); | |
739 } | |
740 */ | |
741 _Bool deco_zone_reached(void) | |
742 { | |
743 if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE) | |
744 return stateUsed->lifeData.pressure_ambient_bar <= stateUsed->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero; | |
745 else | |
746 return stateUsed->vpm.deco_zone_reached; | |
747 | |
748 } | |
749 | |
750 | |
270
2e58a4094770
feature, debug: make simulator write a logbook entry
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
751 void resetEvents(const SDiveState *pStateUsed) |
38 | 752 { |
270
2e58a4094770
feature, debug: make simulator write a logbook entry
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
753 memset((void *)&pStateUsed->events, 0, sizeof(SEvents)); |
38 | 754 } |
755 | |
756 | |
757 /* This is derived from crc32b but does table lookup. First the table | |
758 itself is calculated, if it has not yet been set up. | |
759 Not counting the table setup (which would probably be a separate | |
760 function), when compiled to Cyclops with GCC, this function executes in | |
761 7 + 13n instructions, where n is the number of bytes in the input | |
762 message. It should be doable in 4 + 9n instructions. In any case, two | |
763 of the 13 or 9 instrucions are load byte. | |
764 This is Figure 14-7 in the text. */ | |
765 | |
766 /* http://www.hackersdelight.org/ i guess ;-) *hw */ | |
767 | |
768 uint32_t crc32c_checksum(uint8_t* message, uint16_t length, uint8_t* message2, uint16_t length2) { | |
769 int i, j; | |
770 uint32_t byte, crc, mask; | |
771 static unsigned int table[256] = {0}; | |
772 | |
773 /* Set up the table, if necessary. */ | |
774 if (table[1] == 0) { | |
775 for (byte = 0; byte <= 255; byte++) { | |
776 crc = byte; | |
777 for (j = 7; j >= 0; j--) { // Do eight times. | |
778 mask = -(crc & 1); | |
779 crc = (crc >> 1) ^ (0xEDB88320 & mask); | |
780 } | |
781 table[byte] = crc; | |
782 } | |
783 } | |
784 | |
785 /* Through with table setup, now calculate the CRC. */ | |
786 i = 0; | |
787 crc = 0xFFFFFFFF; | |
788 while (length--) { | |
789 byte = message[i]; | |
790 crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; | |
791 i = i + 1; | |
792 } | |
793 if(length2) | |
794 { | |
795 i = 0; | |
796 while (length2--) { | |
797 byte = message2[i]; | |
798 crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; | |
799 i = i + 1; | |
800 } | |
801 } | |
802 return ~crc; | |
803 } | |
804 | |
805 | |
806 uint32_t CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words) | |
807 { | |
808 cm_t crc_model; | |
809 uint32_t word_to_do; | |
810 uint8_t byte_to_do; | |
811 int i; | |
812 | |
813 // Values for the STM32F generator. | |
814 | |
815 crc_model.cm_width = 32; // 32-bit CRC | |
816 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial | |
817 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's | |
818 crc_model.cm_refin = FALSE; // CRC calculated MSB first | |
819 crc_model.cm_refot = FALSE; // Final result is not bit-reversed | |
820 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this | |
821 | |
822 cm_ini(&crc_model); | |
823 | |
824 while (words--) | |
825 { | |
826 // The STM32F10x hardware does 32-bit words at a time!!! | |
827 if(words > (768000/4)) | |
828 word_to_do = *buffer2++; | |
829 else | |
830 word_to_do = *buffer1++; | |
831 | |
832 // Do all bytes in the 32-bit word. | |
833 | |
834 for (i = 0; i < sizeof(word_to_do); i++) | |
835 { | |
836 // We calculate a *byte* at a time. If the CRC is MSB first we | |
837 // do the next MS byte and vica-versa. | |
838 | |
839 if (crc_model.cm_refin == FALSE) | |
840 { | |
841 // MSB first. Do the next MS byte. | |
842 | |
843 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24); | |
844 word_to_do <<= 8; | |
845 } | |
846 else | |
847 { | |
848 // LSB first. Do the next LS byte. | |
849 | |
850 byte_to_do = (uint8_t) (word_to_do & 0x000000FF); | |
851 word_to_do >>= 8; | |
852 } | |
853 | |
854 cm_nxt(&crc_model, byte_to_do); | |
855 } | |
856 } | |
857 | |
858 // Return the final result. | |
859 | |
860 return (cm_crc(&crc_model)); | |
861 } | |
862 | |
863 | |
864 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words) | |
865 { | |
866 cm_t crc_model; | |
867 uint32_t word_to_do; | |
868 uint8_t byte_to_do; | |
869 int i; | |
870 | |
871 // Values for the STM32F generator. | |
872 | |
873 crc_model.cm_width = 32; // 32-bit CRC | |
874 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial | |
875 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's | |
876 crc_model.cm_refin = FALSE; // CRC calculated MSB first | |
877 crc_model.cm_refot = FALSE; // Final result is not bit-reversed | |
878 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this | |
879 | |
880 cm_ini(&crc_model); | |
881 | |
882 while (words--) | |
883 { | |
884 // The STM32F10x hardware does 32-bit words at a time!!! | |
885 | |
886 word_to_do = *buffer++; | |
887 | |
888 // Do all bytes in the 32-bit word. | |
889 | |
890 for (i = 0; i < sizeof(word_to_do); i++) | |
891 { | |
892 // We calculate a *byte* at a time. If the CRC is MSB first we | |
893 // do the next MS byte and vica-versa. | |
894 | |
895 if (crc_model.cm_refin == FALSE) | |
896 { | |
897 // MSB first. Do the next MS byte. | |
898 | |
899 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24); | |
900 word_to_do <<= 8; | |
901 } | |
902 else | |
903 { | |
904 // LSB first. Do the next LS byte. | |
905 | |
906 byte_to_do = (uint8_t) (word_to_do & 0x000000FF); | |
907 word_to_do >>= 8; | |
908 } | |
909 | |
910 cm_nxt(&crc_model, byte_to_do); | |
911 } | |
912 } | |
913 | |
914 // Return the final result. | |
915 | |
916 return (cm_crc(&crc_model)); | |
917 } | |
918 | |
919 | |
920 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData) | |
921 { | |
922 if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.04f)) | |
923 return true; | |
924 else | |
925 return false; | |
926 } |