Mercurial > public > ostc4
annotate Small_CPU/Src/scheduler.c @ 173:05c770dc2911 max-depth
Bugfix: make max depth move with current depth (part 1)
The display in dive mode of the max depth was updated before the actual
depth, which looks very strange. The reason for this was conceptually
simple. The depth value was averaged over a set of depth samples, but
the current depth was only taken from the current sample. So, per
definition, on an initial descend, the current depth is always bigger
(deeper) than any average from previous shallower samples.
This part 1 commit introduces a new function that is used immediate
after reception of the new sample from the RTE. This function does the
trivial average of a set of samples. Notice that also the surface and
ambient mbar pressures are taken into account (which are used heavily
over the entire code). This is a consistency thing. We should base any
further calculation from the data presented in the UI, instead of
presenting A, and use A' for further calculations.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Mon, 11 Mar 2019 19:48:57 +0100 |
parents | c659fda83e44 |
children | 331882a89421 |
rev | line source |
---|---|
38 | 1 /** |
2 ****************************************************************************** | |
3 * @file scheduler.c | |
4 * @author heinrichs weikamp gmbh | |
5 * @date 27-March-2014 | |
6 * @version V0.0.6 | |
7 * @since 18-June-2015 | |
8 * @brief the main part except for base.c | |
9 * | |
10 @verbatim | |
11 ============================================================================== | |
12 ##### How to use ##### | |
13 ============================================================================== | |
14 @endverbatim | |
15 ****************************************************************************** | |
16 * @attention | |
17 * | |
18 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2> | |
19 * | |
20 ****************************************************************************** | |
21 */ | |
22 | |
23 | |
24 //#define DEBUGMODE | |
25 | |
26 /* Includes ------------------------------------------------------------------*/ | |
27 #include <string.h> | |
28 #include "baseCPU2.h" | |
29 #include "stm32f4xx_hal.h" | |
30 #include "i2c.h" | |
31 #include "scheduler.h" | |
32 #include "pressure.h" | |
33 #include "compass.h" | |
34 #include "batteryGasGauge.h" | |
35 #include "batteryCharger.h" | |
36 #include "spi.h" | |
37 #include "rtc.h" | |
38 #include "dma.h" | |
39 #include "adc.h" | |
40 #include "calc_crush.h" | |
41 #include "stm32f4xx_hal_rtc_ex.h" | |
42 #include "decom.h" | |
43 #include "wireless.h" | |
44 #include "tm_stm32f4_otp.h" | |
45 | |
46 | |
135 | 47 #define INVALID_PREASURE_VALUE (100.0F) |
48 | |
38 | 49 /* Private types -------------------------------------------------------------*/ |
50 const SGas Air = {79,0,0,0,0}; | |
51 | |
52 uint8_t testarrayindex = 0; | |
53 uint32_t testarray[256]; | |
54 uint32_t testarrayMain[256]; | |
55 | |
56 /* Exported variables --------------------------------------------------------*/ | |
57 SGlobal global; | |
58 SDevice DeviceDataFlash; | |
59 uint8_t deviceDataFlashValid = 0; | |
60 uint8_t deviceDataSubSeconds = 0; | |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
142
diff
changeset
|
61 uint8_t dohardspisync = 1; |
38 | 62 |
63 /* Private variables ---------------------------------------------------------*/ | |
64 /* can be lost while in sleep */ | |
65 uint8_t clearDecoNow = 0; | |
66 uint8_t setButtonsNow = 0; | |
67 | |
68 /* has to be in SRAM2 */ | |
69 uint8_t secondsCount = 0; | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
70 |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
71 SScheduleCtrl Scheduler; |
38 | 72 |
73 /* Private function prototypes -----------------------------------------------*/ | |
74 | |
75 _Bool vpm_crush2(void); | |
76 void scheduleUpdateDeviceData(void); | |
77 void initStructWithZeero(uint8_t* data, uint16_t length); | |
78 long get_nofly_time_minutes(void); | |
79 void copyActualGas(SGas gas); | |
80 void copyPressureData(void); | |
81 void copyCnsAndOtuData(void); | |
82 void copyTimeData(void); | |
83 void copyCompassData(void); | |
84 void copyCompassDataDuringCalibration(int16_t dx, int16_t dy, int16_t dz); | |
85 //void copyBatteryData(void); now in header | |
86 void copyAmbientLightData(void); | |
87 void copyTissueData(void); | |
88 void copyVpmCrushingData(void); | |
89 void copyDeviceData(void); | |
90 void changeAgeWirelessData(void); | |
91 void copyWirelessData(void); | |
92 void copyPICdata(void); | |
93 uint16_t schedule_update_timer_helper(int8_t thisSeconds); | |
94 | |
95 | |
96 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow); | |
97 | |
98 _Bool scheduleCheck_pressure_reached_dive_mode_level(void); | |
99 void scheduleSetDate(SDeviceLine *line); | |
100 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
101 extern void SPI_Evaluate_RX_Data(); |
38 | 102 /* Exported functions --------------------------------------------------------*/ |
103 | |
104 void initGlobals(void) | |
105 { | |
106 initStructWithZeero((uint8_t*) &global, sizeof(SGlobal)); | |
107 | |
108 global.dataSendToSlavePending = 0; | |
109 global.dataSendToSlaveIsValid = 1; | |
110 global.dataSendToSlaveIsNotValidCount = 0; | |
111 | |
112 global.mode = MODE_POWERUP; | |
113 global.repetitive_dive = 0; | |
114 global.conservatism = 0; | |
115 global.whichGas = 0; | |
116 global.aktualGas[0] = Air; | |
117 global.lifeData.actualGas = global.aktualGas[0]; | |
118 | |
172
c659fda83e44
Minor: Button defaults, release date adjusted, use SPI_SHOW_SYNC_STATS
heinrichsweikamp
parents:
155
diff
changeset
|
119 const uint8_t button_standard_sensitivity = 85; |
38 | 120 global.ButtonResponsiveness[0] = button_standard_sensitivity; |
121 global.ButtonResponsiveness[1] = button_standard_sensitivity; | |
122 global.ButtonResponsiveness[2] = button_standard_sensitivity; | |
123 global.ButtonResponsiveness[3] = button_standard_sensitivity; | |
124 | |
125 global.ButtonPICdata[0] = 0xFF; | |
126 global.ButtonPICdata[1] = 0xFF; | |
127 global.ButtonPICdata[2] = 0xFF; | |
128 global.ButtonPICdata[3] = 0xFF; | |
129 | |
130 global.I2C_SystemStatus = 0xFF; // 0x00 would be everything working | |
131 | |
135 | 132 global.lifeData.pressure_ambient_bar = INVALID_PREASURE_VALUE; |
133 global.lifeData.pressure_surface_bar = INVALID_PREASURE_VALUE; | |
38 | 134 decom_reset_with_1000mbar(&global.lifeData); |
135 | |
136 global.demo_mode = 0; | |
137 | |
138 for(int i = 0; i < MAX_SENSORS; i++) | |
139 { | |
140 global.sensorError[i] = HAL_OK; // HAL_OK = 0; | |
141 } | |
142 | |
143 global.dataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH;; | |
144 global.dataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW;; | |
145 global.dataSendToMaster.chargeStatus = 0; | |
146 | |
147 global.dataSendToMaster.power_on_reset = 1; | |
148 global.dataSendToMaster.header.checkCode[0] = 0xA1; | |
149 global.dataSendToMaster.header.checkCode[1] = 0xA2; | |
150 global.dataSendToMaster.header.checkCode[2] = 0xA3; | |
151 global.dataSendToMaster.header.checkCode[3] = 0xA4; | |
152 global.dataSendToMaster.footer.checkCode[3] = 0xE4; | |
153 global.dataSendToMaster.footer.checkCode[2] = 0xE3; | |
154 global.dataSendToMaster.footer.checkCode[1] = 0xE2; | |
155 global.dataSendToMaster.footer.checkCode[0] = 0xE1; | |
156 global.dataSendToMaster.sensorErrors = 0; | |
157 | |
158 global.sync_error_count = 0; | |
159 global.check_sync_not_running = 0; | |
160 | |
161 global.deviceDataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH; | |
162 global.deviceDataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW; | |
163 global.deviceDataSendToMaster.chargeStatus = 0; | |
164 | |
165 global.deviceDataSendToMaster.power_on_reset = 1; | |
166 global.deviceDataSendToMaster.header.checkCode[0] = 0xDF; | |
167 global.deviceDataSendToMaster.header.checkCode[1] = 0xDE; | |
168 global.deviceDataSendToMaster.header.checkCode[2] = 0xDD; | |
169 global.deviceDataSendToMaster.header.checkCode[3] = 0xDC; | |
170 global.deviceDataSendToMaster.footer.checkCode[3] = 0xE4; | |
171 global.deviceDataSendToMaster.footer.checkCode[2] = 0xE3; | |
172 global.deviceDataSendToMaster.footer.checkCode[1] = 0xE2; | |
173 global.deviceDataSendToMaster.footer.checkCode[0] = 0xE1; | |
174 | |
175 global.dataSendToSlave.getDeviceDataNow = 0; | |
176 | |
177 global.deviceData.batteryChargeCompleteCycles.value_int32 = 0; | |
178 global.deviceData.batteryChargeCycles.value_int32 = 0; | |
179 global.deviceData.depthMaximum.value_int32 = 0; | |
180 global.deviceData.diveCycles.value_int32 = 0; | |
181 global.deviceData.hoursOfOperation.value_int32 = 0; | |
182 global.deviceData.temperatureMaximum.value_int32 = INT32_MIN; | |
183 global.deviceData.temperatureMinimum.value_int32 = INT32_MAX; | |
184 global.deviceData.voltageMinimum.value_int32 = INT32_MAX; | |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
142
diff
changeset
|
185 |
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
142
diff
changeset
|
186 dohardspisync = 1; |
38 | 187 } |
188 | |
189 | |
190 void scheduleSpecial_Evaluate_DataSendToSlave(void) | |
191 { | |
104 | 192 //TEMPORARY fix for compass calibration. |
193 //TODO: Fix I2C timeout for complete solving problem. | |
194 if(global.mode==MODE_CALIB){ | |
195 return; | |
196 } | |
90 | 197 |
88 | 198 global.dataSendToSlavePending = 0; |
199 if(!global.dataSendToSlaveIsValid) return; | |
38 | 200 |
201 global.dataSendToMaster.confirmRequest.uw = 0; | |
202 | |
203 if(TM_OTP_Read(0,0) == 0xFF) | |
204 { | |
205 if(global.dataSendToSlave.revisionHardware == (global.dataSendToSlave.revisionCRCx0x7A ^ 0x7A)) | |
206 TM_OTP_Write(0,0,global.dataSendToSlave.revisionHardware); | |
207 } | |
208 | |
209 if(global.dataSendToSlave.setAccidentFlag) | |
210 { | |
211 global.dataSendToMaster.confirmRequest.ub.accident = 1; | |
212 global.deviceData.diveAccident.value_int32 = global.dataSendToSlave.setAccidentFlag; | |
213 scheduleSetDate(&global.deviceData.diveAccident); | |
214 global.accidentFlag |= global.dataSendToSlave.setAccidentFlag; | |
215 if(global.accidentFlag == ACCIDENT_CNS) // LVL1 | |
216 global.accidentRemainingSeconds = 2*60*60; | |
217 else | |
218 global.accidentRemainingSeconds = 24*60*60; | |
219 } | |
220 | |
221 if(global.dataSendToSlave.setTimeNow) | |
222 { | |
223 global.dataSendToMaster.confirmRequest.ub.time = 1; | |
224 RTC_SetTime(global.dataSendToSlave.data.newTime); | |
225 schedule_update_timer_helper(0); | |
226 } | |
227 | |
228 if(global.dataSendToSlave.setDateNow) | |
229 { | |
230 global.dataSendToMaster.confirmRequest.ub.date = 1; | |
231 RTC_SetDate(global.dataSendToSlave.data.newDate); | |
232 schedule_update_timer_helper(0); | |
233 } | |
234 | |
235 if(global.dataSendToSlave.calibrateCompassNow) | |
236 { | |
237 global.dataSendToMaster.confirmRequest.ub.compass = 1; | |
238 global.mode = MODE_CALIB; | |
239 } | |
240 | |
241 if(global.dataSendToSlave.clearDecoNow) | |
242 { | |
243 global.dataSendToMaster.confirmRequest.ub.clearDeco = 1; | |
244 clearDecoNow = 1; | |
245 } | |
246 | |
247 if(global.dataSendToSlave.setButtonSensitivityNow) | |
248 { | |
249 global.dataSendToMaster.confirmRequest.ub.button = 1; | |
250 global.ButtonResponsiveness[0] = global.dataSendToSlave.data.buttonResponsiveness[0]; | |
251 global.ButtonResponsiveness[1] = global.dataSendToSlave.data.buttonResponsiveness[1]; | |
252 global.ButtonResponsiveness[2] = global.dataSendToSlave.data.buttonResponsiveness[2]; | |
253 global.ButtonResponsiveness[3] = global.dataSendToSlave.data.buttonResponsiveness[3]; | |
254 setButtonsNow = 1; | |
255 } | |
256 | |
257 if(global.dataSendToSlave.setBatteryGaugeNow) | |
258 { | |
104 | 259 if(global.mode!=MODE_CALIB){ |
38 | 260 global.dataSendToMaster.confirmRequest.ub.batterygauge = 1; |
261 battery_gas_gauge_set(global.dataSendToSlave.data.newBatteryGaugePercentageFloat); | |
104 | 262 } |
38 | 263 } |
264 | |
265 if((global.mode == MODE_SURFACE) && (global.dataSendToSlave.mode == MODE_SHUTDOWN)) | |
266 { | |
267 global.mode = MODE_SHUTDOWN; | |
268 } | |
269 | |
270 if(global.mode == MODE_DIVE) | |
271 { | |
272 copyActualGas(global.dataSendToSlave.data.actualGas); | |
273 } | |
274 else | |
275 { | |
276 copyActualGas(Air); | |
277 global.settings.divetimeToCreateLogbook = global.dataSendToSlave.data.divetimeToCreateLogbook; | |
278 global.settings.timeoutDiveReachedZeroDepth = global.dataSendToSlave.data.timeoutDiveReachedZeroDepth; | |
279 } | |
280 | |
281 /* for simulation / testing */ | |
282 global.ceiling_from_main_CPU_mbar = global.dataSendToSlave.data.ambient_pressure_mbar_ceiling; | |
283 | |
88 | 284 /* for device data updates */ |
285 deviceDataFlashValid = 0; | |
286 memcpy(&DeviceDataFlash, &global.dataSendToSlave.data.DeviceData, sizeof(SDevice)); | |
287 deviceDataFlashValid = 1; | |
89 | 288 |
289 | |
104 | 290 //TODO: Temporary placed here. Duration ~210 ms. |
291 if (global.I2C_SystemStatus != HAL_OK) { | |
292 MX_I2C1_TestAndClear(); | |
293 MX_I2C1_Init(); | |
294 // init_pressure(); | |
295 // compass_init(0, 7); | |
296 // accelerator_init(); | |
297 } | |
38 | 298 } |
299 | |
300 | |
301 /** | |
302 ****************************************************************************** | |
303 * @brief schedule_time_compare_helper. | |
304 * @author heinrichs weikamp gmbh | |
305 * @version V0.0.1 | |
306 * @date 20-Oct-2016 | |
307 ****************************************************************************** | |
308 */ | |
309 | |
310 uint8_t RtcBugFixChsw(uint8_t inStupidTime) | |
311 { | |
312 uint8_t multiplesOf16 = 0; | |
313 | |
314 multiplesOf16 = inStupidTime / 16; | |
315 | |
316 inStupidTime -= multiplesOf16 * 16; | |
317 | |
318 return (10 * multiplesOf16) + inStupidTime; | |
319 } | |
320 | |
321 | |
322 uint32_t minCounterDebug = 0; | |
323 | |
324 uint32_t schedule_time_compare_helper(RTC_TimeTypeDef timeNow, RTC_DateTypeDef dateNow, RTC_TimeTypeDef timeLast, RTC_DateTypeDef dateLast) | |
325 { | |
326 uint32_t nowInSeconds; | |
327 uint32_t lastInSeconds; | |
328 uint32_t resultDiff; | |
329 | |
330 if(timeNow.Minutes != timeLast.Minutes) | |
331 minCounterDebug++; | |
332 | |
333 nowInSeconds = (uint32_t)RtcBugFixChsw(timeNow.Hours) * 3600; | |
334 nowInSeconds += (uint32_t)RtcBugFixChsw(timeNow.Minutes) * 60; | |
335 nowInSeconds += (uint32_t)RtcBugFixChsw(timeNow.Seconds); | |
336 | |
337 lastInSeconds = (uint32_t)RtcBugFixChsw(timeLast.Hours) * 3600; | |
338 lastInSeconds += (uint32_t)RtcBugFixChsw(timeLast.Minutes) * 60; | |
339 lastInSeconds += (uint32_t)RtcBugFixChsw(timeLast.Seconds); | |
340 | |
341 /* | |
342 nowInSeconds = (uint32_t)timeNow.Hours * 3600; | |
343 nowInSeconds += (uint32_t)timeNow.Minutes * 60; | |
344 nowInSeconds += (uint32_t)timeNow.Seconds; | |
345 | |
346 lastInSeconds = (uint32_t)timeLast.Hours * 3600; | |
347 lastInSeconds += (uint32_t)timeLast.Minutes * 60; | |
348 lastInSeconds += (uint32_t)timeLast.Seconds; | |
349 */ | |
350 | |
351 if(dateNow.Date != dateLast.Date) | |
352 { | |
353 resultDiff = 86400 + nowInSeconds - lastInSeconds; | |
354 } | |
355 else | |
356 { | |
357 resultDiff = nowInSeconds - lastInSeconds; | |
358 } | |
359 return resultDiff; | |
360 } | |
361 | |
362 | |
363 | |
364 /** | |
365 ****************************************************************************** | |
366 * @brief schedule_update_timer_helper. | |
367 * @author heinrichs weikamp gmbh | |
368 * @version V0.0.1 | |
369 * @date 20-Oct-2016 | |
370 * @brief use 0 for init | |
371 use -1 for RTC controlled | |
372 use >= 1 for manual control | |
373 ****************************************************************************** | |
374 */ | |
375 extern RTC_HandleTypeDef RTCHandle; | |
376 | |
377 uint16_t schedule_update_timer_helper(int8_t thisSeconds) | |
378 { | |
379 static RTC_TimeTypeDef sTimeLast; | |
380 static RTC_DateTypeDef sDateLast; | |
381 RTC_TimeTypeDef sTimeNow; | |
382 RTC_DateTypeDef sDateNow; | |
383 uint32_t secondsPast; | |
384 uint32_t tempNewValue = 0; | |
385 | |
386 HAL_RTC_GetTime(&RTCHandle, &sTimeNow, RTC_FORMAT_BCD); | |
387 HAL_RTC_GetDate(&RTCHandle, &sDateNow, RTC_FORMAT_BCD); | |
388 | |
389 if(thisSeconds != 0) // otherwise just store sTimeLast, sDateLast and return 0 | |
390 { | |
391 secondsPast = schedule_time_compare_helper(sTimeNow, sDateNow, sTimeLast, sDateLast); | |
392 | |
393 if(thisSeconds > 0) // use this value instead, good for pre-loading sTimeLast and sDateLast | |
394 { | |
395 secondsPast = thisSeconds; | |
396 } | |
397 | |
398 if(global.seconds_since_last_dive) | |
399 { | |
400 if(secondsPast >= 777900) | |
401 { | |
402 global.seconds_since_last_dive = 0; | |
403 } | |
404 else | |
405 { | |
406 tempNewValue = ((uint32_t)global.seconds_since_last_dive) + secondsPast; | |
407 if(tempNewValue > 777900) // a bit more than nine days [seconds] | |
408 global.seconds_since_last_dive = 0; | |
409 else | |
410 global.seconds_since_last_dive = (long)tempNewValue; | |
411 } | |
412 } | |
413 } | |
414 | |
415 sTimeLast = sTimeNow; | |
416 sDateLast = sDateNow; | |
417 | |
418 return tempNewValue; | |
419 } | |
420 | |
421 | |
422 | |
423 | |
424 /** | |
425 ****************************************************************************** | |
426 * @brief schedule_check_resync. | |
427 * @author heinrichs weikamp gmbh | |
428 * @version V0.0.2 | |
429 * @date 18-June-2015 | |
430 ****************************************************************************** | |
431 */ | |
135 | 432 |
38 | 433 void schedule_check_resync(void) |
434 { | |
155
4fd8bbc7d841
Do hard sync after communication timeout > 1 second
Ideenmodellierer
parents:
148
diff
changeset
|
435 /* counter is incremented in cyclic 100ms loop and reset to 0 if the transmission complete callback is called */ |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
142
diff
changeset
|
436 if((global.check_sync_not_running >= 3)) |
38 | 437 { |
89 | 438 // global.dataSendToSlaveIsNotValidCount = 0; |
135 | 439 global.check_sync_not_running = 0; |
440 global.sync_error_count++; | |
441 | |
442 /* Try to start communication again. If exchange is stuck during execution for some reason the TX will be aborted by the | |
443 * function error handler | |
444 */ | |
445 SPI_Start_single_TxRx_with_Master(); | |
38 | 446 } |
155
4fd8bbc7d841
Do hard sync after communication timeout > 1 second
Ideenmodellierer
parents:
148
diff
changeset
|
447 if((global.check_sync_not_running == 10)) /* connection lost for about a second. Could be debugging or Firmware update */ |
4fd8bbc7d841
Do hard sync after communication timeout > 1 second
Ideenmodellierer
parents:
148
diff
changeset
|
448 { |
4fd8bbc7d841
Do hard sync after communication timeout > 1 second
Ideenmodellierer
parents:
148
diff
changeset
|
449 dohardspisync = 1; |
4fd8bbc7d841
Do hard sync after communication timeout > 1 second
Ideenmodellierer
parents:
148
diff
changeset
|
450 } |
38 | 451 } |
452 | |
453 | |
454 /** | |
455 ****************************************************************************** | |
456 * @brief scheduleDiveMode. / Dive Mode: Main Loop | |
457 * @author Peter Ryser | |
458 * @version V0.0.1 | |
459 * @date 22-April-2014 | |
460 ****************************************************************************** | |
461 */ | |
462 void scheduleDiveMode(void) | |
463 { | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
464 // uint32_t tickstart = 0; |
38 | 465 uint32_t ticksdiff = 0; |
466 uint32_t lasttick = 0; | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
467 |
38 | 468 uint32_t turbo_seconds = 0; |
469 uint8_t counterAscentRate = 0; | |
470 float lastPressure_bar = 0.0f; | |
471 global.dataSendToMaster.mode = MODE_DIVE; | |
472 global.deviceDataSendToMaster.mode = MODE_DIVE; | |
473 //uint16_t counterSecondsShallowDepth = 0; | |
474 uint8_t counter_exit = 0; | |
475 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
476 Scheduler.tickstart = HAL_GetTick() - 1000; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
477 Scheduler.counterSPIdata100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
478 Scheduler.counterCompass100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
479 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
480 Scheduler.counterAmbientLight100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
481 Scheduler.counterWireless1msec = 0; |
38 | 482 |
483 global.deviceData.diveCycles.value_int32++; | |
484 scheduleSetDate(&global.deviceData.diveCycles); | |
485 global.lifeData.counterSecondsShallowDepth = 0; | |
486 | |
487 while(global.mode == MODE_DIVE) | |
488 { | |
489 schedule_check_resync(); | |
490 lasttick = HAL_GetTick(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
491 ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick); |
38 | 492 |
493 | |
494 //Evaluate wireless data every ms, if present | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
495 if(ticksdiff > Scheduler.counterWireless1msec) |
38 | 496 { |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
497 Scheduler.counterWireless1msec++; |
38 | 498 changeAgeWirelessData(); |
499 global.wirelessReceived = wireless_evaluate(global.wirelessdata,MAX_WIRELESS_BYTES, &global.wirelessConfidenceStatus); | |
500 if((global.wirelessReceived > 0) && !wireless_evaluate_crc_error(global.wirelessdata,global.wirelessReceived)) | |
501 { | |
502 copyWirelessData(); | |
503 } | |
504 } | |
505 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
506 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
507 { |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
508 SPI_Evaluate_RX_Data(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
509 Scheduler.counterSPIdata100msec++; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
510 } |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
511 |
38 | 512 //Evaluate pressure at 20 ms, 120 ms, 220 ms,.... |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
513 if(ticksdiff >= Scheduler.counterPressure100msec * 100 + 20) |
38 | 514 { |
515 global.check_sync_not_running++; | |
135 | 516 pressure_update(); |
517 scheduleUpdateDeviceData(); | |
38 | 518 if(global.demo_mode) |
519 { | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
520 turbo_seconds = demo_modify_temperature_and_pressure(global.lifeData.dive_time_seconds, Scheduler.counterPressure100msec, global.ceiling_from_main_CPU_mbar); |
38 | 521 if(turbo_seconds) |
522 { | |
523 global.lifeData.dive_time_seconds += turbo_seconds; | |
524 decom_tissues_exposure((int)(turbo_seconds), &global.lifeData); | |
525 copyTissueData(); | |
526 } | |
527 if((global.lifeData.counterSecondsShallowDepth > 1) && (global.lifeData.counterSecondsShallowDepth < (global.settings.timeoutDiveReachedZeroDepth - 10))) | |
528 global.lifeData.counterSecondsShallowDepth = (global.settings.timeoutDiveReachedZeroDepth - 10); | |
529 } | |
530 | |
531 | |
532 //Calc ascentrate every two second (20 * 100 ms) | |
533 counterAscentRate++; | |
534 if(counterAscentRate == 20) | |
535 { | |
536 global.lifeData.pressure_ambient_bar = get_pressure_mbar() / 1000.0f; | |
537 if(lastPressure_bar >= 0) | |
538 { | |
539 //2 seconds * 30 == 1 minute, bar * 10 = meter | |
540 global.lifeData.ascent_rate_meter_per_min = (lastPressure_bar - global.lifeData.pressure_ambient_bar) * 30 * 10; | |
541 } | |
542 lastPressure_bar = global.lifeData.pressure_ambient_bar; | |
543 counterAscentRate = 0; | |
544 } | |
135 | 545 copyPressureData(); |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
546 Scheduler.counterPressure100msec++; |
38 | 547 } |
548 //evaluate compass data at 50 ms, 150 ms, 250 ms,.... | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
549 if(ticksdiff >= Scheduler.counterCompass100msec * 100 + 50) |
135 | 550 { |
551 compass_read(); | |
552 acceleration_read(); | |
553 compass_calc(); | |
554 copyCompassData(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
555 Scheduler.counterCompass100msec++; |
135 | 556 } |
38 | 557 |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
558 if(ticksdiff >= Scheduler.counterAmbientLight100msec * 100 + 70) |
38 | 559 { |
560 adc_ambient_light_sensor_get_data(); | |
561 copyAmbientLightData(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
562 Scheduler.counterAmbientLight100msec++; |
38 | 563 } |
564 | |
565 //Evaluate tissues, toxic data, vpm, etc. once a second | |
566 if(ticksdiff >= 1000) | |
567 { | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
568 /* reset counter */ |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
569 Scheduler.tickstart = HAL_GetTick(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
570 |
38 | 571 if(global.dataSendToSlave.diveModeInfo != DIVEMODE_Apnea) |
572 { | |
573 scheduleUpdateLifeData(0); // includes tissues | |
574 global.lifeData.dive_time_seconds++; // there is dive_time_seconds_without_surface_time too | |
575 global.lifeData.ppO2 = decom_calc_ppO2(global.lifeData.pressure_ambient_bar, &global.lifeData.actualGas); | |
576 decom_oxygen_calculate_cns(&global.lifeData.cns,global.lifeData.ppO2); | |
577 decom_oxygen_calculate_otu(&global.lifeData.otu,global.lifeData.ppO2); | |
88 | 578 battery_gas_gauge_get_data(); |
38 | 579 |
580 | |
581 /** counter_exit allows safe exit via button for testing | |
582 * and demo_mode is exited too if aplicable. | |
583 */ | |
584 if(global.dataSendToMaster.mode == MODE_ENDDIVE) | |
585 { | |
586 counter_exit++; | |
587 if(counter_exit >= 2) | |
588 { | |
589 global.mode = MODE_SURFACE; | |
590 global.demo_mode = 0; | |
591 } | |
592 } | |
593 | |
594 if(is_ambient_pressure_close_to_surface(&global.lifeData)) | |
595 { | |
596 global.lifeData.counterSecondsShallowDepth++; | |
597 if((global.lifeData.counterSecondsShallowDepth >= global.settings.timeoutDiveReachedZeroDepth) || ((global.lifeData.dive_time_seconds < 60) && (global.demo_mode == 0)) || (global.dataSendToSlave.setEndDive)) | |
598 { | |
599 global.seconds_since_last_dive = 1; // start counter | |
600 schedule_update_timer_helper(0); // zum starten :-) | |
601 global.dataSendToMaster.mode = MODE_ENDDIVE; | |
602 global.deviceDataSendToMaster.mode = MODE_ENDDIVE; | |
603 } | |
604 } | |
605 else | |
606 { | |
607 global.lifeData.counterSecondsShallowDepth = 0; | |
608 global.lifeData.dive_time_seconds_without_surface_time++; | |
609 } | |
610 vpm_crush2(); | |
611 } | |
612 else // DIVEMODE_Apnea | |
613 { | |
614 global.lifeData.dive_time_seconds++; | |
615 | |
616 // exit dive mode | |
617 if(global.dataSendToMaster.mode == MODE_ENDDIVE) | |
618 { | |
619 counter_exit++; | |
620 if(counter_exit >= 2) | |
621 { | |
622 scheduleUpdateLifeData(-1); // 'restart' tissue calculations without calculating time during apnea mode | |
623 global.lifeData.dive_time_seconds = 0; // use backup noflytime and desaturation time | |
624 global.mode = MODE_SURFACE; | |
625 global.demo_mode = 0; | |
626 } | |
627 } | |
628 | |
629 // surface break | |
630 if(is_ambient_pressure_close_to_surface(&global.lifeData)) | |
631 { | |
632 global.lifeData.counterSecondsShallowDepth++; | |
633 if(global.lifeData.counterSecondsShallowDepth > 3) // time for main cpu to copy to apnea_last_dive_time_seconds | |
634 { | |
635 global.lifeData.dive_time_seconds = 0; // this apnea dive ends here | |
636 } | |
637 if((global.lifeData.counterSecondsShallowDepth >= global.settings.timeoutDiveReachedZeroDepth) || (global.dataSendToSlave.setEndDive)) | |
638 { | |
639 global.dataSendToMaster.mode = MODE_ENDDIVE; | |
640 global.deviceDataSendToMaster.mode = MODE_ENDDIVE; | |
641 } | |
642 } | |
643 else | |
644 { | |
645 global.lifeData.counterSecondsShallowDepth = 0; | |
646 global.lifeData.dive_time_seconds_without_surface_time++; | |
647 } | |
648 } // standard dive or DIVEMODE_Apnea | |
649 | |
88 | 650 copyVpmCrushingData(); |
651 copyTimeData(); | |
652 copyCnsAndOtuData(); | |
653 copyBatteryData(); | |
38 | 654 |
88 | 655 // new hw 170523 |
656 if(global.I2C_SystemStatus != HAL_OK) | |
657 { | |
658 MX_I2C1_TestAndClear(); | |
659 MX_I2C1_Init(); | |
660 if(!is_init_pressure_done()) | |
661 { | |
662 init_pressure(); | |
663 } | |
664 } | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
665 Scheduler.counterSPIdata100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
666 Scheduler.counterCompass100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
667 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
668 Scheduler.counterAmbientLight100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
669 Scheduler.counterWireless1msec = 0; |
38 | 670 } |
671 } | |
672 } | |
673 | |
674 | |
675 /** | |
676 ****************************************************************************** | |
677 * @brief scheduleSurfaceMode / surface mode: Main Loop | |
678 * @author Peter Ryser | |
679 * @version V0.0.1 | |
680 * @date 22-April-2014 | |
681 ****************************************************************************** | |
682 */ | |
683 | |
684 | |
685 // =============================================================================== | |
686 // scheduleTestMode | |
687 /// @brief included for sealed hardware with permanent RTE update message | |
688 // =============================================================================== | |
689 void scheduleTestMode(void) | |
690 { | |
691 uint32_t ticksdiff = 0; | |
692 uint32_t lasttick = 0; | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
693 Scheduler.tickstart = HAL_GetTick(); |
38 | 694 |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
695 Scheduler.counterPressure100msec = 0; |
38 | 696 |
697 float temperature_carousel = 0.0f; | |
698 float temperature_changer = 0.1f; | |
699 | |
700 while(global.mode == MODE_TEST) | |
701 { | |
702 schedule_check_resync(); | |
703 lasttick = HAL_GetTick(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
704 ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
705 |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
706 //Evaluate received data at 10 ms, 110 ms, 210 ms,... |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
707 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
708 { |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
709 SPI_Evaluate_RX_Data(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
710 Scheduler.counterSPIdata100msec++; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
711 } |
38 | 712 |
713 //Evaluate pressure at 20 ms, 120 ms, 220 ms,... | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
714 if(ticksdiff >= Scheduler.counterPressure100msec * 100 + 20) |
38 | 715 { |
716 global.check_sync_not_running++; | |
717 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
718 pressure_update(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
719 scheduleUpdateDeviceData(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
720 global.lifeData.ascent_rate_meter_per_min = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
721 copyPressureData(); |
38 | 722 |
723 if(temperature_carousel > 20.0f) | |
724 { | |
725 temperature_carousel = 20.0f; | |
726 temperature_changer = -0.1f; | |
727 } | |
728 else | |
729 if(temperature_carousel < 0) | |
730 { | |
731 temperature_carousel = 0; | |
732 temperature_changer = +0.1f; | |
733 } | |
734 | |
735 temperature_carousel += temperature_changer; | |
736 | |
737 uint8_t boolPressureData = !global.dataSendToMaster.boolPressureData; | |
738 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
739 global.dataSendToMaster.data[boolPressureData].pressure_mbar = get_pressure_mbar(); |
38 | 740 |
741 global.dataSendToMaster.data[boolPressureData].temperature = temperature_carousel; | |
742 global.dataSendToMaster.data[boolPressureData].pressure_uTick = HAL_GetTick(); | |
743 global.dataSendToMaster.boolPressureData = boolPressureData; | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
744 Scheduler.counterPressure100msec++; |
38 | 745 } |
746 | |
747 if(ticksdiff >= 1000) | |
748 { | |
749 //Set back tick counter | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
750 Scheduler.tickstart = HAL_GetTick(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
751 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
752 Scheduler.counterSPIdata100msec = 0; |
38 | 753 } |
754 }; | |
755 } | |
756 | |
757 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
758 |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
759 |
38 | 760 void scheduleSurfaceMode(void) |
761 { | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
762 |
38 | 763 uint32_t ticksdiff = 0; |
764 uint32_t lasttick = 0; | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
765 Scheduler.tickstart = HAL_GetTick(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
766 Scheduler.counterSPIdata100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
767 Scheduler.counterCompass100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
768 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
769 Scheduler.counterAmbientLight100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
770 Scheduler.counterWireless1msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
771 |
38 | 772 global.dataSendToMaster.mode = MODE_SURFACE; |
773 global.deviceDataSendToMaster.mode = MODE_SURFACE; | |
774 | |
775 while(global.mode == MODE_SURFACE) | |
776 { | |
120 | 777 /* printf("surface...\n"); */ |
89 | 778 // SPI_Start_single_TxRx_with_Master(); |
38 | 779 schedule_check_resync(); |
780 lasttick = HAL_GetTick(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
781 ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick); |
38 | 782 |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
783 if(ticksdiff > Scheduler.counterWireless1msec) |
38 | 784 { |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
785 Scheduler.counterWireless1msec++; |
38 | 786 changeAgeWirelessData(); |
787 global.wirelessReceived = wireless_evaluate(global.wirelessdata,MAX_WIRELESS_BYTES, &global.wirelessConfidenceStatus); | |
788 if((global.wirelessReceived > 0) && !wireless_evaluate_crc_error(global.wirelessdata,global.wirelessReceived)) | |
789 { | |
790 copyWirelessData(); | |
791 } | |
792 } | |
793 if(setButtonsNow == 1) | |
794 { | |
795 if(scheduleSetButtonResponsiveness()) | |
796 setButtonsNow = 0; | |
797 } | |
798 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
799 |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
800 //Evaluate received data at 10 ms, 110 ms, 210 ms,... |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
801 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
802 { |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
803 SPI_Evaluate_RX_Data(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
804 Scheduler.counterSPIdata100msec++; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
805 } |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
806 |
38 | 807 //Evaluate pressure at 20 ms, 120 ms, 220 ms,... |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
808 if(ticksdiff >= Scheduler.counterPressure100msec * 100 + 20) |
38 | 809 { |
810 global.check_sync_not_running++; | |
135 | 811 pressure_update(); |
812 scheduleUpdateDeviceData(); | |
38 | 813 global.lifeData.ascent_rate_meter_per_min = 0; |
135 | 814 copyPressureData(); |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
815 Scheduler.counterPressure100msec++; |
135 | 816 |
38 | 817 if(scheduleCheck_pressure_reached_dive_mode_level()) |
818 global.mode = MODE_DIVE; | |
819 } | |
820 | |
821 //evaluate compass data at 50 ms, 150 ms, 250 ms,... | |
822 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
823 if(ticksdiff >= Scheduler.counterCompass100msec * 100 + 50) |
135 | 824 { |
825 compass_read(); | |
826 acceleration_read(); | |
827 compass_calc(); | |
828 copyCompassData(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
829 Scheduler.counterCompass100msec++; |
135 | 830 } |
38 | 831 |
832 //evaluate compass data at 70 ms, 170 ms, 270 ms,... | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
833 if(ticksdiff >= Scheduler.counterAmbientLight100msec * 100 + 70) |
38 | 834 { |
835 adc_ambient_light_sensor_get_data(); | |
836 copyAmbientLightData(); | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
837 Scheduler.counterAmbientLight100msec++; |
38 | 838 } |
89 | 839 //Evaluate tissues, toxic data, etc. once a second |
38 | 840 if(ticksdiff >= 1000) |
841 { | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
842 //Set back tick counter |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
843 Scheduler.tickstart = HAL_GetTick(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
844 |
38 | 845 if(clearDecoNow) |
846 { | |
847 decom_reset_with_1000mbar(&global.lifeData); ///< this should almost reset desaturation time | |
848 // new 160215 hw | |
849 global.repetitive_dive = 0; | |
850 global.seconds_since_last_dive = 0; ///< this will reset OTU and CNS as well | |
851 global.no_fly_time_minutes = 0; | |
852 global.accidentFlag = 0; | |
853 global.accidentRemainingSeconds = 0; | |
854 vpm_init(&global.vpm, global.conservatism, global.repetitive_dive, global.seconds_since_last_dive); | |
855 clearDecoNow = 0; | |
856 } | |
89 | 857 |
38 | 858 if(global.seconds_since_last_dive) |
859 { | |
860 schedule_update_timer_helper(-1); | |
861 // global.seconds_since_last_dive++; | |
862 // if(global.seconds_since_last_dive > 777900) // a bit more than nine days [seconds] | |
863 // global.seconds_since_last_dive = 0; | |
864 } | |
89 | 865 |
38 | 866 if(global.accidentRemainingSeconds) |
867 { | |
868 global.accidentRemainingSeconds--; | |
869 if(!global.accidentRemainingSeconds) | |
870 global.accidentFlag = 0; | |
871 } | |
872 global.dataSendToMaster.accidentFlags = global.accidentFlag; | |
89 | 873 |
38 | 874 update_surface_pressure(1); |
875 scheduleUpdateLifeData(0); | |
876 decom_oxygen_calculate_otu_degrade(&global.lifeData.otu, global.seconds_since_last_dive); | |
877 decom_oxygen_calculate_cns_degrade(&global.lifeData.cns, global.seconds_since_last_dive); | |
135 | 878 |
879 /* start desaturation calculation after first valid measurement has been done */ | |
880 if(global.lifeData.pressure_surface_bar != INVALID_PREASURE_VALUE) | |
881 { | |
882 global.lifeData.desaturation_time_minutes = decom_calc_desaturation_time(global.lifeData.tissue_nitrogen_bar,global.lifeData.tissue_helium_bar,global.lifeData.pressure_surface_bar); | |
883 } | |
884 else | |
885 { | |
886 global.lifeData.desaturation_time_minutes = 0; | |
887 } | |
38 | 888 battery_charger_get_status_and_contral_battery_gas_gauge(0); |
88 | 889 battery_gas_gauge_get_data(); |
89 | 890 |
88 | 891 copyCnsAndOtuData(); |
892 copyTimeData(); | |
893 copyBatteryData(); | |
894 copyDeviceData(); | |
38 | 895 |
88 | 896 // new hw 170523 |
897 if(global.I2C_SystemStatus != HAL_OK) | |
898 { | |
899 MX_I2C1_TestAndClear(); | |
900 MX_I2C1_Init(); | |
901 if(!is_init_pressure_done()) | |
902 { | |
903 init_pressure(); | |
904 } | |
905 } | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
906 Scheduler.counterSPIdata100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
907 Scheduler.counterCompass100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
908 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
909 Scheduler.counterAmbientLight100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
910 Scheduler.counterWireless1msec = 0; |
38 | 911 } |
912 } | |
913 } | |
914 | |
142
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
915 void HardSyncToSPI() |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
916 { |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
917 if(dohardspisync) |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
918 { |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
919 //Set back tick counter |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
920 Scheduler.tickstart = HAL_GetTick(); |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
921 Scheduler.counterSPIdata100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
922 Scheduler.counterCompass100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
923 Scheduler.counterPressure100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
924 Scheduler.counterAmbientLight100msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
925 Scheduler.counterWireless1msec = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
926 dohardspisync = 0; |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
927 } |
69f4b8067daa
Use one global structure for all schedule counters
Ideenmodellierer
parents:
135
diff
changeset
|
928 } |
38 | 929 |
930 /** | |
931 ****************************************************************************** | |
932 * @brief scheduleCompassCalibrationMode | |
933 * @author heinrichs weikamp gmbh | |
934 * @version V0.0.1 | |
935 * @since 31-March-2015 | |
936 * @date 31-March-2015 | |
937 ****************************************************************************** | |
938 */ | |
939 void scheduleCompassCalibrationMode(void) | |
940 { | |
941 compass_init(1,7); // fast mode, max gain | |
942 compass_calib(); // duration : 1 minute! | |
943 compass_init(0,7); // back to normal mode | |
944 | |
945 if(global.seconds_since_last_dive) | |
946 { | |
947 schedule_update_timer_helper(-1); | |
948 // global.seconds_since_last_dive += 60; | |
949 // if(global.seconds_since_last_dive > 777900) // a bit more than nine days [seconds] | |
950 // global.seconds_since_last_dive = 0; | |
951 } | |
952 | |
953 scheduleUpdateLifeData(0); | |
954 global.mode = MODE_SURFACE; | |
955 } | |
956 | |
957 | |
958 /** | |
959 ****************************************************************************** | |
960 * @brief scheduleSleepMode / sleep mode: Main Loop | |
961 * @author heinrichs weikamp gmbh | |
962 * @version V0.0.2 | |
963 * @since 31-March-2015 | |
964 * @date 22-April-2014 | |
965 ****************************************************************************** | |
966 */ | |
967 | |
968 void scheduleSleepMode(void) | |
969 { | |
970 global.dataSendToMaster.mode = 0; | |
971 global.deviceDataSendToMaster.mode = 0; | |
972 | |
973 /* prevent button wake up problem while in sleep_prepare | |
974 * sleep prepare does I2C_DeInit() | |
975 */ | |
976 if(global.mode != MODE_SLEEP) | |
977 MX_I2C1_Init(); | |
978 else | |
979 do | |
980 { | |
981 I2C_DeInit(); | |
982 | |
983 #ifdef DEBUGMODE | |
984 HAL_Delay(2000); | |
985 #else | |
986 RTC_StopMode_2seconds(); | |
987 #endif | |
988 | |
989 | |
990 | |
991 if(global.mode == MODE_SLEEP) | |
992 secondsCount += 2; | |
993 | |
994 MX_I2C1_Init(); | |
995 pressure_sensor_get_pressure_raw(); | |
996 | |
997 if(secondsCount >= 30) | |
998 { | |
999 pressure_sensor_get_temperature_raw(); | |
1000 battery_gas_gauge_get_data(); | |
1001 // ReInit_battery_charger_status_pins(); | |
1002 battery_charger_get_status_and_contral_battery_gas_gauge(1); | |
1003 // DeInit_battery_charger_status_pins(); | |
1004 secondsCount = 0; | |
1005 } | |
1006 | |
1007 pressure_calculation(); | |
1008 | |
1009 scheduleUpdateDeviceData(); | |
1010 update_surface_pressure(2); | |
1011 | |
1012 if(global.seconds_since_last_dive) | |
1013 { | |
1014 schedule_update_timer_helper(-1); | |
1015 // global.seconds_since_last_dive += 2; | |
1016 // if(global.seconds_since_last_dive > 777900) // a bit more than nine days [seconds] | |
1017 // global.seconds_since_last_dive = 0; | |
1018 } | |
1019 | |
1020 if(global.accidentRemainingSeconds) | |
1021 { | |
1022 if(global.accidentRemainingSeconds > 2) | |
1023 global.accidentRemainingSeconds -= 2; | |
1024 else | |
1025 { | |
1026 global.accidentRemainingSeconds = 0; | |
1027 global.accidentFlag = 0; | |
1028 } | |
1029 } | |
1030 | |
1031 if(scheduleCheck_pressure_reached_dive_mode_level()) | |
1032 global.mode = MODE_BOOT; | |
1033 | |
1034 scheduleUpdateLifeData(2000); | |
1035 } | |
1036 while(global.mode == MODE_SLEEP); | |
1037 /* new section for system after Standby */ | |
1038 scheduleUpdateLifeData(-1); | |
1039 clearDecoNow = 0; | |
1040 setButtonsNow = 0; | |
1041 } | |
1042 | |
1043 | |
1044 | |
1045 /* Private functions ---------------------------------------------------------*/ | |
1046 | |
1047 | |
1048 /** | |
1049 ****************************************************************************** | |
1050 * @brief scheduleCheck_pressure_reached_dive_mode_level | |
1051 * @author heinrichs weikamp gmbh | |
1052 * @version V0.0.1 from inline code | |
1053 * @date 09-Sept-2015 | |
1054 ****************************************************************************** | |
1055 */ | |
1056 _Bool scheduleCheck_pressure_reached_dive_mode_level(void) | |
1057 { | |
1058 if(get_pressure_mbar() > 1160) | |
1059 return 1; | |
1060 else | |
1061 if((global.mode == MODE_SURFACE) && (get_pressure_mbar() > (get_surface_mbar() + 100)) && (get_surface_mbar() > 880)) | |
1062 return 1; | |
1063 else | |
1064 return 0; | |
1065 } | |
1066 | |
1067 | |
1068 /** | |
1069 ****************************************************************************** | |
1070 * @brief scheduleUpdateLifeData / calculates tissues | |
1071 * @author Peter Ryser | |
1072 * @version V0.0.1 | |
1073 * @date 22-April-2014 | |
1074 ****************************************************************************** | |
1075 */ | |
1076 | |
1077 | |
1078 void scheduleUpdateLifeData(int32_t asynchron_milliseconds_since_last) | |
1079 { | |
1080 static _Bool first = 1; | |
1081 static uint32_t tickstart = 0; | |
1082 static uint32_t ticksrest = 0; | |
1083 | |
1084 uint32_t ticksdiff = 0; | |
1085 uint32_t ticksnow = 0; | |
1086 uint32_t time_seconds = 0; | |
1087 uint8_t whichGasTmp = 0; | |
1088 | |
135 | 1089 uint8_t updateTissueData = 0; |
1090 | |
1091 | |
1092 if(global.lifeData.pressure_surface_bar == INVALID_PREASURE_VALUE) | |
1093 { | |
1094 updateTissueData = 1; | |
1095 } | |
1096 | |
38 | 1097 if(asynchron_milliseconds_since_last < 0) |
1098 { | |
1099 first = 1; | |
1100 tickstart = 0; | |
1101 ticksrest = 0; | |
1102 return; | |
1103 } | |
1104 | |
1105 if(!asynchron_milliseconds_since_last && first) | |
1106 { | |
1107 tickstart = HAL_GetTick(); | |
1108 first = 0; | |
1109 return; | |
1110 } | |
1111 | |
1112 whichGasTmp = global.whichGas; | |
1113 global.lifeData.actualGas = global.aktualGas[whichGasTmp]; | |
1114 global.lifeData.pressure_ambient_bar = get_pressure_mbar() / 1000.0f; | |
1115 global.lifeData.pressure_surface_bar = get_surface_mbar() / 1000.0f; | |
1116 | |
135 | 1117 if(updateTissueData) |
1118 { | |
1119 decom_reset_with_ambientmbar(global.lifeData.pressure_surface_bar,&global.lifeData); | |
1120 } | |
1121 | |
38 | 1122 if(!asynchron_milliseconds_since_last) |
1123 { | |
1124 ticksnow = HAL_GetTick(); | |
1125 ticksdiff = time_elapsed_ms(tickstart,ticksnow); | |
1126 } | |
1127 else | |
1128 { | |
1129 first = 1; | |
1130 ticksdiff = asynchron_milliseconds_since_last; | |
1131 } | |
1132 | |
1133 if(ticksrest > 1000) // whatever happens after standby with STM32L476 | |
1134 ticksrest = 0; // maybe move static to SRAM2 | |
1135 | |
1136 ticksdiff += ticksrest; | |
1137 time_seconds = ticksdiff/ 1000; | |
1138 ticksrest = ticksdiff - time_seconds * 1000; | |
1139 tickstart = ticksnow; | |
1140 | |
1141 decom_tissues_exposure((int)time_seconds, &global.lifeData); | |
1142 if(global.demo_mode) | |
1143 decom_tissues_exposure((int)(3*time_seconds), &global.lifeData); | |
1144 copyTissueData(); | |
1145 } | |
1146 | |
1147 | |
1148 /** | |
1149 ****************************************************************************** | |
1150 * @brief scheduleUpdateDeviceData | |
1151 * @author heinrichs weikamp gmbh | |
1152 * @version V0.0.1 | |
1153 * @date 16-March-2015 | |
1154 * | |
1155 * two step process | |
1156 * first compare with data from main CPU == externalLogbookFlash | |
1157 * second update with new sensor data | |
1158 ****************************************************************************** | |
1159 */ | |
1160 void scheduleSetDate(SDeviceLine *line) | |
1161 { | |
1162 extern RTC_HandleTypeDef RTCHandle; | |
1163 | |
1164 line->date_rtc_dr = (uint32_t)(RTCHandle.Instance->DR & RTC_DR_RESERVED_MASK); | |
1165 line->time_rtc_tr = (uint32_t)(RTCHandle.Instance->TR & RTC_TR_RESERVED_MASK); | |
1166 } | |
1167 | |
1168 | |
1169 void scheduleCopyDeviceData(SDeviceLine *lineWrite, const SDeviceLine *lineRead) | |
1170 { | |
1171 lineWrite->date_rtc_dr = lineRead->date_rtc_dr; | |
1172 lineWrite->time_rtc_tr = lineRead->time_rtc_tr; | |
1173 lineWrite->value_int32 = lineRead->value_int32; | |
1174 } | |
1175 | |
1176 | |
1177 void scheduleUpdateDeviceData(void) | |
1178 { | |
1179 /* first step, main CPU */ | |
1180 | |
1181 if(deviceDataFlashValid) | |
1182 { | |
1183 /* max values */ | |
1184 if(global.deviceData.batteryChargeCompleteCycles.value_int32 < DeviceDataFlash.batteryChargeCompleteCycles.value_int32) | |
1185 { | |
1186 scheduleCopyDeviceData(&global.deviceData.batteryChargeCompleteCycles, &DeviceDataFlash.batteryChargeCompleteCycles); | |
1187 } | |
1188 if(global.deviceData.batteryChargeCycles.value_int32 < DeviceDataFlash.batteryChargeCycles.value_int32) | |
1189 { | |
1190 scheduleCopyDeviceData(&global.deviceData.batteryChargeCycles, &DeviceDataFlash.batteryChargeCycles); | |
1191 } | |
1192 if(global.deviceData.temperatureMaximum.value_int32 < DeviceDataFlash.temperatureMaximum.value_int32) | |
1193 { | |
1194 scheduleCopyDeviceData(&global.deviceData.temperatureMaximum, &DeviceDataFlash.temperatureMaximum); | |
1195 } | |
1196 if(global.deviceData.depthMaximum.value_int32 < DeviceDataFlash.depthMaximum.value_int32) | |
1197 { | |
1198 scheduleCopyDeviceData(&global.deviceData.depthMaximum, &DeviceDataFlash.depthMaximum); | |
1199 } | |
1200 if(global.deviceData.diveCycles.value_int32 < DeviceDataFlash.diveCycles.value_int32) | |
1201 { | |
1202 scheduleCopyDeviceData(&global.deviceData.diveCycles, &DeviceDataFlash.diveCycles); | |
1203 } | |
1204 if(global.deviceData.hoursOfOperation.value_int32 < DeviceDataFlash.hoursOfOperation.value_int32) | |
1205 { | |
1206 scheduleCopyDeviceData(&global.deviceData.hoursOfOperation, &DeviceDataFlash.hoursOfOperation); | |
1207 } | |
1208 | |
1209 /* min values */ | |
1210 if(global.deviceData.temperatureMinimum.value_int32 > DeviceDataFlash.temperatureMinimum.value_int32) | |
1211 { | |
1212 scheduleCopyDeviceData(&global.deviceData.temperatureMinimum, &DeviceDataFlash.temperatureMinimum); | |
1213 } | |
1214 if(global.deviceData.voltageMinimum.value_int32 > DeviceDataFlash.voltageMinimum.value_int32) | |
1215 { | |
1216 scheduleCopyDeviceData(&global.deviceData.voltageMinimum, &DeviceDataFlash.voltageMinimum); | |
1217 } | |
1218 } | |
1219 | |
1220 /* second step, sensor data */ | |
1221 int32_t temperature_centigrad_int32; | |
1222 int32_t pressure_mbar_int32; | |
1223 int32_t voltage_mvolt_int32; | |
1224 | |
1225 temperature_centigrad_int32 = (int32_t)(get_temperature() * 100); | |
1226 if(temperature_centigrad_int32 < global.deviceData.temperatureMinimum.value_int32) | |
1227 { | |
1228 global.deviceData.temperatureMinimum.value_int32 = temperature_centigrad_int32; | |
88 | 1229 scheduleSetDate(&global.deviceData.temperatureMinimum); |
38 | 1230 } |
1231 | |
1232 if(temperature_centigrad_int32 > global.deviceData.temperatureMaximum.value_int32) | |
1233 { | |
1234 global.deviceData.temperatureMaximum.value_int32 = temperature_centigrad_int32; | |
88 | 1235 scheduleSetDate(&global.deviceData.temperatureMaximum); |
38 | 1236 } |
1237 | |
1238 pressure_mbar_int32 = (int32_t)get_pressure_mbar(); | |
1239 if(pressure_mbar_int32 > global.deviceData.depthMaximum.value_int32) | |
1240 { | |
1241 global.deviceData.depthMaximum.value_int32 = pressure_mbar_int32; | |
88 | 1242 scheduleSetDate(&global.deviceData.depthMaximum); |
38 | 1243 } |
1244 | |
1245 voltage_mvolt_int32 = (int32_t)(get_voltage() * 1000); | |
1246 if(voltage_mvolt_int32 < global.deviceData.voltageMinimum.value_int32) | |
1247 { | |
1248 global.deviceData.voltageMinimum.value_int32 = voltage_mvolt_int32; | |
88 | 1249 scheduleSetDate(&global.deviceData.voltageMinimum); |
38 | 1250 } |
1251 | |
1252 /* third step, counter */ | |
1253 switch (global.mode) | |
1254 { | |
1255 case MODE_SURFACE: | |
1256 case MODE_DIVE: | |
1257 default: | |
1258 deviceDataSubSeconds++; | |
1259 if(deviceDataSubSeconds > 10) | |
1260 { | |
1261 deviceDataSubSeconds = 0; | |
1262 global.deviceData.hoursOfOperation.value_int32++; | |
1263 } | |
1264 break; | |
1265 | |
1266 case MODE_SLEEP: | |
1267 case MODE_SHUTDOWN: | |
1268 break; | |
1269 } | |
1270 } | |
1271 | |
1272 | |
1273 void scheduleUpdateDeviceDataChargerFull(void) | |
1274 { | |
1275 global.deviceData.batteryChargeCompleteCycles.value_int32++; | |
88 | 1276 scheduleSetDate(&global.deviceData.batteryChargeCompleteCycles); |
38 | 1277 } |
1278 | |
1279 | |
1280 void scheduleUpdateDeviceDataChargerCharging(void) | |
1281 { | |
1282 global.deviceData.batteryChargeCycles.value_int32++; | |
88 | 1283 scheduleSetDate(&global.deviceData.batteryChargeCycles); |
38 | 1284 } |
1285 | |
1286 | |
1287 /** | |
1288 ****************************************************************************** | |
1289 * @brief vpm_crush / calls vpm calc_crushing_pressure every four seconds during descend | |
1290 * @author Peter Ryser | |
1291 * @version V0.0.1 | |
1292 * @date 22-April-2014 | |
1293 ****************************************************************************** | |
1294 */ | |
1295 _Bool vpm_crush2(void) | |
1296 { | |
1297 int i = 0; | |
1298 static float starting_ambient_pressure = 0; | |
1299 static float ending_ambient_pressure = 0; | |
1300 static float time_calc_begin = -1; | |
1301 static float initial_helium_pressure[16]; | |
1302 static float initial_nitrogen_pressure[16]; | |
1303 ending_ambient_pressure = global.lifeData.pressure_ambient_bar * 10; | |
1304 | |
1305 if((global.lifeData.dive_time_seconds <= 4) || (starting_ambient_pressure >= ending_ambient_pressure)) | |
1306 { | |
1307 time_calc_begin = global.lifeData.dive_time_seconds; | |
1308 starting_ambient_pressure = global.lifeData.pressure_ambient_bar * 10; | |
1309 for( i = 0; i < 16; i++) | |
1310 { | |
1311 initial_helium_pressure[i] = global.lifeData.tissue_helium_bar[i] * 10; | |
1312 initial_nitrogen_pressure[i] = global.lifeData.tissue_nitrogen_bar[i] * 10; | |
1313 } | |
1314 return 0; | |
1315 } | |
1316 if(global.lifeData.dive_time_seconds - time_calc_begin >= 4) | |
1317 { | |
1318 if(ending_ambient_pressure > starting_ambient_pressure + 0.5f) | |
1319 { | |
1320 float rate = (ending_ambient_pressure - starting_ambient_pressure) * 60 / 4; | |
1321 calc_crushing_pressure(&global.lifeData, &global.vpm, initial_helium_pressure, initial_nitrogen_pressure, starting_ambient_pressure, rate); | |
1322 | |
1323 time_calc_begin = global.lifeData.dive_time_seconds; | |
1324 starting_ambient_pressure = global.lifeData.pressure_ambient_bar * 10; | |
1325 for( i = 0; i < 16; i++) | |
1326 { | |
1327 initial_helium_pressure[i] = global.lifeData.tissue_helium_bar[i] * 10; | |
1328 initial_nitrogen_pressure[i] = global.lifeData.tissue_nitrogen_bar[i] * 10; | |
1329 } | |
1330 | |
1331 return 1; | |
1332 } | |
1333 | |
1334 } | |
1335 return 0; | |
1336 }; | |
1337 | |
1338 | |
1339 void initStructWithZeero(uint8_t* data, uint16_t length) | |
1340 { | |
1341 for(uint16_t i = 0; i < length; i++) | |
1342 data[i] = 0; | |
1343 } | |
1344 | |
1345 | |
1346 long get_nofly_time_minutes(void) | |
1347 { | |
1348 | |
1349 if(global.no_fly_time_minutes <= 0) | |
1350 return 0; | |
1351 | |
1352 long minutes_since_last_dive = global.seconds_since_last_dive/60; | |
1353 | |
1354 if((global.seconds_since_last_dive > 0) && (global.no_fly_time_minutes > minutes_since_last_dive)) | |
1355 { | |
1356 return (global.no_fly_time_minutes - minutes_since_last_dive); | |
1357 } | |
1358 else | |
1359 { | |
1360 global.no_fly_time_minutes = 0; | |
1361 return 0; | |
1362 } | |
1363 } | |
1364 | |
1365 | |
1366 //Supports threadsave copying!!! | |
1367 void copyActualGas(SGas gas) | |
1368 { | |
1369 uint8_t whichGas = !global.whichGas; | |
1370 global.aktualGas[whichGas] = gas; | |
1371 global.whichGas = whichGas; | |
1372 } | |
1373 | |
1374 | |
1375 //Supports threadsave copying!!! | |
1376 void copyPressureData(void) | |
1377 { | |
1378 global.dataSendToMaster.sensorErrors = I2C1_Status(); | |
1379 //uint8_t dataSendToMaster. | |
1380 uint8_t boolPressureData = !global.dataSendToMaster.boolPressureData; | |
1381 global.dataSendToMaster.data[boolPressureData].temperature = get_temperature(); | |
1382 global.dataSendToMaster.data[boolPressureData].pressure_mbar = get_pressure_mbar(); | |
1383 global.dataSendToMaster.data[boolPressureData].surface_mbar = get_surface_mbar(); | |
1384 global.dataSendToMaster.data[boolPressureData].ascent_rate_meter_per_min = global.lifeData.ascent_rate_meter_per_min; | |
1385 global.dataSendToMaster.data[boolPressureData].pressure_uTick = HAL_GetTick(); | |
1386 global.dataSendToMaster.boolPressureData = boolPressureData; | |
1387 } | |
1388 | |
1389 | |
1390 //Supports threadsave copying!!! | |
1391 void copyCnsAndOtuData(void) | |
1392 { | |
1393 //uint8_t dataSendToMaster. | |
1394 uint8_t boolToxicData = !global.dataSendToMaster.boolToxicData; | |
1395 global.dataSendToMaster.data[boolToxicData].cns = global.lifeData.cns; | |
1396 global.dataSendToMaster.data[boolToxicData].otu = global.lifeData.otu; | |
1397 global.dataSendToMaster.data[boolToxicData].desaturation_time_minutes = global.lifeData.desaturation_time_minutes; | |
1398 global.dataSendToMaster.data[boolToxicData].no_fly_time_minutes = get_nofly_time_minutes(); | |
1399 global.dataSendToMaster.boolToxicData = boolToxicData; | |
1400 } | |
1401 | |
1402 | |
1403 //Supports threadsave copying!!! | |
1404 void copyTimeData(void) | |
1405 { | |
1406 extern RTC_HandleTypeDef RTCHandle; | |
1407 | |
1408 uint8_t boolTimeData = !global.dataSendToMaster.boolTimeData; | |
1409 global.dataSendToMaster.data[boolTimeData].localtime_rtc_tr = (uint32_t)(RTCHandle.Instance->TR & RTC_TR_RESERVED_MASK); | |
1410 global.dataSendToMaster.data[boolTimeData].localtime_rtc_dr = (uint32_t)(RTCHandle.Instance->DR & RTC_DR_RESERVED_MASK); | |
1411 global.dataSendToMaster.data[boolTimeData].divetime_seconds = (uint32_t)global.lifeData.dive_time_seconds; | |
1412 global.dataSendToMaster.data[boolTimeData].dive_time_seconds_without_surface_time = (uint32_t)global.lifeData.dive_time_seconds_without_surface_time; | |
1413 global.dataSendToMaster.data[boolTimeData].surfacetime_seconds = (uint32_t)global.seconds_since_last_dive; | |
1414 global.dataSendToMaster.data[boolTimeData].counterSecondsShallowDepth = (uint32_t)global.lifeData.counterSecondsShallowDepth; | |
1415 global.dataSendToMaster.boolTimeData = boolTimeData; | |
1416 } | |
1417 | |
1418 | |
1419 //Supports threadsave copying!!! | |
1420 void copyCompassData(void) | |
1421 { | |
1422 extern float compass_heading; | |
1423 extern float compass_roll; | |
1424 extern float compass_pitch; | |
1425 //uint8_t dataSendToMaster. | |
1426 uint8_t boolCompassData = !global.dataSendToMaster.boolCompassData; | |
1427 global.dataSendToMaster.data[boolCompassData].compass_heading = compass_heading; | |
1428 global.dataSendToMaster.data[boolCompassData].compass_roll = compass_roll; | |
1429 global.dataSendToMaster.data[boolCompassData].compass_pitch = compass_pitch; | |
1430 global.dataSendToMaster.data[boolCompassData].compass_DX_f = 0; | |
1431 global.dataSendToMaster.data[boolCompassData].compass_DY_f = 0; | |
1432 global.dataSendToMaster.data[boolCompassData].compass_DZ_f = 0; | |
1433 global.dataSendToMaster.data[boolCompassData].compass_uTick = HAL_GetTick(); | |
1434 global.dataSendToMaster.boolCompassData = boolCompassData; | |
1435 } | |
1436 | |
1437 | |
1438 void copyCompassDataDuringCalibration(int16_t dx, int16_t dy, int16_t dz) | |
1439 { | |
1440 extern float compass_heading; | |
1441 extern float compass_roll; | |
1442 extern float compass_pitch; | |
1443 //uint8_t dataSendToMaster. | |
1444 uint8_t boolCompassData = !global.dataSendToMaster.boolCompassData; | |
1445 global.dataSendToMaster.data[boolCompassData].compass_heading = compass_heading; | |
1446 global.dataSendToMaster.data[boolCompassData].compass_roll = compass_roll; | |
1447 global.dataSendToMaster.data[boolCompassData].compass_pitch = compass_pitch; | |
1448 global.dataSendToMaster.data[boolCompassData].compass_DX_f = dx; | |
1449 global.dataSendToMaster.data[boolCompassData].compass_DY_f = dy; | |
1450 global.dataSendToMaster.data[boolCompassData].compass_DZ_f = dz; | |
1451 global.dataSendToMaster.boolCompassData = boolCompassData; | |
1452 } | |
1453 | |
1454 | |
1455 //Supports threadsave copying!!! | |
1456 void copyBatteryData(void) | |
1457 { | |
1458 uint8_t boolBatteryData = !global.dataSendToMaster.boolBatteryData; | |
1459 global.dataSendToMaster.data[boolBatteryData].battery_voltage = get_voltage(); | |
1460 global.dataSendToMaster.data[boolBatteryData].battery_charge= get_charge(); | |
1461 global.dataSendToMaster.boolBatteryData = boolBatteryData; | |
1462 } | |
1463 | |
1464 | |
1465 //Supports threadsave copying!!! | |
1466 void copyAmbientLightData(void) | |
1467 { | |
1468 uint8_t boolAmbientLightData = !global.dataSendToMaster.boolAmbientLightData; | |
1469 global.dataSendToMaster.data[boolAmbientLightData].ambient_light_level = get_ambient_light_level(); | |
1470 global.dataSendToMaster.boolAmbientLightData = boolAmbientLightData; | |
1471 } | |
1472 | |
1473 | |
1474 //Supports threadsave copying!!! | |
1475 void copyTissueData(void) | |
1476 { | |
1477 //uint8_t dataSendToMaster. | |
1478 uint8_t boolTisssueData = !global.dataSendToMaster.boolTisssueData; | |
1479 for(int i = 0; i < 16; i++) | |
1480 { | |
1481 global.dataSendToMaster.data[boolTisssueData].tissue_nitrogen_bar[i] = global.lifeData.tissue_nitrogen_bar[i]; | |
1482 global.dataSendToMaster.data[boolTisssueData].tissue_helium_bar[i] = global.lifeData.tissue_helium_bar[i]; | |
1483 } | |
1484 global.dataSendToMaster.boolTisssueData = boolTisssueData; | |
1485 } | |
1486 | |
1487 | |
1488 //Supports threadsave copying!!! | |
1489 void copyVpmCrushingData(void) | |
1490 { | |
1491 //uint8_t dataSendToMaster. | |
1492 uint8_t boolCrushingData = !global.dataSendToMaster.boolCrushingData; | |
1493 for(int i = 0; i < 16; i++) | |
1494 { | |
1495 global.dataSendToMaster.data[boolCrushingData].max_crushing_pressure_n2[i] = global.vpm.max_crushing_pressure_n2[i]; | |
1496 global.dataSendToMaster.data[boolCrushingData].max_crushing_pressure_he[i] = global.vpm.max_crushing_pressure_he[i]; | |
1497 global.dataSendToMaster.data[boolCrushingData].adjusted_critical_radius_he[i] = global.vpm.adjusted_critical_radius_he[i]; | |
1498 global.dataSendToMaster.data[boolCrushingData].adjusted_critical_radius_n2[i] = global.vpm.adjusted_critical_radius_n2[i]; | |
1499 } | |
1500 global.dataSendToMaster.boolCrushingData = boolCrushingData; | |
1501 } | |
1502 | |
1503 | |
1504 void copyDeviceData(void) | |
1505 { | |
1506 uint8_t boolDeviceData = !global.deviceDataSendToMaster.boolDeviceData; | |
1507 memcpy(&global.deviceDataSendToMaster.DeviceData[boolDeviceData], &global.deviceData,sizeof(SDevice)); | |
1508 global.deviceDataSendToMaster.boolDeviceData = boolDeviceData; | |
1509 | |
1510 global.deviceDataSendToMaster.boolVpmRepetitiveDataValid = 0; | |
1511 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.adjusted_critical_radius_he, &global.vpm.adjusted_critical_radius_he, sizeof(16*4)); | |
1512 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.adjusted_critical_radius_n2, &global.vpm.adjusted_critical_radius_n2, sizeof(16*4)); | |
1513 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.adjusted_crushing_pressure_he, &global.vpm.adjusted_crushing_pressure_he, sizeof(16*4)); | |
1514 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.adjusted_crushing_pressure_n2, &global.vpm.adjusted_crushing_pressure_n2, sizeof(16*4)); | |
1515 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.initial_allowable_gradient_he, &global.vpm.initial_allowable_gradient_he, sizeof(16*4)); | |
1516 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.initial_allowable_gradient_n2, &global.vpm.initial_allowable_gradient_n2, sizeof(16*4)); | |
1517 memcpy(&global.deviceDataSendToMaster.VpmRepetitiveData.max_actual_gradient, &global.vpm.max_actual_gradient, sizeof(16*4)); | |
1518 global.deviceDataSendToMaster.VpmRepetitiveData.repetitive_variables_not_valid = global.vpm.repetitive_variables_not_valid; | |
1519 global.deviceDataSendToMaster.boolVpmRepetitiveDataValid = 1; | |
1520 } | |
1521 | |
1522 void changeAgeWirelessData(void) | |
1523 { | |
1524 for(int i=0;i<4;i++) | |
1525 { | |
1526 if(global.dataSendToMaster.data[global.dataSendToMaster.boolWirelessData].wireless_data[i].ageInMilliSeconds) | |
1527 global.dataSendToMaster.data[global.dataSendToMaster.boolWirelessData].wireless_data[i].ageInMilliSeconds++; | |
1528 } | |
1529 } | |
1530 | |
1531 void copyWirelessData(void) | |
1532 { | |
1533 uint8_t boolWirelessData = !global.dataSendToMaster.boolWirelessData; | |
1534 SDataWireless *dataOld, *dataNew; | |
1535 for(int i=0;i<3;i++) | |
1536 { | |
1537 dataNew = &global.dataSendToMaster.data[boolWirelessData].wireless_data[i+1]; | |
1538 dataOld = &global.dataSendToMaster.data[!boolWirelessData].wireless_data[i]; | |
1539 dataNew->ageInMilliSeconds = dataOld->ageInMilliSeconds; | |
1540 dataNew->numberOfBytes = dataOld->numberOfBytes; | |
1541 dataNew->status = dataOld->status; | |
1542 memcpy(dataNew->data, dataOld->data,8); | |
1543 } | |
1544 | |
1545 global.dataSendToMaster.data[boolWirelessData].wireless_data[0].ageInMilliSeconds = 1; | |
1546 global.dataSendToMaster.data[boolWirelessData].wireless_data[0].numberOfBytes = global.wirelessReceived; | |
1547 global.dataSendToMaster.data[boolWirelessData].wireless_data[0].status = global.wirelessConfidenceStatus; | |
1548 for(int i=0;i<MAX_WIRELESS_BYTES;i++) | |
1549 global.dataSendToMaster.data[boolWirelessData].wireless_data[0].data[i] = global.wirelessdata[i]; | |
1550 for(int i=MAX_WIRELESS_BYTES;i<12;i++) | |
1551 global.dataSendToMaster.data[boolWirelessData].wireless_data[0].data[i] = 0xFF; | |
1552 | |
1553 global.dataSendToMaster.boolWirelessData = boolWirelessData; | |
1554 } | |
1555 | |
1556 /* copyPICdata(); is used in spi.c */ | |
1557 void copyPICdata(void) | |
1558 { | |
1559 uint8_t boolPICdata = !global.dataSendToMaster.boolPICdata; | |
1560 for(int i = 0; i < 3; i++) | |
1561 { | |
1562 global.dataSendToMaster.data[boolPICdata].button_setting[i] = global.ButtonPICdata[i]; | |
1563 } | |
1564 global.dataSendToMaster.boolPICdata = boolPICdata; | |
1565 } | |
1566 | |
1567 | |
1568 | |
1569 | |
1570 typedef enum | |
1571 { | |
1572 SPI3_OK = 0x00, | |
1573 SPI3_DEINIT = 0x01, | |
1574 } SPI3_StatusTypeDef; | |
1575 /* if spi3 is running and the SPI3_ButtonAdjust call returns OK, all is fine | |
1576 if the SPI3_ButtonAdjust call returns error, the spi3 is DeInit | |
1577 and will be init the next call of scheduleSetButtonResponsiveness() | |
1578 and data will be send again on the third call | |
1579 therefore on return 0 of scheduleSetButtonResponsiveness() the caller flag should kept active | |
1580 */ | |
1581 uint8_t scheduleSetButtonResponsiveness(void) | |
1582 { | |
1583 static uint8_t SPI3status = SPI3_OK; | |
1584 | |
1585 if((SPI3status == SPI3_OK) && (SPI3_ButtonAdjust(global.ButtonResponsiveness, global.ButtonPICdata))) | |
1586 { | |
1587 copyPICdata(); | |
1588 return 1; | |
1589 } | |
1590 else | |
1591 { | |
1592 for(int i=0;i<3;i++) | |
1593 { | |
1594 global.ButtonPICdata[i] = 0xFF; | |
1595 } | |
1596 copyPICdata(); | |
1597 | |
1598 if(SPI3status == SPI3_OK) | |
1599 { | |
1600 MX_SPI3_DeInit(); | |
1601 SPI3status = SPI3_DEINIT; | |
1602 } | |
1603 else | |
1604 { | |
1605 MX_SPI3_Init(); | |
1606 SPI3status = SPI3_OK; | |
1607 } | |
1608 return 0; | |
1609 } | |
1610 } | |
1611 | |
1612 | |
1613 //save time diffenrence | |
1614 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow) | |
1615 { | |
1616 if(ticksstart <= ticksnow) | |
1617 { | |
1618 return ticksnow - ticksstart; | |
1619 } | |
1620 else | |
1621 { | |
1622 return 0xFFFFFFFF - ticksstart + ticksnow; | |
1623 } | |
1624 } | |
1625 | |
1626 /* same as in data_central.c */ | |
1627 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeDataCall) | |
1628 { | |
1629 if(lifeDataCall->pressure_ambient_bar < (lifeDataCall->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f | |
1630 return true; | |
1631 else | |
1632 return false; | |
1633 } | |
1634 | |
1635 | |
1636 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ | |
1637 |