Mercurial > public > ostc4
annotate Discovery/Src/data_central.c @ 563:d97f0e395058
Refine o2 sensor diagnostic functions:
Changed implementation to ignore connection errors if analog interface is selected. Because the HUD is using cBars, the code has been modified to be compatible with the Bar units provided by the analog interface. Behavior (outofbounds) should be identical to the previous implementation.
author | Ideenmodellierer |
---|---|
date | Sun, 15 Nov 2020 20:01:56 +0100 |
parents | d784f281833a |
children | 1b995079c045 |
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> | |
539
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
64 #include <math.h> |
38 | 65 #include "data_central.h" |
66 #include "calc_crush.h" | |
67 #include "decom.h" | |
68 #include "stm32f4xx_hal.h" | |
69 #include "settings.h" | |
70 #include "data_exchange_main.h" | |
71 #include "ostc.h" // for button adjust on hw testboard 1 | |
72 #include "tCCR.h" | |
73 #include "crcmodel.h" | |
74 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
149
diff
changeset
|
75 static SDiveState stateReal = { 0 }; |
38 | 76 SDiveState stateSim = { 0 }; |
77 SDiveState stateDeco = { 0 }; | |
78 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
79 static SDevice stateDevice = |
38 | 80 { |
81 /* max is 0x7FFFFFFF, min is 0x80000000 but also defined in stdint.h :-) */ | |
82 | |
83 /* count, use 0 */ | |
84 .batteryChargeCompleteCycles.value_int32 = 0, | |
85 .batteryChargeCycles.value_int32 = 0, | |
86 .diveCycles.value_int32 = 0, | |
87 .hoursOfOperation.value_int32 = 0, | |
88 | |
89 /* max values, use min. */ | |
90 .temperatureMaximum.value_int32 = INT32_MIN, | |
91 .depthMaximum.value_int32 = INT32_MIN, | |
92 | |
93 /* min values, use max. */ | |
94 .temperatureMinimum.value_int32 = INT32_MAX, | |
95 .voltageMinimum.value_int32 = INT32_MAX, | |
96 }; | |
97 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
98 static SVpmRepetitiveData stateVPM = |
38 | 99 { |
100 .repetitive_variables_not_valid = 1, | |
101 .is_data_from_RTE_CPU = 0, | |
102 }; | |
103 | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
104 const SDiveState *stateUsed = &stateReal; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
105 SDiveState *stateUsedWrite = &stateReal; |
38 | 106 |
539
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
107 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
108 #define COMPASS_FRACTION (4.0f) /* delay till value changes to new actual */ |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
109 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
110 static float compass_compensated = 0; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
111 |
38 | 112 void set_stateUsedToReal(void) |
113 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
114 stateUsed = stateUsedWrite = &stateReal; |
38 | 115 } |
116 | |
117 void set_stateUsedToSim(void) | |
118 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
119 stateUsed = stateUsedWrite = &stateSim; |
38 | 120 } |
121 | |
122 _Bool is_stateUsedSetToSim(void) | |
123 { | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
149
diff
changeset
|
124 return stateUsed == &stateSim; |
38 | 125 } |
126 | |
127 const SDiveState * stateRealGetPointer(void) | |
128 { | |
129 return &stateReal; | |
130 } | |
131 | |
132 SDiveState * stateRealGetPointerWrite(void) | |
133 { | |
134 return &stateReal; | |
135 } | |
136 | |
137 | |
138 const SDiveState * stateSimGetPointer(void) | |
139 { | |
140 return &stateSim; | |
141 } | |
142 | |
143 | |
144 SDiveState * stateSimGetPointerWrite(void) | |
145 { | |
146 return &stateSim; | |
147 } | |
148 | |
149 | |
150 const SDevice * stateDeviceGetPointer(void) | |
151 { | |
152 return &stateDevice; | |
153 } | |
154 | |
155 | |
156 SDevice * stateDeviceGetPointerWrite(void) | |
157 { | |
158 return &stateDevice; | |
159 } | |
160 | |
161 | |
162 const SVpmRepetitiveData * stateVpmRepetitiveDataGetPointer(void) | |
163 { | |
164 return &stateVPM; | |
165 } | |
166 | |
167 | |
168 SVpmRepetitiveData * stateVpmRepetitiveDataGetPointerWrite(void) | |
169 { | |
170 return &stateVPM; | |
171 } | |
172 | |
173 | |
174 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow) | |
175 { | |
176 if(ticksstart <= ticksnow) | |
177 return ticksnow - ticksstart; | |
178 else | |
179 return 0xFFFFFFFF - ticksstart + ticksnow; | |
180 } | |
181 | |
182 | |
183 uint8_t decoLock = DECO_CALC_undefined; | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
184 |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
185 static int descent_rate_meter_per_min = 20; |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
186 static int max_depth = 70; |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
187 static int bottom_time = 10; |
38 | 188 |
189 _Bool vpm_crush(SDiveState* pDiveState); | |
190 void setSimulationValues(int _ascent_rate_meter_per_min, int _descent_rate_meter_per_min, int _max_depth, int _bottom_time ) | |
191 { | |
192 descent_rate_meter_per_min = _descent_rate_meter_per_min; | |
193 max_depth = _max_depth; | |
194 bottom_time = _bottom_time; | |
195 } | |
196 | |
197 int current_second(void) { | |
198 | |
199 return HAL_GetTick() / 1000; | |
200 } | |
201 | |
202 #define OXY_ONE_SIXTIETH_PART 0.0166667f | |
203 | |
204 uint8_t calc_MOD(uint8_t gasId) | |
205 { | |
206 int16_t oxygen, maxppO2, result; | |
207 SSettings *pSettings; | |
208 | |
209 pSettings = settingsGetPointer(); | |
210 | |
211 oxygen = (int16_t)(pSettings->gas[gasId].oxygen_percentage); | |
212 | |
213 if(pSettings->gas[gasId].note.ub.deco > 0) | |
214 maxppO2 =(int16_t)(pSettings->ppO2_max_deco); | |
215 else | |
216 maxppO2 =(int16_t)(pSettings->ppO2_max_std); | |
217 | |
218 result = 10 * maxppO2; | |
219 result /= oxygen; | |
220 result -= 10; | |
221 | |
222 if(result < 0) | |
223 return 0; | |
224 | |
225 if(result > 255) | |
226 return 255; | |
227 | |
228 return result; | |
229 } | |
230 | |
231 float get_ambiant_pressure_simulation(long dive_time_seconds, float surface_pressure_bar ) | |
232 { | |
233 static | |
234 long descent_time; | |
235 float depth_meter; | |
236 | |
237 descent_time = 60 * max_depth / descent_rate_meter_per_min; | |
238 | |
239 if(dive_time_seconds <= descent_time) | |
240 { | |
241 depth_meter = ((float)(dive_time_seconds * descent_rate_meter_per_min)) / 60; | |
242 return surface_pressure_bar + depth_meter / 10; | |
243 } | |
244 //else if(dive_time_seconds <= (descent_time + bottom_time * 60)) | |
245 return surface_pressure_bar + max_depth / 10; | |
246 | |
247 | |
248 | |
249 } | |
250 | |
251 void UpdateLifeDataTest(SDiveState * pDiveState) | |
252 { | |
253 static int last_second = -1; | |
254 int now = current_second(); | |
255 if(last_second == now) | |
256 return; | |
257 last_second = now; | |
258 | |
259 pDiveState->lifeData.dive_time_seconds += 1; | |
260 pDiveState->lifeData.pressure_ambient_bar = get_ambiant_pressure_simulation(pDiveState->lifeData.dive_time_seconds,pDiveState->lifeData.pressure_surface_bar); | |
261 | |
262 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; | |
263 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
264 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
265 decom_tissues_exposure(1, &pDiveState->lifeData); | |
266 pDiveState->lifeData.ppO2 = decom_calc_ppO2( pDiveState->lifeData.pressure_ambient_bar, &pDiveState->lifeData.actualGas); | |
267 decom_oxygen_calculate_cns(& pDiveState->lifeData.cns, pDiveState->lifeData.ppO2); | |
268 | |
269 vpm_crush(pDiveState); | |
270 } | |
271 | |
272 | |
273 _Bool vpm_crush(SDiveState* pDiveState) | |
274 { | |
275 int i = 0; | |
276 static float starting_ambient_pressure = 0; | |
277 static float ending_ambient_pressure = 0; | |
278 static float time_calc_begin = -1; | |
279 static float initial_helium_pressure[16]; | |
280 static float initial_nitrogen_pressure[16]; | |
281 ending_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
282 | |
283 if((pDiveState->lifeData.dive_time_seconds <= 4) || (starting_ambient_pressure >= ending_ambient_pressure)) | |
284 { | |
285 time_calc_begin = pDiveState->lifeData.dive_time_seconds; | |
286 starting_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
287 for( i = 0; i < 16; i++) | |
288 { | |
289 initial_helium_pressure[i] = pDiveState->lifeData.tissue_helium_bar[i] * 10; | |
290 initial_nitrogen_pressure[i] = pDiveState->lifeData.tissue_nitrogen_bar[i] * 10; | |
291 } | |
292 return false; | |
293 } | |
294 if(pDiveState->lifeData.dive_time_seconds - time_calc_begin >= 4) | |
295 { | |
296 if(ending_ambient_pressure > starting_ambient_pressure + 0.5f) | |
297 { | |
298 float rate = (ending_ambient_pressure - starting_ambient_pressure) * 60 / 4; | |
299 calc_crushing_pressure(&pDiveState->lifeData, &pDiveState->vpm, initial_helium_pressure, initial_nitrogen_pressure, starting_ambient_pressure, rate); | |
300 | |
301 time_calc_begin = pDiveState->lifeData.dive_time_seconds; | |
302 starting_ambient_pressure = pDiveState->lifeData.pressure_ambient_bar * 10; | |
303 for( i = 0; i < 16; i++) | |
304 { | |
305 initial_helium_pressure[i] = pDiveState->lifeData.tissue_helium_bar[i] * 10; | |
306 initial_nitrogen_pressure[i] = pDiveState->lifeData.tissue_nitrogen_bar[i] * 10; | |
307 } | |
308 | |
309 return true; | |
310 } | |
311 | |
312 } | |
313 return false; | |
314 }; | |
315 | |
316 | |
317 void createDiveSettings(void) | |
318 { | |
319 SSettings* pSettings = settingsGetPointer(); | |
320 | |
321 setActualGasFirst(&stateReal.lifeData); | |
322 | |
323 stateReal.diveSettings.compassHeading = pSettings->compassBearing; | |
324 stateReal.diveSettings.ascentRate_meterperminute = 10; | |
325 | |
326 stateReal.diveSettings.diveMode = pSettings->dive_mode; | |
327 stateReal.diveSettings.CCR_Mode = pSettings->CCR_Mode; | |
328 if(stateReal.diveSettings.diveMode == DIVEMODE_CCR) | |
329 stateReal.diveSettings.ccrOption = 1; | |
330 else | |
331 stateReal.diveSettings.ccrOption = 0; | |
332 memcpy(stateReal.diveSettings.gas, pSettings->gas,sizeof(pSettings->gas)); | |
333 memcpy(stateReal.diveSettings.setpoint, pSettings->setpoint,sizeof(pSettings->setpoint)); | |
334 stateReal.diveSettings.gf_high = pSettings->GF_high; | |
335 stateReal.diveSettings.gf_low = pSettings->GF_low; | |
336 stateReal.diveSettings.input_next_stop_increment_depth_bar = ((float)pSettings->stop_increment_depth_meter) / 10.0f; | |
337 stateReal.diveSettings.last_stop_depth_bar = ((float)pSettings->last_stop_depth_meter) / 10.0f; | |
338 stateReal.diveSettings.vpm_conservatism = pSettings->VPM_conservatism.ub.standard; | |
339 stateReal.diveSettings.deco_type.uw = pSettings->deco_type.uw; | |
340 stateReal.diveSettings.fallbackOption = pSettings->fallbackToFixedSetpoint; | |
341 stateReal.diveSettings.ppo2sensors_deactivated = pSettings->ppo2sensors_deactivated; | |
342 stateReal.diveSettings.future_TTS_minutes = pSettings->future_TTS; | |
343 | |
344 decom_CreateGasChangeList(&stateReal.diveSettings, &stateReal.lifeData); // decogaslist | |
345 stateReal.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
346 | |
347 /* for safety */ | |
348 stateReal.diveSettings.input_second_to_last_stop_depth_bar = stateReal.diveSettings.last_stop_depth_bar + stateReal.diveSettings.input_next_stop_increment_depth_bar; | |
349 /* and the proper calc */ | |
350 for(int i = 1; i <10; i++) | |
351 { | |
352 if(stateReal.diveSettings.input_next_stop_increment_depth_bar * i > stateReal.diveSettings.last_stop_depth_bar) | |
353 { | |
354 stateReal.diveSettings.input_second_to_last_stop_depth_bar = stateReal.diveSettings.input_next_stop_increment_depth_bar * i; | |
355 break; | |
356 } | |
357 } | |
358 } | |
359 | |
360 | |
361 void copyDiveSettingsToSim(void) | |
362 { | |
363 memcpy(&stateSim, &stateReal, sizeof(stateReal)); | |
364 } | |
365 | |
366 | |
367 void copyVpmRepetetiveDataToSim(void) | |
368 { | |
369 SDiveState * pSimData = stateSimGetPointerWrite(); | |
370 const SVpmRepetitiveData * pVpmData = stateVpmRepetitiveDataGetPointer(); | |
371 | |
372 if(pVpmData->is_data_from_RTE_CPU) | |
373 { | |
374 for(int i=0; i<16;i++) | |
375 { | |
376 pSimData->vpm.adjusted_critical_radius_he[i] = pVpmData->adjusted_critical_radius_he[i]; | |
377 pSimData->vpm.adjusted_critical_radius_n2[i] = pVpmData->adjusted_critical_radius_n2[i]; | |
378 | |
379 pSimData->vpm.adjusted_crushing_pressure_he[i] = pVpmData->adjusted_crushing_pressure_he[i]; | |
380 pSimData->vpm.adjusted_crushing_pressure_n2[i] = pVpmData->adjusted_crushing_pressure_n2[i]; | |
381 | |
382 pSimData->vpm.initial_allowable_gradient_he[i] = pVpmData->initial_allowable_gradient_he[i]; | |
383 pSimData->vpm.initial_allowable_gradient_n2[i] = pVpmData->initial_allowable_gradient_n2[i]; | |
384 | |
385 pSimData->vpm.max_actual_gradient[i] = pVpmData->max_actual_gradient[i]; | |
386 } | |
387 pSimData->vpm.repetitive_variables_not_valid = pVpmData->repetitive_variables_not_valid; | |
388 } | |
389 } | |
390 | |
391 | |
392 void updateSetpointStateUsed(void) | |
393 { | |
394 if(stateUsed->diveSettings.diveMode != DIVEMODE_CCR) | |
395 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
396 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
|
397 stateUsedWrite->lifeData.ppO2 = decom_calc_ppO2(stateUsed->lifeData.pressure_ambient_bar, &stateUsed->lifeData.actualGas); |
38 | 398 } |
399 else | |
400 { | |
401 if(stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) | |
402 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
403 stateUsedWrite->lifeData.actualGas.setPoint_cbar = get_ppO2SensorWeightedResult_cbar(); |
38 | 404 } |
405 | |
406 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
|
407 stateUsedWrite->lifeData.ppO2 = stateUsed->lifeData.pressure_ambient_bar; |
38 | 408 else |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
409 stateUsedWrite->lifeData.ppO2 = ((float)stateUsed->lifeData.actualGas.setPoint_cbar) / 100; |
38 | 410 } |
411 } | |
412 | |
413 void setActualGasFirst(SLifeData *lifeData) | |
414 { | |
415 SSettings* pSettings = settingsGetPointer(); | |
416 uint8_t start = 0; | |
417 uint8_t gasId = 0; | |
418 uint8_t setpoint_cbar = 0; | |
419 | |
420 if(pSettings->dive_mode == DIVEMODE_CCR) | |
421 { | |
422 setpoint_cbar = pSettings->setpoint[1].setpoint_cbar; | |
423 start = NUM_OFFSET_DILUENT+1; | |
424 } | |
425 else | |
426 { | |
427 setpoint_cbar = 0; | |
428 start = 1; | |
429 } | |
430 | |
431 gasId = start; | |
432 for(int i=start;i<=NUM_GASES+start;i++) | |
433 { | |
434 if(pSettings->gas[i].note.ub.first) | |
435 { | |
436 gasId = i; | |
437 break; | |
438 } | |
439 } | |
440 setActualGas(lifeData, gasId, setpoint_cbar); | |
441 } | |
442 | |
443 void setActualGasAir(SLifeData *lifeData) | |
444 { | |
445 uint8_t nitrogen; | |
446 nitrogen = 79; | |
447 lifeData->actualGas.GasIdInSettings = 0; | |
448 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
449 lifeData->actualGas.helium_percentage =0; | |
450 lifeData->actualGas.setPoint_cbar = 0; | |
451 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
452 } | |
453 | |
454 | |
455 void setActualGas(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar) | |
456 { | |
457 SSettings* pSettings = settingsGetPointer(); | |
458 uint8_t nitrogen; | |
459 | |
460 nitrogen = 100; | |
461 nitrogen -= pSettings->gas[gasId].oxygen_percentage; | |
462 nitrogen -= pSettings->gas[gasId].helium_percentage; | |
463 | |
464 lifeData->actualGas.GasIdInSettings = gasId; | |
465 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
466 lifeData->actualGas.helium_percentage = pSettings->gas[gasId].helium_percentage; | |
467 lifeData->actualGas.setPoint_cbar = setpoint_cbar; | |
468 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
469 | |
470 if((pSettings->dive_mode == DIVEMODE_CCR) && (gasId > NUM_OFFSET_DILUENT)) | |
471 lifeData->lastDiluent_GasIdInSettings = gasId; | |
472 } | |
473 | |
474 | |
475 void setActualGas_DM(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar) | |
476 { | |
477 if(stateUsed->diveSettings.ccrOption && gasId < 6) | |
478 { | |
479 if(lifeData->actualGas.GasIdInSettings != gasId) | |
480 { | |
481 SSettings* pSettings = settingsGetPointer(); | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
482 stateUsedWrite->events.bailout = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
483 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
|
484 stateUsedWrite->events.info_bailoutHe = pSettings->gas[gasId].helium_percentage; |
38 | 485 } |
486 } | |
487 else | |
488 { | |
489 if(lifeData->actualGas.GasIdInSettings != gasId) | |
490 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
491 stateUsedWrite->events.gasChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
492 stateUsedWrite->events.info_GasChange = gasId; |
38 | 493 } |
494 if( lifeData->actualGas.setPoint_cbar != setpoint_cbar) | |
495 { | |
496 // 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
|
497 stateUsedWrite->events.setpointChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
498 stateUsedWrite->events.info_SetpointChange = setpoint_cbar; |
38 | 499 } |
500 } | |
501 setActualGas(lifeData, gasId, setpoint_cbar); | |
502 } | |
503 | |
504 void setActualGas_ExtraGas(SLifeData *lifeData, uint8_t oxygen, uint8_t helium, uint8_t setpoint_cbar) | |
505 { | |
506 uint8_t nitrogen; | |
507 | |
508 nitrogen = 100; | |
509 nitrogen -= oxygen; | |
510 nitrogen -= helium; | |
511 | |
512 if((lifeData->actualGas.nitrogen_percentage != nitrogen) || (lifeData->actualGas.helium_percentage != helium)) | |
513 { | |
281 | 514 stateUsedWrite->events.manualGasSet = 1; |
515 stateUsedWrite->events.info_manualGasSetHe = helium; | |
516 stateUsedWrite->events.info_manualGasSetO2 = oxygen; | |
38 | 517 } |
518 if( lifeData->actualGas.setPoint_cbar != setpoint_cbar) | |
519 { | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
520 stateUsedWrite->events.setpointChange = 1; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
521 stateUsedWrite->events.info_SetpointChange = setpoint_cbar; |
38 | 522 } |
523 lifeData->actualGas.GasIdInSettings = 0; | |
524 lifeData->actualGas.nitrogen_percentage = nitrogen; | |
525 lifeData->actualGas.helium_percentage = helium; | |
526 lifeData->actualGas.setPoint_cbar = setpoint_cbar; | |
527 lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; | |
528 | |
529 } | |
530 | |
531 void setButtonResponsiveness(uint8_t *ButtonSensitivyList) | |
532 { | |
533 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
534 | |
535 for(int i=0; i<4; i++) | |
536 { | |
537 pDataOut->data.buttonResponsiveness[i] = settingsHelperButtonSens_translate_percentage_to_hwOS_values(ButtonSensitivyList[i]); | |
538 } | |
539 pDataOut->setButtonSensitivityNow = 1; | |
540 } | |
541 | |
542 | |
543 void setDate(RTC_DateTypeDef Sdate) | |
544 { | |
545 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
546 | |
547 pDataOut->data.newDate = Sdate; | |
548 pDataOut->setDateNow = 1; | |
549 } | |
550 | |
551 | |
552 void setTime(RTC_TimeTypeDef Stime) | |
553 { | |
554 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
555 | |
556 pDataOut->data.newTime = Stime; | |
557 pDataOut->setTimeNow = 1; | |
558 } | |
559 | |
560 | |
561 void setBatteryPercentage(uint8_t newChargePercentage) | |
562 { | |
563 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
564 | |
565 pDataOut->data.newBatteryGaugePercentageFloat = settingsGetPointer()->lastKnownBatteryPercentage; | |
566 pDataOut->setBatteryGaugeNow = 1; | |
567 } | |
568 | |
569 | |
570 void calibrateCompass(void) | |
571 { | |
572 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
573 pDataOut->calibrateCompassNow = 1; | |
574 } | |
575 | |
576 | |
577 void clearDeco(void) | |
578 { | |
579 SDataReceiveFromMaster *pDataOut = dataOutGetPointer(); | |
580 pDataOut->clearDecoNow = 1; | |
581 | |
582 stateRealGetPointerWrite()->cnsHigh_at_the_end_of_dive = 0; | |
583 stateRealGetPointerWrite()->decoMissed_at_the_end_of_dive = 0; | |
584 } | |
585 | |
586 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
587 static int32_t helper_days_from_civil(int32_t y, uint32_t m, uint32_t d) |
38 | 588 { |
589 y += 2000; | |
590 y -= m <= 2; | |
591 int32_t era = (y >= 0 ? y : y-399) / 400; | |
592 uint32_t yoe = (uint32_t)(y - era * 400); // [0, 399] | |
593 uint32_t doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365] | |
594 uint32_t doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] | |
595 return era * 146097 + (int32_t)(doe) - 719468; | |
596 } | |
597 | |
598 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
281
diff
changeset
|
599 static uint8_t helper_weekday_from_days(int32_t z) |
38 | 600 { |
601 return (uint8_t)(z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6); | |
602 } | |
603 | |
604 | |
605 void setWeekday(RTC_DateTypeDef *sDate) | |
606 { | |
607 uint8_t day; | |
608 // [0, 6] -> [Sun, Sat] | |
609 day = helper_weekday_from_days(helper_days_from_civil(sDate->Year, sDate->Month, sDate->Date)); | |
610 // [1, 7] -> [Mon, Sun] | |
611 if(day == 0) | |
612 day = 7; | |
613 sDate->WeekDay = day; | |
614 } | |
615 | |
616 | |
617 void translateDate(uint32_t datetmpreg, RTC_DateTypeDef *sDate) | |
618 { | |
619 datetmpreg = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK); | |
620 | |
621 /* Fill the structure fields with the read parameters */ | |
622 sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); | |
623 sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); | |
624 sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU)); | |
625 sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13); | |
626 | |
627 /* Convert the date structure parameters to Binary format */ | |
628 sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year); | |
629 sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month); | |
630 sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date); | |
631 } | |
632 | |
633 void translateTime(uint32_t tmpreg, RTC_TimeTypeDef *sTime) | |
634 { | |
635 tmpreg = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); | |
636 | |
637 /* Fill the structure fields with the read parameters */ | |
638 sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); | |
639 sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); | |
640 sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); | |
641 sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); | |
642 | |
643 /* Convert the time structure parameters to Binary format */ | |
644 sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); | |
645 sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); | |
646 sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); | |
647 sTime->SubSeconds = 0; | |
648 } | |
649 | |
270
2e58a4094770
feature, debug: make simulator write a logbook entry
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
650 void resetEvents(const SDiveState *pStateUsed) |
38 | 651 { |
270
2e58a4094770
feature, debug: make simulator write a logbook entry
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
652 memset((void *)&pStateUsed->events, 0, sizeof(SEvents)); |
38 | 653 } |
654 | |
655 | |
656 uint32_t CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words) | |
657 { | |
658 cm_t crc_model; | |
659 uint32_t word_to_do; | |
660 uint8_t byte_to_do; | |
661 int i; | |
662 | |
663 // Values for the STM32F generator. | |
664 | |
665 crc_model.cm_width = 32; // 32-bit CRC | |
666 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial | |
667 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's | |
668 crc_model.cm_refin = FALSE; // CRC calculated MSB first | |
669 crc_model.cm_refot = FALSE; // Final result is not bit-reversed | |
670 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this | |
671 | |
672 cm_ini(&crc_model); | |
673 | |
674 while (words--) | |
675 { | |
676 // The STM32F10x hardware does 32-bit words at a time!!! | |
677 if(words > (768000/4)) | |
678 word_to_do = *buffer2++; | |
679 else | |
680 word_to_do = *buffer1++; | |
681 | |
682 // Do all bytes in the 32-bit word. | |
683 | |
684 for (i = 0; i < sizeof(word_to_do); i++) | |
685 { | |
686 // We calculate a *byte* at a time. If the CRC is MSB first we | |
687 // do the next MS byte and vica-versa. | |
688 | |
689 if (crc_model.cm_refin == FALSE) | |
690 { | |
691 // MSB first. Do the next MS byte. | |
692 | |
693 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24); | |
694 word_to_do <<= 8; | |
695 } | |
696 else | |
697 { | |
698 // LSB first. Do the next LS byte. | |
699 | |
700 byte_to_do = (uint8_t) (word_to_do & 0x000000FF); | |
701 word_to_do >>= 8; | |
702 } | |
703 | |
704 cm_nxt(&crc_model, byte_to_do); | |
705 } | |
706 } | |
707 | |
708 // Return the final result. | |
709 | |
710 return (cm_crc(&crc_model)); | |
711 } | |
712 | |
713 | |
714 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words) | |
715 { | |
716 cm_t crc_model; | |
717 uint32_t word_to_do; | |
718 uint8_t byte_to_do; | |
719 int i; | |
720 | |
721 // Values for the STM32F generator. | |
722 | |
723 crc_model.cm_width = 32; // 32-bit CRC | |
724 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial | |
725 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's | |
726 crc_model.cm_refin = FALSE; // CRC calculated MSB first | |
727 crc_model.cm_refot = FALSE; // Final result is not bit-reversed | |
728 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this | |
729 | |
730 cm_ini(&crc_model); | |
731 | |
732 while (words--) | |
733 { | |
734 // The STM32F10x hardware does 32-bit words at a time!!! | |
735 | |
736 word_to_do = *buffer++; | |
737 | |
738 // Do all bytes in the 32-bit word. | |
739 | |
740 for (i = 0; i < sizeof(word_to_do); i++) | |
741 { | |
742 // We calculate a *byte* at a time. If the CRC is MSB first we | |
743 // do the next MS byte and vica-versa. | |
744 | |
745 if (crc_model.cm_refin == FALSE) | |
746 { | |
747 // MSB first. Do the next MS byte. | |
748 | |
749 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24); | |
750 word_to_do <<= 8; | |
751 } | |
752 else | |
753 { | |
754 // LSB first. Do the next LS byte. | |
755 | |
756 byte_to_do = (uint8_t) (word_to_do & 0x000000FF); | |
757 word_to_do >>= 8; | |
758 } | |
759 | |
760 cm_nxt(&crc_model, byte_to_do); | |
761 } | |
762 } | |
763 | |
764 // Return the final result. | |
765 | |
766 return (cm_crc(&crc_model)); | |
767 } | |
768 | |
302
eba8d1eb5bef
bugfix, cleanup: keep both is_ambient_pressure_close_to_surface in sync
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
769 // This code is also in RTE. Keep it in sync when editing |
38 | 770 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData) |
771 { | |
310
95928ef3986f
Make dive mode detection more advanced
Jan Mulder <jlmulder@xs4all.nl>
parents:
302
diff
changeset
|
772 if (lifeData->pressure_ambient_bar > 1.16) |
95928ef3986f
Make dive mode detection more advanced
Jan Mulder <jlmulder@xs4all.nl>
parents:
302
diff
changeset
|
773 return false; |
95928ef3986f
Make dive mode detection more advanced
Jan Mulder <jlmulder@xs4all.nl>
parents:
302
diff
changeset
|
774 else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f)) |
38 | 775 return true; |
776 else | |
777 return false; | |
778 } | |
539
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
779 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
780 void compass_Inertia(float newHeading) |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
781 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
782 float newTarget = newHeading; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
783 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
784 if(settingsGetPointer()->compassInertia == 0) |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
785 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
786 compass_compensated = newHeading; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
787 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
788 else |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
789 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
790 if((compass_compensated > 270.0) && (newHeading < 90.0)) /* transition passing 0 clockwise */ |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
791 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
792 newTarget = newHeading + 360.0; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
793 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
794 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
795 if((compass_compensated < 90.0) && (newHeading > 270.0)) /* transition passing 0 counter clockwise */ |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
796 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
797 newTarget = newHeading - 360.0; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
798 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
799 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
800 compass_compensated = compass_compensated + ((newTarget - compass_compensated) / (COMPASS_FRACTION * (settingsGetPointer()->compassInertia))); |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
801 if(compass_compensated < 0.0) |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
802 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
803 compass_compensated += 360.0; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
804 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
805 if(compass_compensated >= 360.0) |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
806 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
807 compass_compensated -= 360.0; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
808 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
809 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
810 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
811 |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
812 float compass_getCompensated() |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
813 { |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
814 return compass_compensated; |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
815 } |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
310
diff
changeset
|
816 |