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