38
+ − 1 /**
+ − 2 ******************************************************************************
+ − 3 * @file data_exchange_main.c
+ − 4 * @author heinrichs weikamp gmbh
+ − 5 * @date 13-Oct-2014
+ − 6 * @version V0.0.3
+ − 7 * @since 17-Feb-2016
+ − 8
+ − 9 * @brief Communication with the second CPU == RTE system
+ − 10 *
+ − 11 @verbatim
+ − 12 ==============================================================================
+ − 13 ##### Version Changes #####
+ − 14 ==============================================================================
+ − 15 160217 V0.0.3 pStateUsed->decolistXXXXX.tickstamp = HAL_GetTick(); added
+ − 16 150627 V0.0.2
+ − 17
+ − 18 ==============================================================================
+ − 19 ##### How to use #####
+ − 20 ==============================================================================
+ − 21
+ − 22 ==============================================================================
+ − 23 ##### Button, Set Time, Clear Deco etc Request #####
+ − 24 ==============================================================================
+ − 25 was updated (151207) for buttons and clear deco at the moment only
+ − 26 using requestNecessary and checking in DataEX_copy_to_LifeData()
+ − 27 Hence if there is no confirm from the smallCPU on the data after the request
+ − 28 the request will be send again.
+ − 29
+ − 30 ==============================================================================
+ − 31 ##### Device Data #####
+ − 32 ==============================================================================
+ − 33
+ − 34 main CPU always sends the device data info that it has at the moment
+ − 35
+ − 36 on start it is INT32_MIN, INT32_MAX and 0
+ − 37 as initialized in data_central.c variable declaration
+ − 38
+ − 39 second small CPU gets request to send its device data
+ − 40
198
+ − 41 on reception the data is merged with the data in externLogbookFlash,
38
+ − 42 stored on the externLogbookFlash and from now on send to small CPU
+ − 43
+ − 44 ==============================================================================
+ − 45 ##### Magnet Reset #####
+ − 46 ==============================================================================
+ − 47
+ − 48 @endverbatim
+ − 49 ******************************************************************************
+ − 50 * @attention
+ − 51 *
+ − 52 * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+ − 53 *
+ − 54 ******************************************************************************
+ − 55 */
+ − 56
+ − 57 /* Includes ------------------------------------------------------------------*/
133
+ − 58 #include <stdlib.h>
198
+ − 59 #include <string.h> // for memcpy
38
+ − 60 #include "stm32f4xx_hal.h"
+ − 61 #include "stdio.h"
+ − 62 #include "ostc.h"
+ − 63 #include "settings.h"
+ − 64 #include "data_central.h"
+ − 65 #include "data_exchange_main.h"
+ − 66 #include "base.h"
+ − 67 #include "decom.h"
+ − 68 #include "calc_crush.h" /* for vpm_init */
+ − 69 #include "simulation.h"
+ − 70 #include "tCCR.h"
+ − 71 #include "timer.h"
+ − 72 #include "buehlmann.h"
+ − 73 #include "externLogbookFlash.h"
+ − 74
+ − 75
173
+ − 76 /* Exported variables --------------------------------------------------------*/
198
+ − 77 static uint8_t wasPowerOn = 0;
+ − 78 static confirmbit8_Type requestNecessary = { .uw = 0 };
+ − 79 static uint8_t wasUpdateNotPowerOn = 0;
38
+ − 80
+ − 81 /* Private variables with external access ------------------------------------*/
+ − 82
+ − 83 /* Private variables ---------------------------------------------------------*/
198
+ − 84 static uint8_t told_reset_logik_alles_ok = 0;
38
+ − 85
198
+ − 86 static SDataReceiveFromMaster dataOut;
+ − 87 static SDataExchangeSlaveToMaster dataIn;
38
+ − 88
198
+ − 89 static uint8_t data_old__lost_connection_to_slave_counter_temp = 0;
+ − 90 static uint8_t data_old__lost_connection_to_slave_counter_retry = 0;
+ − 91 static uint32_t data_old__lost_connection_to_slave_counter_total = 0;
38
+ − 92
+ − 93 /* Private types -------------------------------------------------------------*/
+ − 94
+ − 95 /* Private function prototypes -----------------------------------------------*/
198
+ − 96 static uint8_t DataEX_check_header_and_footer_ok(void);
+ − 97 static uint8_t DataEX_check_header_and_footer_shifted(void);
+ − 98 static uint8_t DataEX_check_header_and_footer_devicedata(void);
+ − 99 static void DataEX_check_DeviceData(void);
38
+ − 100
+ − 101 /* Exported functions --------------------------------------------------------*/
+ − 102
+ − 103 uint8_t DataEX_was_power_on(void)
+ − 104 {
+ − 105 return wasPowerOn;
+ − 106 }
+ − 107
198
+ − 108 static uint8_t count_DataEX_Error_Handler = 0;
+ − 109 static uint8_t last_error_DataEX_Error_Handler = 0;
38
+ − 110
198
+ − 111 static void DataEX_Error_Handler(uint8_t answer)
38
+ − 112 {
+ − 113 count_DataEX_Error_Handler++;
+ − 114 last_error_DataEX_Error_Handler = answer;
133
+ − 115
156
+ − 116 /* A wrong footer indicates a communication interrupt. State machine is waiting for new data which is not received because no new transmission is triggered */
133
+ − 117 /* ==> Abort data exchange to enable a new RX / TX cycle */
+ − 118 if(answer == HAL_BUSY)
+ − 119 {
+ − 120 HAL_SPI_Abort_IT(&cpu2DmaSpi);
+ − 121 }
137
+ − 122
38
+ − 123 return;
+ − 124 }
+ − 125
+ − 126
+ − 127 uint32_t DataEX_lost_connection_count(void)
+ − 128 {
+ − 129 return data_old__lost_connection_to_slave_counter_total;
+ − 130 }
+ − 131
+ − 132
198
+ − 133 SDataReceiveFromMaster *dataOutGetPointer(void)
38
+ − 134 {
+ − 135 return &dataOut;
+ − 136 }
+ − 137
+ − 138 void DataEX_init(void)
+ − 139 {
+ − 140 SDiveState * pStateReal = stateRealGetPointerWrite();
99
+ − 141 pStateReal->data_old__lost_connection_to_slave = 0; //initial value
38
+ − 142 data_old__lost_connection_to_slave_counter_temp = 0;
+ − 143 data_old__lost_connection_to_slave_counter_total = 0;
+ − 144
+ − 145 memset((void *)&dataOut, 0, sizeof(SDataReceiveFromMaster));
+ − 146
+ − 147 dataOut.header.checkCode[0] = 0xBB;
208
+ − 148 dataOut.header.checkCode[1] = SPI_RX_STATE_OK;
+ − 149 dataOut.header.checkCode[2] = SPI_RX_STATE_OK;
38
+ − 150 dataOut.header.checkCode[3] = 0xBB;
+ − 151
+ − 152 dataOut.footer.checkCode[0] = 0xF4;
+ − 153 dataOut.footer.checkCode[1] = 0xF3;
+ − 154 dataOut.footer.checkCode[2] = 0xF2;
+ − 155 dataOut.footer.checkCode[3] = 0xF1;
+ − 156 }
+ − 157
+ − 158
198
+ − 159 static void DataEx_call_helper_requests(void)
38
+ − 160 {
+ − 161 static uint8_t setDateWasSend = 0;
+ − 162 static uint8_t setTimeWasSend = 0;
+ − 163 static uint8_t calibrateCompassWasSend = 0;
+ − 164 static uint8_t setButtonSensitivityWasSend = 0;
+ − 165 static uint8_t clearDecoWasSend = 0;
+ − 166 static uint8_t getDeviceDataWasSend = 0;
+ − 167 static uint8_t setAccidentFlagWasSend = 0;
+ − 168 static uint8_t setEndDiveWasSend = 0;
+ − 169
+ − 170 if(getDeviceDataWasSend)
+ − 171 {
+ − 172 dataOut.getDeviceDataNow = 0;
+ − 173 requestNecessary.ub.devicedata = 1;
+ − 174 }
+ − 175 getDeviceDataWasSend = 0;
+ − 176 if(dataOut.getDeviceDataNow)
+ − 177 {
+ − 178 getDeviceDataWasSend = 1;
+ − 179 }
+ − 180
+ − 181 if(setEndDiveWasSend)
+ − 182 {
+ − 183 dataOut.setEndDive = 0;
+ − 184 //requestNecessary.ub.XXX = 1; not implemented and no space here
+ − 185 }
+ − 186 setEndDiveWasSend = 0;
+ − 187 if(dataOut.setEndDive)
+ − 188 {
+ − 189 setEndDiveWasSend = 1;
+ − 190 }
+ − 191
+ − 192 if(setAccidentFlagWasSend)
+ − 193 {
+ − 194 dataOut.setAccidentFlag = 0;
+ − 195 requestNecessary.ub.accident = 1;
+ − 196 }
+ − 197 setAccidentFlagWasSend = 0;
+ − 198 if(dataOut.setAccidentFlag)
+ − 199 {
+ − 200 setAccidentFlagWasSend = 1;
+ − 201 }
+ − 202
+ − 203 if(setDateWasSend)
+ − 204 {
+ − 205 dataOut.setDateNow = 0;
+ − 206 requestNecessary.ub.date = 1;
+ − 207 }
+ − 208 setDateWasSend = 0;
+ − 209 if(dataOut.setDateNow)
+ − 210 {
+ − 211 setDateWasSend = 1;
+ − 212 }
+ − 213
+ − 214 if(setTimeWasSend)
+ − 215 {
+ − 216 dataOut.setTimeNow = 0;
+ − 217 requestNecessary.ub.time = 1;
+ − 218 }
+ − 219 setTimeWasSend = 0;
+ − 220 if(dataOut.setTimeNow)
+ − 221 {
+ − 222 setTimeWasSend = 1;
+ − 223 }
+ − 224
+ − 225 if(calibrateCompassWasSend)
+ − 226 {
+ − 227 dataOut.calibrateCompassNow = 0;
+ − 228 requestNecessary.ub.compass = 1;
+ − 229 }
+ − 230 calibrateCompassWasSend = 0;
+ − 231 if(dataOut.calibrateCompassNow)
+ − 232 {
+ − 233 calibrateCompassWasSend = 1;
+ − 234 }
+ − 235
+ − 236 if(clearDecoWasSend)
+ − 237 {
+ − 238 dataOut.clearDecoNow = 0;
+ − 239 requestNecessary.ub.clearDeco = 1;
+ − 240 }
+ − 241 if(dataOut.clearDecoNow)
+ − 242 {
+ − 243 clearDecoWasSend = 1;
+ − 244 }
+ − 245
+ − 246 if(setButtonSensitivityWasSend)
+ − 247 {
+ − 248 dataOut.setButtonSensitivityNow = 0;
+ − 249 requestNecessary.ub.button = 1;
+ − 250 }
+ − 251 setButtonSensitivityWasSend = 0;
+ − 252 if(dataOut.setButtonSensitivityNow)
+ − 253 {
+ − 254 setButtonSensitivityWasSend = 1;
+ − 255 }
+ − 256 }
+ − 257
+ − 258
+ − 259 uint8_t DataEX_call(void)
+ − 260 {
208
+ − 261 static uint32_t RTEOfflineCnt = 0;
+ − 262 static uint8_t SusppressCom = 0;
+ − 263
38
+ − 264 uint8_t SPI_DMA_answer = 0;
141
+ − 265
208
+ − 266 if(SusppressCom)
38
+ − 267 {
208
+ − 268 SusppressCom--;
38
+ − 269 }
149
+ − 270 else
+ − 271 {
208
+ − 272 if(data_old__lost_connection_to_slave_counter_temp >= 2) /* error reaction is triggered whenever communication could not be reestablishen within two cycles */
+ − 273 {
+ − 274 data_old__lost_connection_to_slave_counter_temp = 0;
+ − 275 if(DataEX_check_header_and_footer_shifted())
+ − 276 {
+ − 277 if(RTEOfflineCnt > 1) /* RTE restarted communication after a longer silent time => restart error handling to recover */
+ − 278 {
+ − 279 data_old__lost_connection_to_slave_counter_retry = 0;
+ − 280 RTEOfflineCnt = 0;
+ − 281 }
38
+ − 282
208
+ − 283 /* We received shifted data. Step one. Reset DMA to see if the problem is located at main */
+ − 284 if (data_old__lost_connection_to_slave_counter_retry == 0)
+ − 285 {
+ − 286 HAL_SPI_Abort_IT(&cpu2DmaSpi);
+ − 287 }
+ − 288 /* reset of own DMA does not work ==> request reset of slave dma by indicating shifted receiption */
+ − 289 if (data_old__lost_connection_to_slave_counter_retry == 1)
+ − 290 {
+ − 291 dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_SHIFTED;
+ − 292 }
+ − 293
+ − 294 /* stop communication with RTE to trigger RTE timeout reaction */
+ − 295 if (data_old__lost_connection_to_slave_counter_retry == 2)
+ − 296 {
+ − 297 SusppressCom = 3;
+ − 298 }
38
+ − 299
208
+ − 300 data_old__lost_connection_to_slave_counter_retry++;
+ − 301 }
+ − 302 else
+ − 303 {
+ − 304 RTEOfflineCnt++; /* based on footer status the RTE does not seem to provide data in time */
+ − 305 dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OFFLINE;
+ − 306 }
+ − 307 }
+ − 308 #if USE_OLD_SYNC_METHOD
+ − 309 /* one cycle with NotChipSelect true to clear slave spi buffer */
+ − 310 else
+ − 311 {
+ − 312 HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+ − 313 }
+ − 314 #endif
133
+ − 315
208
+ − 316 DataEx_call_helper_requests();
+ − 317
+ − 318 //HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_RESET); /* only for testing with Oscilloscope */
+ − 319
+ − 320 if(SusppressCom == 0)
+ − 321 {
+ − 322 HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+ − 323
+ − 324 SPI_DMA_answer = HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)&dataOut, (uint8_t *)&dataIn, EXCHANGE_BUFFERSIZE);
+ − 325 if(SPI_DMA_answer != HAL_OK)
+ − 326 {
+ − 327 DataEX_Error_Handler(SPI_DMA_answer);
+ − 328 }
+ − 329 }
+ − 330 }
104
+ − 331 // HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_SET);
38
+ − 332 //HAL_Delay(3);
+ − 333 //HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_SET); /* only for testing with Oscilloscope */
+ − 334
+ − 335 return 1;
+ − 336 }
+ − 337
82
+ − 338
198
+ − 339 static uint32_t SPI_CALLBACKS;
82
+ − 340 uint32_t get_num_SPI_CALLBACKS(void){
+ − 341 return SPI_CALLBACKS;
+ − 342 }
+ − 343
+ − 344 SDataExchangeSlaveToMaster* get_dataInPointer(void){
+ − 345 return &dataIn;
+ − 346 }
+ − 347
+ − 348 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
+ − 349 {
+ − 350 if(hspi == &cpu2DmaSpi)
+ − 351 {
154
+ − 352 HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_SET);
82
+ − 353 SPI_CALLBACKS+=1;
+ − 354 }
+ − 355 }
+ − 356
+ − 357
38
+ − 358 void DateEx_copy_to_dataOut(void)
+ − 359 {
+ − 360 const SDiveState * pStateReal = stateRealGetPointer();
+ − 361 SSettings *settings = settingsGetPointer();
+ − 362
+ − 363 if(get_globalState() == StStop)
+ − 364 dataOut.mode = MODE_SHUTDOWN;
+ − 365 else
+ − 366 dataOut.mode = 0;
+ − 367
+ − 368 dataOut.diveModeInfo = pStateReal->diveSettings.diveMode; // hw 170215
+ − 369
+ − 370 memcpy(&dataOut.data.DeviceData, stateDeviceGetPointer(), sizeof(SDevice));
+ − 371
+ − 372 dataOut.data.VPMconservatism = pStateReal->diveSettings.vpm_conservatism;
+ − 373 dataOut.data.actualGas = pStateReal->lifeData.actualGas;
+ − 374 dataOut.data.ambient_pressure_mbar_ceiling = (pStateReal->decolistBuehlmann.output_ceiling_meter * 100) + (pStateReal->lifeData.pressure_surface_bar * 1000);
+ − 375 dataOut.data.divetimeToCreateLogbook = settings->divetimeToCreateLogbook;
+ − 376 dataOut.data.timeoutDiveReachedZeroDepth = settings->timeoutDiveReachedZeroDepth;
+ − 377
+ − 378 dataOut.data.offsetPressureSensor_mbar = settings->offsetPressure_mbar;
+ − 379 dataOut.data.offsetTemperatureSensor_centiDegree = settings->offsetTemperature_centigrad;
+ − 380
+ − 381 if((hardwareDataGetPointer()->primarySerial <= 32) || (((hardwareDataGetPointer()->primarySerial == 72) && (hardwareDataGetPointer()->secondarySerial == 15))))
+ − 382 {
+ − 383 dataOut.revisionHardware = 0x00;
+ − 384 dataOut.revisionCRCx0x7A = 0x7A;
+ − 385 }
+ − 386 else
+ − 387 if(hardwareDataGetPointer()->primarySerial < 0xFFFF)
+ − 388 {
+ − 389 dataOut.revisionHardware = hardwareDataGetPointer()->revision8bit;
+ − 390 dataOut.revisionCRCx0x7A = hardwareDataGetPointer()->revision8bit ^ 0x7A;
+ − 391 }
+ − 392 else
+ − 393 {
+ − 394 dataOut.revisionHardware = 0xFF;
+ − 395 dataOut.revisionCRCx0x7A = 0xFF;
+ − 396 }
+ − 397
+ − 398 if(DataEX_check_header_and_footer_ok() && !told_reset_logik_alles_ok)
+ − 399 {
+ − 400 MX_tell_reset_logik_alles_ok();
+ − 401 told_reset_logik_alles_ok = 1;
+ − 402 }
+ − 403
+ − 404 if(DataEX_check_header_and_footer_ok() && (dataIn.power_on_reset == 1))
+ − 405 {
+ − 406 if(!wasUpdateNotPowerOn)
+ − 407 wasPowerOn = 1;
+ − 408
+ − 409 settingsHelperButtonSens_keepPercentageValues(settingsGetPointerStandard()->ButtonResponsiveness[3], settings->ButtonResponsiveness);
+ − 410 setButtonResponsiveness(settings->ButtonResponsiveness);
+ − 411
+ − 412 // hw 160720 new lastKnownBatteryPercentage
+ − 413 if(!wasUpdateNotPowerOn)
+ − 414 {
+ − 415 // dataOut.data.newBatteryGaugePercentageFloat = settingsGetPointer()->lastKnownBatteryPercentage;
+ − 416 dataOut.data.newBatteryGaugePercentageFloat = 0;
+ − 417 dataOut.setBatteryGaugeNow = 1;
+ − 418 }
+ − 419 }
+ − 420 }
+ − 421
+ − 422
+ − 423 void DataEX_copy_to_deco(void)
+ − 424 {
+ − 425 if(decoLock == DECO_CALC_running)
+ − 426 return;
+ − 427
+ − 428 if(decoLock == DECO_CALC_init_as_is_start_of_dive)
+ − 429 {
288
+ − 430 vpm_init(&stateUsedWrite->vpm, stateUsedWrite->diveSettings.vpm_conservatism, 0, 0);
38
+ − 431 buehlmann_init();
+ − 432 timer_init();
288
+ − 433 resetEvents(stateUsedWrite);
+ − 434 stateUsedWrite->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0;
38
+ − 435 }
+ − 436
+ − 437 if(decoLock == DECO_CALC_FINSHED_Buehlmann)
+ − 438 {
+ − 439
+ − 440 }
+ − 441 switch(decoLock)
+ − 442 {
+ − 443
+ − 444 //Deco_calculation finished
+ − 445 case DECO_CALC_FINSHED_vpm:
288
+ − 446 memcpy(&stateUsedWrite->decolistVPM,&stateDeco.decolistVPM,sizeof(SDecoinfo));
+ − 447 stateUsedWrite->decolistVPM.tickstamp = HAL_GetTick();
+ − 448 stateUsedWrite->vpm.deco_zone_reached = stateDeco.vpm.deco_zone_reached;
38
+ − 449 for(int i = 0; i< 16; i++)
+ − 450 {
288
+ − 451 stateUsedWrite->vpm.adjusted_critical_radius_he[i] = stateDeco.vpm.adjusted_critical_radius_he[i];
+ − 452 stateUsedWrite->vpm.adjusted_critical_radius_n2[i] = stateDeco.vpm.adjusted_critical_radius_n2[i];
+ − 453 stateUsedWrite->vpm.adjusted_crushing_pressure_he[i] = stateDeco.vpm.adjusted_crushing_pressure_he[i];
+ − 454 stateUsedWrite->vpm.adjusted_crushing_pressure_n2[i] = stateDeco.vpm.adjusted_crushing_pressure_n2[i];
+ − 455 stateUsedWrite->vpm.initial_allowable_gradient_he[i] = stateDeco.vpm.initial_allowable_gradient_he[i];
+ − 456 stateUsedWrite->vpm.initial_allowable_gradient_n2[i] = stateDeco.vpm.initial_allowable_gradient_n2[i];
+ − 457 stateUsedWrite->vpm.max_actual_gradient[i] = stateDeco.vpm.max_actual_gradient[i];
38
+ − 458 }
+ − 459 break;
+ − 460 case DECO_CALC_FINSHED_Buehlmann:
288
+ − 461 memcpy(&stateUsedWrite->decolistBuehlmann,&stateDeco.decolistBuehlmann,sizeof(SDecoinfo));
+ − 462 stateUsedWrite->decolistBuehlmann.tickstamp = HAL_GetTick();
38
+ − 463 //Copy Data to be stored if regular Buehlmann, not FutureBuehlmann
288
+ − 464 stateUsedWrite->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = stateDeco.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero;
38
+ − 465 break;
+ − 466 case DECO_CALC_FINSHED_FutureBuehlmann:
288
+ − 467 memcpy(&stateUsedWrite->decolistFutureBuehlmann,&stateDeco.decolistFutureBuehlmann,sizeof(SDecoinfo));
+ − 468 stateUsedWrite->decolistFutureBuehlmann.tickstamp = HAL_GetTick();
38
+ − 469 break;
+ − 470 case DECO_CALC_FINSHED_Futurevpm:
288
+ − 471 memcpy(&stateUsedWrite->decolistFutureVPM,&stateDeco.decolistFutureVPM,sizeof(SDecoinfo));
+ − 472 stateUsedWrite->decolistFutureVPM.tickstamp = HAL_GetTick();
38
+ − 473 break;
+ − 474 }
+ − 475
+ − 476 //Copy Inputdata from stateReal to stateDeco
288
+ − 477 memcpy(&stateDeco.lifeData,&stateUsedWrite->lifeData,sizeof(SLifeData));
+ − 478 memcpy(&stateDeco.diveSettings,&stateUsedWrite->diveSettings,sizeof(SDiveSettings));
38
+ − 479
288
+ − 480 stateDeco.vpm.deco_zone_reached = stateUsedWrite->vpm.deco_zone_reached;
38
+ − 481 // memcpy(&stateDeco.vpm,&pStateUsed->vpm,sizeof(SVpm));
+ − 482 for(int i = 0; i< 16; i++)
+ − 483 {
288
+ − 484 stateDeco.vpm.max_crushing_pressure_he[i] = stateUsedWrite->vpm.max_crushing_pressure_he[i];
+ − 485 stateDeco.vpm.max_crushing_pressure_n2[i] = stateUsedWrite->vpm.max_crushing_pressure_n2[i];
+ − 486 stateDeco.vpm.adjusted_critical_radius_he[i] = stateUsedWrite->vpm.adjusted_critical_radius_he[i];
+ − 487 stateDeco.vpm.adjusted_critical_radius_n2[i] = stateUsedWrite->vpm.adjusted_critical_radius_n2[i];
38
+ − 488 }
+ − 489 decoLock = DECO_CALC_ready;
+ − 490 }
+ − 491
+ − 492
198
+ − 493 static void DataEX_helper_copy_deviceData(SDeviceLine *lineWrite, const SDeviceLine *lineRead)
38
+ − 494 {
+ − 495 lineWrite->date_rtc_dr = lineRead->date_rtc_dr;
+ − 496 lineWrite->time_rtc_tr = lineRead->time_rtc_tr;
+ − 497 lineWrite->value_int32 = lineRead->value_int32;
+ − 498 }
+ − 499
198
+ − 500 static void DataEX_helper_SetTime(RTC_TimeTypeDef inStimestructure, uint32_t *outTimetmpreg)
38
+ − 501 {
+ − 502 inStimestructure.TimeFormat = RTC_HOURFORMAT_24;
+ − 503
+ − 504 *outTimetmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(inStimestructure.Hours) << 16U) | \
+ − 505 ((uint32_t)RTC_ByteToBcd2(inStimestructure.Minutes) << 8U) | \
+ − 506 ((uint32_t)RTC_ByteToBcd2(inStimestructure.Seconds)) | \
+ − 507 (((uint32_t)inStimestructure.TimeFormat) << 16U));
+ − 508 }
+ − 509
+ − 510
198
+ − 511 static void DataEX_helper_SetDate(RTC_DateTypeDef inSdatestructure, uint32_t *outDatetmpreg)
38
+ − 512 {
+ − 513 *outDatetmpreg = (((uint32_t)RTC_ByteToBcd2(inSdatestructure.Year) << 16U) | \
+ − 514 ((uint32_t)RTC_ByteToBcd2(inSdatestructure.Month) << 8U) | \
+ − 515 ((uint32_t)RTC_ByteToBcd2(inSdatestructure.Date)) | \
+ − 516 ((uint32_t)inSdatestructure.WeekDay << 13U));
+ − 517 }
+ − 518
+ − 519
+ − 520
198
+ − 521 static void DataEX_helper_set_Unknown_Date_deviceData(SDeviceLine *lineWrite)
38
+ − 522 {
+ − 523 RTC_DateTypeDef sdatestructure;
+ − 524 RTC_TimeTypeDef stimestructure;
+ − 525
+ − 526 stimestructure.Hours = 1;
+ − 527 stimestructure.Minutes = 0;
+ − 528 stimestructure.Seconds = 0;
+ − 529
+ − 530 sdatestructure.Date = 1;
+ − 531 sdatestructure.Month = 1;
+ − 532 sdatestructure.Year = 16;
+ − 533 setWeekday(&sdatestructure);
+ − 534
+ − 535 DataEX_helper_SetTime(stimestructure, &lineWrite->time_rtc_tr);
+ − 536 DataEX_helper_SetDate(sdatestructure, &lineWrite->date_rtc_dr);
+ − 537 }
+ − 538
+ − 539
198
+ − 540 static uint8_t DataEX_helper_Check_And_Correct_Date_deviceData(SDeviceLine *lineWrite)
38
+ − 541 {
+ − 542 RTC_DateTypeDef sdatestructure;
+ − 543 RTC_TimeTypeDef stimestructure;
+ − 544
+ − 545 // from lineWrite to structure
+ − 546 translateDate(lineWrite->date_rtc_dr, &sdatestructure);
+ − 547 translateTime(lineWrite->time_rtc_tr, &stimestructure);
+ − 548
+ − 549 if( (sdatestructure.Year >= 15)
+ − 550 && (sdatestructure.Year <= 30)
+ − 551 && (sdatestructure.Month <= 12))
+ − 552 return 0;
+ − 553
+ − 554
+ − 555 DataEX_helper_set_Unknown_Date_deviceData(lineWrite);
+ − 556 return 1;
+ − 557 }
+ − 558
+ − 559
198
+ − 560 static uint8_t DataEX_helper_Check_And_Correct_Value_deviceData(SDeviceLine *lineWrite, int32_t from, int32_t to)
38
+ − 561 {
+ − 562 if(lineWrite->value_int32 >= from && lineWrite->value_int32 <= to)
+ − 563 return 0;
+ − 564
+ − 565 if(lineWrite->value_int32 < from)
+ − 566 lineWrite->value_int32 = from;
+ − 567 else
+ − 568 lineWrite->value_int32 = to;
+ − 569
+ − 570 DataEX_helper_set_Unknown_Date_deviceData(lineWrite);
+ − 571 return 0;
+ − 572 }
+ − 573
+ − 574
198
+ − 575 static void DataEX_check_DeviceData(void)
38
+ − 576 {
+ − 577 SDevice *DeviceData = stateDeviceGetPointerWrite();
+ − 578
+ − 579 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->batteryChargeCompleteCycles);
+ − 580 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->batteryChargeCycles);
+ − 581 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->depthMaximum);
+ − 582 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->diveCycles);
+ − 583 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->hoursOfOperation);
+ − 584 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->temperatureMaximum);
+ − 585 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->temperatureMinimum);
+ − 586 DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->voltageMinimum);
+ − 587
+ − 588 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->batteryChargeCompleteCycles, 0, 10000);
+ − 589 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->batteryChargeCycles, 0, 20000);
+ − 590 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->depthMaximum, 0, (500*100)+1000);
+ − 591 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->diveCycles, 0, 20000);
+ − 592 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->hoursOfOperation, 0, 1000000);
+ − 593 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->temperatureMaximum, -30*100, 150*100);
+ − 594 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->temperatureMinimum, -30*100, 150*100);
+ − 595 DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->voltageMinimum, -1*1000, 6*1000);
+ − 596 }
+ − 597
+ − 598
198
+ − 599 static void DataEX_merge_DeviceData_and_store(void)
38
+ − 600 {
+ − 601 uint16_t dataLengthRead;
+ − 602 SDevice DeviceDataFlash;
+ − 603 SDevice *DeviceData = stateDeviceGetPointerWrite();
+ − 604
+ − 605 dataLengthRead = ext_flash_read_devicedata((uint8_t *)&DeviceDataFlash,sizeof(SDevice));
+ − 606
+ − 607 if(dataLengthRead == 0)
+ − 608 {
+ − 609 ext_flash_write_devicedata();
+ − 610 return;
+ − 611 }
+ − 612
+ − 613 /* max values */
+ − 614 if(DeviceData->batteryChargeCompleteCycles.value_int32 < DeviceDataFlash.batteryChargeCompleteCycles.value_int32)
+ − 615 {
+ − 616 DataEX_helper_copy_deviceData(&DeviceData->batteryChargeCompleteCycles, &DeviceDataFlash.batteryChargeCompleteCycles);
+ − 617 }
+ − 618 if(DeviceData->batteryChargeCycles.value_int32 < DeviceDataFlash.batteryChargeCycles.value_int32)
+ − 619 {
+ − 620 DataEX_helper_copy_deviceData(&DeviceData->batteryChargeCycles, &DeviceDataFlash.batteryChargeCycles);
+ − 621 }
+ − 622 if(DeviceData->temperatureMaximum.value_int32 < DeviceDataFlash.temperatureMaximum.value_int32)
+ − 623 {
+ − 624 DataEX_helper_copy_deviceData(&DeviceData->temperatureMaximum, &DeviceDataFlash.temperatureMaximum);
+ − 625 }
+ − 626 if(DeviceData->depthMaximum.value_int32 < DeviceDataFlash.depthMaximum.value_int32)
+ − 627 {
+ − 628 DataEX_helper_copy_deviceData(&DeviceData->depthMaximum, &DeviceDataFlash.depthMaximum);
+ − 629 }
+ − 630 if(DeviceData->diveCycles.value_int32 < DeviceDataFlash.diveCycles.value_int32)
+ − 631 {
+ − 632 DataEX_helper_copy_deviceData(&DeviceData->diveCycles, &DeviceDataFlash.diveCycles);
+ − 633 }
+ − 634
+ − 635 /* min values */
+ − 636 if(DeviceData->temperatureMinimum.value_int32 > DeviceDataFlash.temperatureMinimum.value_int32)
+ − 637 {
+ − 638 DataEX_helper_copy_deviceData(&DeviceData->temperatureMinimum, &DeviceDataFlash.temperatureMinimum);
+ − 639 }
+ − 640 // Voltage minimum, keep limit to 2.0 Volt; hw 09.09.2015
+ − 641 if(DeviceData->voltageMinimum.value_int32 > DeviceDataFlash.voltageMinimum.value_int32)
+ − 642 {
+ − 643 if(DeviceDataFlash.voltageMinimum.value_int32 > 2000) // do not copy back 2000 and below
+ − 644 DataEX_helper_copy_deviceData(&DeviceData->voltageMinimum, &DeviceDataFlash.voltageMinimum);
+ − 645 }
+ − 646 if(DeviceData->voltageMinimum.value_int32 < 2000)
+ − 647 DeviceData->voltageMinimum.value_int32 = 2000;
+ − 648
+ − 649 DataEX_check_DeviceData ();
+ − 650 ext_flash_write_devicedata();
+ − 651 }
+ − 652
+ − 653
198
+ − 654 static void DataEX_copy_to_DeviceData(void)
38
+ − 655 {
+ − 656 SDataExchangeSlaveToMasterDeviceData * dataInDevice = (SDataExchangeSlaveToMasterDeviceData *)&dataIn;
+ − 657 SDevice * pDeviceState = stateDeviceGetPointerWrite();
+ − 658
+ − 659 memcpy(pDeviceState, &dataInDevice->DeviceData[dataInDevice->boolDeviceData], sizeof(SDevice));
+ − 660 }
+ − 661
+ − 662
198
+ − 663 static void DataEX_copy_to_VpmRepetitiveData(void)
38
+ − 664 {
+ − 665 SDataExchangeSlaveToMasterDeviceData * dataInDevice = (SDataExchangeSlaveToMasterDeviceData *)&dataIn;
+ − 666 SVpmRepetitiveData * pVpmState = stateVpmRepetitiveDataGetPointerWrite();
+ − 667
+ − 668 if(dataInDevice->boolVpmRepetitiveDataValid)
+ − 669 {
+ − 670 memcpy(pVpmState, &dataInDevice->VpmRepetitiveData, sizeof(SVpmRepetitiveData));
+ − 671 pVpmState->is_data_from_RTE_CPU = 1;
+ − 672 }
+ − 673 }
+ − 674
+ − 675
+ − 676 void DataEX_control_connection_while_asking_for_sleep(void)
+ − 677 {
+ − 678 if(!DataEX_check_header_and_footer_ok())
+ − 679 {
+ − 680 if(DataEX_check_header_and_footer_devicedata())
+ − 681 {
+ − 682 data_old__lost_connection_to_slave_counter_retry = 0;
+ − 683 data_old__lost_connection_to_slave_counter_temp = 0;
+ − 684 stateRealGetPointerWrite()->data_old__lost_connection_to_slave = 0;
208
+ − 685 dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
38
+ − 686 }
+ − 687 else
+ − 688 {
+ − 689 stateRealGetPointerWrite()->data_old__lost_connection_to_slave = 1;
+ − 690 data_old__lost_connection_to_slave_counter_temp += 1;
+ − 691 data_old__lost_connection_to_slave_counter_total += 1;
+ − 692 }
+ − 693 }
+ − 694 }
+ − 695
173
+ − 696 #define AVERAGE_COUNT 4
+ − 697 static float getSampleDepth(SDataExchangeSlaveToMaster *d, SDiveState *ds)
+ − 698 {
+ − 699 static uint8_t c = 0;
+ − 700 static float ambient[AVERAGE_COUNT] = {0};
+ − 701 static float surface[AVERAGE_COUNT]= {0};
+ − 702 static float depth[AVERAGE_COUNT]= {0};
+ − 703
+ − 704 ambient[c] = d->data[d->boolPressureData].pressure_mbar / 1000.0f;
+ − 705 surface[c] = d->data[d->boolPressureData].surface_mbar / 1000.0f;
+ − 706 float density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f;
+ − 707
+ − 708 ds->lifeData.pressure_ambient_bar = (ambient[0] + ambient[1] + ambient[2] + ambient[3])/4.0f;
+ − 709 ds->lifeData.pressure_surface_bar = (surface[0] + surface[1] + surface[2] + surface[3])/4.0f;
+ − 710 depth[c] = (ambient[c] - surface[c]) / (0.09807f * density);
+ − 711
+ − 712 c++;
+ − 713 if (c == AVERAGE_COUNT) c = 0;
+ − 714
+ − 715 return (depth[0] + depth[1] + depth[2] + depth[3])/4.0f;
+ − 716 }
38
+ − 717
189
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 718 #define TEMP_AVERAGE_COUNT 3
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 719 static float getTemperature(SDataExchangeSlaveToMaster *d)
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 720 {
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 721 static uint8_t c = 0;
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 722 static float temp[TEMP_AVERAGE_COUNT] = {0};
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 723
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 724 temp[c] = d->data[d->boolPressureData].temperature;
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 725
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 726 c++;
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 727 if (c == TEMP_AVERAGE_COUNT) c = 0;
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 728
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 729 return (temp[0] + temp[1] + temp[2])/3.0f;
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 730 }
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 731
38
+ − 732 void DataEX_copy_to_LifeData(_Bool *modeChangeFlag)
+ − 733 {
173
+ − 734 SDiveState *pStateReal = stateRealGetPointerWrite();
38
+ − 735 static uint16_t getDeviceDataAfterStartOfMainCPU = 20;
+ − 736
+ − 737 /* internal sensor: HUD data
+ − 738 */
+ − 739 for(int i=0;i<3;i++)
+ − 740 {
+ − 741 pStateReal->lifeData.ppO2Sensor_bar[i] = get_ppO2Sensor_bar(i);
+ − 742 pStateReal->lifeData.sensorVoltage_mV[i] = get_sensorVoltage_mV(i);
+ − 743 }
+ − 744 pStateReal->lifeData.HUD_battery_voltage_V = get_HUD_battery_voltage_V();
+ − 745
+ − 746
+ − 747 // wireless - �ltere daten aufr�umen
51
+ − 748 for(int i=0;i<(2*NUM_GASES+1);i++)
38
+ − 749 {
+ − 750 if(pStateReal->lifeData.bottle_bar[i])
+ − 751 {
+ − 752 if((pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] == 0) || (pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] > 60000))
+ − 753 {
+ − 754 pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] = 0;
+ − 755 pStateReal->lifeData.bottle_bar[i] = 0;
+ − 756 }
+ − 757 else
+ − 758 pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] += 100;
+ − 759 }
+ − 760 }
+ − 761
+ − 762 if(!DataEX_check_header_and_footer_ok())
+ − 763 {
+ − 764 if(DataEX_check_header_and_footer_devicedata())
+ − 765 {
+ − 766 DataEX_copy_to_DeviceData();
+ − 767 DataEX_merge_DeviceData_and_store();
+ − 768 DataEX_copy_to_VpmRepetitiveData();
+ − 769 data_old__lost_connection_to_slave_counter_temp = 0;
+ − 770 data_old__lost_connection_to_slave_counter_retry = 0;
275
+ − 771 /* Do not yet reset state. Wait till common data has been received in next cycle. Otherwise invalid data may be forwarded for processing */
+ − 772 /* pStateReal->data_old__lost_connection_to_slave = 0; */
208
+ − 773 dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
38
+ − 774 }
+ − 775 else
+ − 776 {
+ − 777 pStateReal->data_old__lost_connection_to_slave = 1;
+ − 778 data_old__lost_connection_to_slave_counter_temp += 1;
+ − 779 data_old__lost_connection_to_slave_counter_total += 1;
+ − 780 }
+ − 781 return;
+ − 782 }
141
+ − 783 else /* RX data OK */
+ − 784 {
+ − 785 data_old__lost_connection_to_slave_counter_temp = 0;
+ − 786 data_old__lost_connection_to_slave_counter_retry = 0;
+ − 787 pStateReal->data_old__lost_connection_to_slave = 0;
208
+ − 788 dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
141
+ − 789 }
38
+ − 790
+ − 791 if(getDeviceDataAfterStartOfMainCPU)
+ − 792 {
+ − 793 getDeviceDataAfterStartOfMainCPU--;
+ − 794 if(getDeviceDataAfterStartOfMainCPU == 0)
+ − 795 {
+ − 796 dataOut.getDeviceDataNow = 1;
141
+ − 797 getDeviceDataAfterStartOfMainCPU = 10*60*10; /* * 100ms = 60 second => update device data every 10 minutes */
38
+ − 798 }
+ − 799 }
+ − 800
+ − 801 /* new 151207 hw */
+ − 802 if(requestNecessary.uw != 0)
+ − 803 {
+ − 804 if(((dataIn.confirmRequest.uw) & CRBUTTON) != 0)
+ − 805 {
+ − 806 requestNecessary.ub.button = 0;
+ − 807 }
+ − 808
+ − 809 if(requestNecessary.ub.button == 1)
+ − 810 {
+ − 811 setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness);
+ − 812 }
+ − 813 }
+ − 814 requestNecessary.uw = 0; // clear all
+ − 815
173
+ − 816 float meter = 0;
38
+ − 817 SSettings *pSettings;
149
+ − 818
38
+ − 819 /* uint8_t IAmStolenPleaseKillMe;
+ − 820 */
51
+ − 821 pSettings = settingsGetPointer();
+ − 822
+ − 823 if(pSettings->IAmStolenPleaseKillMe > 3)
38
+ − 824 {
+ − 825 pSettings->salinity = 0;
+ − 826 dataIn.data[dataIn.boolPressureData].surface_mbar = 999;
+ − 827 dataIn.data[dataIn.boolPressureData].pressure_mbar = 98971;
+ − 828 dataIn.mode = MODE_DIVE;
+ − 829 }
+ − 830
137
+ − 831 if(pStateReal->data_old__lost_connection_to_slave == 0)
+ − 832 {
173
+ − 833 meter = getSampleDepth(&dataIn, pStateReal);
38
+ − 834
137
+ − 835 pStateReal->pressure_uTick_old = pStateReal->pressure_uTick_new;
+ − 836 pStateReal->pressure_uTick_new = dataIn.data[dataIn.boolPressureData].pressure_uTick;
+ − 837 pStateReal->pressure_uTick_local_new = HAL_GetTick();
38
+ − 838
137
+ − 839 pStateReal->lifeData.dateBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_dr;
+ − 840 pStateReal->lifeData.timeBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_tr;
+ − 841 }
38
+ − 842 dataOut.setAccidentFlag = 0;
+ − 843
141
+ − 844 if(pStateReal->data_old__lost_connection_to_slave == 0)
38
+ − 845 {
141
+ − 846 //Start of diveMode?
+ − 847 if(pStateReal->mode != MODE_DIVE && dataIn.mode == MODE_DIVE)
+ − 848 {
+ − 849 if(modeChangeFlag)
+ − 850 {
+ − 851 *modeChangeFlag = 1;
+ − 852 }
+ − 853 if(stateUsed == stateSimGetPointer())
38
+ − 854 {
+ − 855 simulation_exit();
+ − 856 }
141
+ − 857 // new 170508
38
+ − 858 settingsGetPointer()->bluetoothActive = 0;
+ − 859 MX_Bluetooth_PowerOff();
+ − 860 //Init dive Mode
141
+ − 861 decoLock = DECO_CALC_init_as_is_start_of_dive;
+ − 862 pStateReal->lifeData.boolResetAverageDepth = 1;
+ − 863 pStateReal->lifeData.boolResetStopwatch = 1;
38
+ − 864 }
141
+ − 865
197
+ − 866 pStateReal->lifeData.cns = dataIn.data[dataIn.boolToxicData].cns;
+ − 867 pStateReal->lifeData.otu = dataIn.data[dataIn.boolToxicData].otu;
+ − 868 pStateReal->lifeData.no_fly_time_minutes = dataIn.data[dataIn.boolToxicData].no_fly_time_minutes;
+ − 869 pStateReal->lifeData.desaturation_time_minutes = dataIn.data[dataIn.boolToxicData].desaturation_time_minutes;
+ − 870
141
+ − 871 //End of diveMode?
+ − 872 if(pStateReal->mode == MODE_DIVE && dataIn.mode != MODE_DIVE)
+ − 873 {
+ − 874 if(modeChangeFlag)
+ − 875 {
+ − 876 *modeChangeFlag = 1;
+ − 877 }
+ − 878 createDiveSettings();
38
+ − 879
141
+ − 880 if(pStateReal->warnings.cnsHigh)
+ − 881 {
+ − 882 if(pStateReal->lifeData.cns >= 130)
+ − 883 dataOut.setAccidentFlag += ACCIDENT_CNSLVL2;
+ − 884 else if(pStateReal->lifeData.cns >= 100)
+ − 885 dataOut.setAccidentFlag += ACCIDENT_CNS;
+ − 886 }
+ − 887 if(pStateReal->warnings.decoMissed)
+ − 888 dataOut.setAccidentFlag += ACCIDENT_DECOSTOP;
+ − 889 }
+ − 890 pStateReal->mode = dataIn.mode;
+ − 891 pStateReal->chargeStatus = dataIn.chargeStatus;
137
+ − 892
141
+ − 893 if(is_ambient_pressure_close_to_surface(&pStateReal->lifeData))
+ − 894 {
+ − 895 pStateReal->lifeData.depth_meter = 0;
+ − 896 }
+ − 897 else
+ − 898 {
+ − 899 pStateReal->lifeData.depth_meter = meter;
+ − 900 }
+ − 901
189
8b8074080d7b
Bugfix: average temperature on arrival from RTE instead of display time
Jan Mulder <jlmulder@xs4all.nl>
diff
changeset
+ − 902 pStateReal->lifeData.temperature_celsius = getTemperature(&dataIn);
137
+ − 903 pStateReal->lifeData.ascent_rate_meter_per_min = dataIn.data[dataIn.boolPressureData].ascent_rate_meter_per_min;
+ − 904 if(pStateReal->mode != MODE_DIVE)
+ − 905 pStateReal->lifeData.max_depth_meter = 0;
+ − 906 else
+ − 907 {
+ − 908 if(meter > pStateReal->lifeData.max_depth_meter)
+ − 909 pStateReal->lifeData.max_depth_meter = meter;
+ − 910 }
38
+ − 911
137
+ − 912 if(dataIn.accidentFlags & ACCIDENT_DECOSTOP)
+ − 913 pStateReal->decoMissed_at_the_end_of_dive = 1;
+ − 914 if(dataIn.accidentFlags & ACCIDENT_CNS)
+ − 915 pStateReal->cnsHigh_at_the_end_of_dive = 1;
+ − 916
+ − 917 pStateReal->lifeData.dive_time_seconds = (int32_t)dataIn.data[dataIn.boolTimeData].divetime_seconds;
+ − 918 pStateReal->lifeData.dive_time_seconds_without_surface_time = (int32_t)dataIn.data[dataIn.boolTimeData].dive_time_seconds_without_surface_time;
+ − 919 pStateReal->lifeData.counterSecondsShallowDepth = dataIn.data[dataIn.boolTimeData].counterSecondsShallowDepth;
+ − 920 pStateReal->lifeData.surface_time_seconds = (int32_t)dataIn.data[dataIn.boolTimeData].surfacetime_seconds;
38
+ − 921
137
+ − 922 pStateReal->lifeData.compass_heading = dataIn.data[dataIn.boolCompassData].compass_heading;
+ − 923 if(settingsGetPointer()->FlipDisplay) /* consider that diver is targeting into the opposite direction */
+ − 924 {
+ − 925 pStateReal->lifeData.compass_heading -= 180.0;
+ − 926 if (pStateReal->lifeData.compass_heading < 0) pStateReal->lifeData.compass_heading +=360.0;
+ − 927 }
109
+ − 928
137
+ − 929 pStateReal->lifeData.compass_roll = dataIn.data[dataIn.boolCompassData].compass_roll;
+ − 930 pStateReal->lifeData.compass_pitch = dataIn.data[dataIn.boolCompassData].compass_pitch;
38
+ − 931
137
+ − 932 pStateReal->lifeData.compass_DX_f = dataIn.data[dataIn.boolCompassData].compass_DX_f;
+ − 933 pStateReal->lifeData.compass_DY_f = dataIn.data[dataIn.boolCompassData].compass_DY_f;
+ − 934 pStateReal->lifeData.compass_DZ_f = dataIn.data[dataIn.boolCompassData].compass_DZ_f;
38
+ − 935
137
+ − 936 pStateReal->compass_uTick_old = pStateReal->compass_uTick_new;
+ − 937 pStateReal->compass_uTick_new = dataIn.data[dataIn.boolCompassData].compass_uTick;
+ − 938 pStateReal->compass_uTick_local_new = HAL_GetTick();
+ − 939
+ − 940 memcpy(pStateReal->lifeData.tissue_nitrogen_bar, dataIn.data[dataIn.boolTisssueData].tissue_nitrogen_bar,sizeof(pStateReal->lifeData.tissue_nitrogen_bar));
+ − 941 memcpy(pStateReal->lifeData.tissue_helium_bar, dataIn.data[dataIn.boolTisssueData].tissue_helium_bar,sizeof(pStateReal->lifeData.tissue_helium_bar));
+ − 942
+ − 943 if(pStateReal->mode == MODE_DIVE)
38
+ − 944 {
137
+ − 945 for(int i= 0; i <16; i++)
+ − 946 {
+ − 947 pStateReal->vpm.max_crushing_pressure_he[i] = dataIn.data[dataIn.boolCrushingData].max_crushing_pressure_he[i];
+ − 948 pStateReal->vpm.max_crushing_pressure_n2[i] = dataIn.data[dataIn.boolCrushingData].max_crushing_pressure_n2[i];
+ − 949 pStateReal->vpm.adjusted_critical_radius_he[i] = dataIn.data[dataIn.boolCrushingData].adjusted_critical_radius_he[i];
+ − 950 pStateReal->vpm.adjusted_critical_radius_n2[i] = dataIn.data[dataIn.boolCrushingData].adjusted_critical_radius_n2[i];
+ − 951 }
38
+ − 952 }
+ − 953
137
+ − 954 /* battery and ambient light sensors
+ − 955 */
+ − 956 pStateReal->lifeData.ambient_light_level = dataIn.data[dataIn.boolAmbientLightData].ambient_light_level;
+ − 957 pStateReal->lifeData.battery_charge = dataIn.data[dataIn.boolBatteryData].battery_charge;
+ − 958 pStateReal->lifeData.battery_voltage = dataIn.data[dataIn.boolBatteryData].battery_voltage;
275
+ − 959
+ − 960 /* PIC data
+ − 961 */
+ − 962 for(int i=0;i<4;i++)
+ − 963 {
+ − 964 pStateReal->lifeData.buttonPICdata[i] = dataIn.data[dataIn.boolPICdata].button_setting[i];
+ − 965 }
+ − 966
+ − 967 /* sensorErrors
+ − 968 */
+ − 969 pStateReal->sensorErrorsRTE = dataIn.sensorErrors;
137
+ − 970 }
38
+ − 971
+ − 972 /* apnea specials
+ − 973 */
+ − 974 if(pStateReal->diveSettings.diveMode == DIVEMODE_Apnea)
+ − 975 {
+ − 976 if(pStateReal->mode != MODE_DIVE)
+ − 977 {
+ − 978 pStateReal->lifeData.apnea_total_max_depth_meter = 0;
+ − 979 pStateReal->lifeData.apnea_last_dive_time_seconds = 0;
+ − 980 pStateReal->lifeData.apnea_last_max_depth_meter = 0;
+ − 981 }
+ − 982 else
+ − 983 {
+ − 984 if(pStateReal->lifeData.max_depth_meter > pStateReal->lifeData.apnea_total_max_depth_meter)
+ − 985 pStateReal->lifeData.apnea_total_max_depth_meter = pStateReal->lifeData.max_depth_meter;
+ − 986 }
+ − 987
+ − 988 if(pStateReal->lifeData.dive_time_seconds > 15)
+ − 989 {
+ − 990 pStateReal->lifeData.apnea_last_dive_time_seconds = pStateReal->lifeData.dive_time_seconds;
+ − 991 }
+ − 992
+ − 993 if(pStateReal->lifeData.counterSecondsShallowDepth)
+ − 994 {
+ − 995 if(pStateReal->lifeData.max_depth_meter > 1.5f)
+ − 996 {
+ − 997 pStateReal->lifeData.apnea_last_max_depth_meter = pStateReal->lifeData.max_depth_meter;
+ − 998 }
173
+ − 999 // reset max_depth_meter, average_depth_meter and internal values
38
+ − 1000 pStateReal->lifeData.max_depth_meter = 0;
+ − 1001 pStateReal->lifeData.boolResetAverageDepth = 1;
+ − 1002 pStateReal->lifeData.boolResetStopwatch = 1;
+ − 1003 }
+ − 1004 }
+ − 1005
+ − 1006 /* average depth
+ − 1007 */
+ − 1008 float *AvgDepthValue = &pStateReal->lifeData.average_depth_meter;
+ − 1009 float DepthNow = pStateReal->lifeData.depth_meter;
+ − 1010 uint32_t *AvgDepthCount = &pStateReal->lifeData.internal.average_depth_meter_Count;
+ − 1011 uint32_t *AvgDepthTimer = &pStateReal->lifeData.internal.average_depth_last_update_dive_time_seconds_without_surface_time;
+ − 1012 uint32_t AvgSecondsSinceLast;
+ − 1013 uint32_t DiveTime = pStateReal->lifeData.dive_time_seconds_without_surface_time;
+ − 1014
+ − 1015 if(pStateReal->lifeData.boolResetAverageDepth)
+ − 1016 {
+ − 1017 *AvgDepthValue = DepthNow;
+ − 1018 *AvgDepthCount = 1;
+ − 1019 *AvgDepthTimer = DiveTime;
+ − 1020 pStateReal->lifeData.boolResetAverageDepth = 0;
+ − 1021 }
+ − 1022 else if (DiveTime > *AvgDepthTimer)
+ − 1023 {
+ − 1024 AvgSecondsSinceLast = DiveTime - *AvgDepthTimer;
+ − 1025 for(int i=0;i<AvgSecondsSinceLast;i++)
+ − 1026 {
+ − 1027 *AvgDepthValue = (*AvgDepthValue * *AvgDepthCount + DepthNow) / (*AvgDepthCount + 1);
+ − 1028 *AvgDepthCount += 1;
+ − 1029 }
+ − 1030 *AvgDepthTimer = DiveTime;
+ − 1031 }
+ − 1032 if(*AvgDepthCount == 0)
+ − 1033 *AvgDepthValue = 0;
+ − 1034
+ − 1035
+ − 1036 /* stop watch
+ − 1037 */
+ − 1038 if(pStateReal->lifeData.boolResetStopwatch)
+ − 1039 {
+ − 1040 pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds = pStateReal->lifeData.dive_time_seconds;
+ − 1041 pStateReal->lifeData.boolResetStopwatch = 0;
+ − 1042 }
+ − 1043 pStateReal->lifeData.stopwatch_seconds = pStateReal->lifeData.dive_time_seconds - pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds;
+ − 1044 }
+ − 1045
+ − 1046
+ − 1047 uint8_t DataEX_check_RTE_version__needs_update(void)
+ − 1048 {
+ − 1049 if(data_old__lost_connection_to_slave_counter_retry > 10)
+ − 1050 return 1;
+ − 1051 else
+ − 1052 {
+ − 1053 if(stateRealGetPointer()->data_old__lost_connection_to_slave == 0)
+ − 1054 {
+ − 1055 setActualRTEversion(dataIn.RTE_VERSION_high, dataIn.RTE_VERSION_low);
+ − 1056
+ − 1057 if(RTEminimum_required_high() < dataIn.RTE_VERSION_high)
+ − 1058 return 0;
+ − 1059 else
+ − 1060 if((RTEminimum_required_high() == dataIn.RTE_VERSION_high) && (RTEminimum_required_low() <= dataIn.RTE_VERSION_low))
+ − 1061 return 0;
+ − 1062 else
+ − 1063 return 1;
+ − 1064 }
+ − 1065 else
+ − 1066 return 0;
+ − 1067 }
+ − 1068 }
+ − 1069
+ − 1070
+ − 1071 /* Private functions ---------------------------------------------------------*/
+ − 1072
198
+ − 1073 /* Check if there is an empty frame provided by RTE (all 0) or even no data provided by RTE (all 0xFF)
137
+ − 1074 * If that is not the case the DMA is somehow not in sync
+ − 1075 */
198
+ − 1076 static uint8_t DataEX_check_header_and_footer_shifted()
137
+ − 1077 {
+ − 1078 uint8_t ret = 1;
141
+ − 1079 if((dataIn.footer.checkCode[0] == 0x00)
+ − 1080 && (dataIn.footer.checkCode[1] == 0x00)
+ − 1081 && (dataIn.footer.checkCode[2] == 0x00)
+ − 1082 && (dataIn.footer.checkCode[3] == 0x00)) { ret = 0; }
137
+ − 1083
141
+ − 1084 if((dataIn.footer.checkCode[0] == 0xff)
+ − 1085 && (dataIn.footer.checkCode[1] == 0xff)
+ − 1086 && (dataIn.footer.checkCode[2] == 0xff)
+ − 1087 && (dataIn.footer.checkCode[3] == 0xff)) { ret = 0; }
137
+ − 1088
+ − 1089 return ret;
+ − 1090 }
+ − 1091
198
+ − 1092 static uint8_t DataEX_check_header_and_footer_ok(void)
38
+ − 1093 {
+ − 1094 if(dataIn.header.checkCode[0] != 0xA1)
+ − 1095 return 0;
141
+ − 1096 #if USE_OLD_HEADER_FORMAT
38
+ − 1097 if(dataIn.header.checkCode[1] != 0xA2)
+ − 1098 return 0;
+ − 1099 if(dataIn.header.checkCode[2] != 0xA3)
+ − 1100 return 0;
141
+ − 1101 #endif
38
+ − 1102 if(dataIn.header.checkCode[3] != 0xA4)
+ − 1103 return 0;
+ − 1104 if(dataIn.footer.checkCode[0] != 0xE1)
+ − 1105 return 0;
+ − 1106 if(dataIn.footer.checkCode[1] != 0xE2)
+ − 1107 return 0;
+ − 1108 if(dataIn.footer.checkCode[2] != 0xE3)
+ − 1109 return 0;
+ − 1110 if(dataIn.footer.checkCode[3] != 0xE4)
+ − 1111 return 0;
+ − 1112
+ − 1113 return 1;
+ − 1114 }
+ − 1115
198
+ − 1116 static uint8_t DataEX_check_header_and_footer_devicedata(void)
38
+ − 1117 {
+ − 1118 if(dataIn.header.checkCode[0] != 0xDF)
+ − 1119 return 0;
+ − 1120 if(dataIn.header.checkCode[1] != 0xDE)
+ − 1121 return 0;
+ − 1122 if(dataIn.header.checkCode[2] != 0xDD)
+ − 1123 return 0;
+ − 1124 if(dataIn.header.checkCode[3] != 0xDC)
+ − 1125 return 0;
+ − 1126 if(dataIn.footer.checkCode[0] != 0xE1)
+ − 1127 return 0;
+ − 1128 if(dataIn.footer.checkCode[1] != 0xE2)
+ − 1129 return 0;
+ − 1130 if(dataIn.footer.checkCode[2] != 0xE3)
+ − 1131 return 0;
+ − 1132 if(dataIn.footer.checkCode[3] != 0xE4)
+ − 1133 return 0;
+ − 1134
+ − 1135 return 1;
+ − 1136 }