comparison Discovery/Src/logbook.c @ 1014:8c0134a287da GasConsumption

Add a log data event to the scrubber timer at the start of the dive and every time the timer (in minutes) is decremented. The event contains a 12 bit signed integer for the remaining scrubber duration, and two flags for scrubber warning (0x2000, <= 30 minutes remaining) and scrubber error (0x4000, <= 0 minutes remaining). (mikeller)
author heinrichsweikamp
date Sun, 11 May 2025 16:18:20 +0200
parents d9290c76b840
children b0d3e8b84966
comparison
equal deleted inserted replaced
1013:fa1af49319e5 1014:8c0134a287da
65 #define LOGBOOK_VERSION_OSTC3 (0x24) 65 #define LOGBOOK_VERSION_OSTC3 (0x24)
66 66
67 #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */ 67 #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */
68 #define DUMMY_SAMPLES (1000) /* Maximum number of samples profided by a dummy dive profile */ 68 #define DUMMY_SAMPLES (1000) /* Maximum number of samples profided by a dummy dive profile */
69 69
70 #define SCRUBBER_ERROR_FLAG 0x4000
71 #define SCRUBBER_WARNING_FLAG 0x2000
72
70 typedef struct /* don't forget to adjust void clear_divisor(void) */ 73 typedef struct /* don't forget to adjust void clear_divisor(void) */
71 { 74 {
72 uint8_t temperature; 75 uint8_t temperature;
73 uint8_t deco_ndl; 76 uint8_t deco_ndl;
74 uint8_t gradientFactor; 77 uint8_t gradientFactor;
465 } 468 }
466 if (state->events.gnssPositionUpdate) { 469 if (state->events.gnssPositionUpdate) {
467 eventByte1.ub.bit7 = 1; 470 eventByte1.ub.bit7 = 1;
468 eventByte2.ub.bit2 = 1; 471 eventByte2.ub.bit2 = 1;
469 } 472 }
473 if (state->events.scrubberState) {
474 eventByte1.ub.bit7 = 1;
475 eventByte2.ub.bit3 = 1;
476 }
470 477
471 //Add EventByte 1 478 //Add EventByte 1
472 if(eventByte1.uw > 0) 479 if(eventByte1.uw > 0)
473 { 480 {
474 sample[length] = eventByte1.uw; 481 sample[length] = eventByte1.uw;
508 sample[length] = state->events.info_bailoutHe; 515 sample[length] = state->events.info_bailoutHe;
509 length += 1; 516 length += 1;
510 } 517 }
511 if (state->events.compassHeadingUpdate) { 518 if (state->events.compassHeadingUpdate) {
512 // New heading and type of heading 519 // New heading and type of heading
513 sample[length++] = state->events.info_compassHeadingUpdate & 0xFF; 520 pdata = (uint8_t*)&state->events.info_compassHeadingUpdate;
514 sample[length++] = (state->events.info_compassHeadingUpdate & 0xFF00) >> 8; 521 sample[length++] = *pdata++;
522 sample[length++] = *pdata++;
515 } 523 }
516 if (state->events.gnssPositionUpdate) { 524 if (state->events.gnssPositionUpdate) {
517 pdata = (uint8_t*)&state->events.info_gnssPosition.fLon; 525 pdata = (uint8_t*)&state->events.info_gnssPosition.fLon;
518 sample[length++] = *pdata++; 526 sample[length++] = *pdata++;
519 sample[length++] = *pdata++; 527 sample[length++] = *pdata++;
520 sample[length++] = *pdata++; 528 sample[length++] = *pdata++;
521 sample[length++] = *pdata++; 529 sample[length++] = *pdata++;
522 pdata = (uint8_t*)&state->events.info_gnssPosition.fLat; 530 pdata = (uint8_t*)&state->events.info_gnssPosition.fLat;
523 sample[length++] = *pdata++; 531 sample[length++] = *pdata++;
524 sample[length++] = *pdata++; 532 sample[length++] = *pdata++;
533 sample[length++] = *pdata++;
534 sample[length++] = *pdata++;
535 }
536 if (state->events.scrubberState) {
537 pdata = (uint8_t*)&state->events.info_scrubberState;
525 sample[length++] = *pdata++; 538 sample[length++] = *pdata++;
526 sample[length++] = *pdata++; 539 sample[length++] = *pdata++;
527 } 540 }
528 541
529 if(divisor.temperature == 0) 542 if(divisor.temperature == 0)
1319 { 1332 {
1320 if((pStateReal->mode == MODE_DIVE) && (pStateReal->diveSettings.diveMode != DIVEMODE_Apnea) && (pStateReal->lifeData.dive_time_seconds >= 5)) 1333 if((pStateReal->mode == MODE_DIVE) && (pStateReal->diveSettings.diveMode != DIVEMODE_Apnea) && (pStateReal->lifeData.dive_time_seconds >= 5))
1321 { 1334 {
1322 //InitdiveProfile 1335 //InitdiveProfile
1323 pSettings->totalDiveCounter++; 1336 pSettings->totalDiveCounter++;
1324 logbook_initNewdiveProfile(pStateReal,settingsGetPointer()); 1337 logbook_initNewdiveProfile(pStateReal, pSettings);
1325 min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius; 1338 min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius;
1339 if (isScrubberTimerRunning(pStateReal, pSettings)) {
1340 int16_t maxScrubberTime = INT16_MIN;
1341 SScrubberData *longestScrubberData = NULL;
1342 for (unsigned timerId = 0; timerId < 2; timerId++) {
1343 if (pSettings->scrubberActiveId & (1 << timerId)) {
1344 SScrubberData *scrubberData = &pStateReal->scrubberDataDive[timerId];
1345 if (scrubberData->TimerCur > maxScrubberTime) {
1346 maxScrubberTime = scrubberData->TimerCur;
1347 longestScrubberData = scrubberData;
1348 }
1349 }
1350 }
1351
1352 logScrubberState(longestScrubberData);
1353 }
1326 1354
1327 //Write logbook sample 1355 //Write logbook sample
1328 logbook_writeSample(pStateReal); 1356 logbook_writeSample(pStateReal);
1329 resetEvents(pStateReal); 1357 resetEvents(pStateReal);
1330 tickstart = HAL_GetTick(); 1358 tickstart = HAL_GetTick();
2144 { 2172 {
2145 memcpy(pTarget,&dummyMemoryBuffer[dummyReadIdx],length); 2173 memcpy(pTarget,&dummyMemoryBuffer[dummyReadIdx],length);
2146 dummyReadIdx += length; 2174 dummyReadIdx += length;
2147 } 2175 }
2148 2176
2177 void logScrubberState(const SScrubberData *scrubberData)
2178 {
2179 uint16_t scrubberState = scrubberData->TimerCur & 0x0FFF; // truncate to 12 bit
2180 if (isScrubberError(scrubberData)) {
2181 scrubberState |= SCRUBBER_ERROR_FLAG;
2182 }
2183
2184 if (isScrubberWarning(scrubberData)) {
2185 scrubberState |= SCRUBBER_WARNING_FLAG;
2186 }
2187
2188 stateUsedWrite->events.scrubberState = 1;
2189 stateUsedWrite->events.info_scrubberState = scrubberState;
2190 }
2149 2191
2150 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ 2192 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/