Mercurial > public > ostc4
changeset 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 (3 months ago) |
parents | fa1af49319e5 |
children | 5924a2d1d3ba |
files | Common/Drivers/CMSIS/Include/cmsis_gcc.h Common/Inc/data_central.h Common/Inc/settings.h Discovery/Inc/logbook.h Discovery/Inc/t3.h Discovery/Src/data_exchange_main.c Discovery/Src/logbook.c Discovery/Src/settings.c Discovery/Src/simulation.c Discovery/Src/t3.c Discovery/Src/t7.c Discovery/Src/tCCR.c Discovery/Src/tMenuCvOption.c Discovery/Src/tMenuEditCvOption.c Discovery/Src/tMenuEditPlanner.c Discovery/Src/tMenuEditXtra.c |
diffstat | 16 files changed, 252 insertions(+), 194 deletions(-) [+] |
line wrap: on
line diff
--- a/Common/Drivers/CMSIS/Include/cmsis_gcc.h Sat May 10 21:27:06 2025 +0200 +++ b/Common/Drivers/CMSIS/Include/cmsis_gcc.h Sun May 11 16:18:20 2025 +0200 @@ -185,11 +185,10 @@ \param [in] topOfMainStack Main Stack Pointer value to set */ -// This is deprecated, get the compiler to shut up about it -//__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -//{ -// __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); -//} +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} /**
--- a/Common/Inc/data_central.h Sat May 10 21:27:06 2025 +0200 +++ b/Common/Inc/data_central.h Sun May 11 16:18:20 2025 +0200 @@ -344,6 +344,8 @@ uint16_t info_compassHeadingUpdate; int16_t gnssPositionUpdate; SGnssCoord info_gnssPosition; + int16_t scrubberState; + uint16_t info_scrubberState; } SEvents; @@ -598,4 +600,6 @@ uint8_t calculateSlowExit(uint16_t* pCountDownSec, float* pExitDepthMeter, uint8_t* pColor); +bool isScrubberTimerEnabled(const SSettings *settings); +bool isScrubberTimerRunning(const SDiveState *diveState, const SSettings *settings); #endif // DATA_CENTRAL_H
--- a/Common/Inc/settings.h Sat May 10 21:27:06 2025 +0200 +++ b/Common/Inc/settings.h Sun May 11 16:18:20 2025 +0200 @@ -81,8 +81,11 @@ #define MAX_VIEWPORT_MODE (0x7F) -#define MAX_SCRUBBER_TIME (999u) +#define MAX_SCRUBBER_TIME (999u) #define MIN_SCRUBBER_TIME -99 +#define SCRUBBER_WARNING_TIME 30 +#define SCRUBBER_ERROR_TIME 0 + #define MIN_PPO2_SP_CBAR (40u) #define PSCR_MAX_O2_DROP (15u) @@ -108,7 +111,7 @@ typedef enum { - SCRUB_TIMER_OFF = 0, + INVALID_SCRUB_TIMER_OFF = 0, SCRUB_TIMER_MINUTES, SCRUB_TIMER_PERCENT, SCRUB_TIMER_END @@ -258,7 +261,7 @@ uint8_t co2_sensor_active; /* redefined in 0xFFFF0021 */ uint8_t ext_uart_protocol; /* redefined in 0xFFFF0022 */ - uint8_t scubberActiveId; /* redefined in 0xFFFF0023 */ + uint8_t scrubberActiveId; /* redefined in 0xFFFF0023 */ SScrubberData scrubberData[2]; uint8_t ext_sensor_map_Obsolete[5]; uint8_t buttonLockActive; /* redefined in 0xFFFF0025 */ @@ -409,4 +412,7 @@ uint8_t isSettingsWarning(); bool checkAndFixSetpointSettings(void); + +bool isScrubberWarning(const SScrubberData *scrubberData); +bool isScrubberError(const SScrubberData *scrubberData); #endif // SETTINGS_H
--- a/Discovery/Inc/logbook.h Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Inc/logbook.h Sun May 11 16:18:20 2025 +0200 @@ -221,4 +221,6 @@ uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader); void logbook_readDummySamples(uint8_t* pTarget, uint16_t length); +void logScrubberState(const SScrubberData *scrubberData); + #endif /* LOGBOOK_H */
--- a/Discovery/Inc/t3.h Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Inc/t3.h Sun May 11 16:18:20 2025 +0200 @@ -44,6 +44,6 @@ uint8_t t3_customview_disabled(uint8_t view); void t3_handleAutofocus(void); -int printScrubberText(char *text, size_t size, const SScrubberData *scrubberData, SSettings *settings); +unsigned printScrubberText(char *text, size_t size, const SScrubberData scrubberData[], const SSettings *settings, bool useTwoLines); #endif /* T3_H */
--- a/Discovery/Src/data_exchange_main.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/data_exchange_main.c Sun May 11 16:18:20 2025 +0200 @@ -849,8 +849,7 @@ SDiveState *pStateReal = stateRealGetPointerWrite(); uint8_t idx; float meter = 0; - SSettings *pSettings; - + #ifdef ENABLE_EXTERNAL_PRESSURE float CO2Corr = 0.0; #endif @@ -914,6 +913,7 @@ } } + SSettings *pSettings = settingsGetPointer(); if((requestNecessary.uw != 0) && (dataIn.confirmRequest.uw != 0)) { if(((dataIn.confirmRequest.uw) & CRBUTTON) != 0) @@ -951,14 +951,12 @@ if(requestNecessary.ub.button == 1) /* send button values to RTE */ { - setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness); + setButtonResponsiveness(pSettings->ButtonResponsiveness); } } /* uint8_t IAmStolenPleaseKillMe; */ - pSettings = settingsGetPointer(); - if(pSettings->IAmStolenPleaseKillMe > 3) { pSettings->salinity = 0; @@ -1046,7 +1044,7 @@ disableTimer(); // new 170508 - settingsGetPointer()->bluetoothActive = 0; + pSettings->bluetoothActive = 0; MX_Bluetooth_PowerOff(); //Init dive Mode decoLock = DECO_CALC_init_as_is_start_of_dive; @@ -1376,3 +1374,12 @@ return; } +bool isScrubberTimerEnabled(const SSettings *settings) +{ + return settings->scrubberActiveId != 0x00 && isLoopMode(settings->dive_mode); +} + +bool isScrubberTimerRunning(const SDiveState *diveState, const SSettings *settings) +{ + return isScrubberTimerEnabled(settings) && diveState->mode == MODE_DIVE && isLoopMode(diveState->diveSettings.diveMode); +}
--- a/Discovery/Src/logbook.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/logbook.c Sun May 11 16:18:20 2025 +0200 @@ -67,6 +67,9 @@ #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */ #define DUMMY_SAMPLES (1000) /* Maximum number of samples profided by a dummy dive profile */ +#define SCRUBBER_ERROR_FLAG 0x4000 +#define SCRUBBER_WARNING_FLAG 0x2000 + typedef struct /* don't forget to adjust void clear_divisor(void) */ { uint8_t temperature; @@ -467,6 +470,10 @@ eventByte1.ub.bit7 = 1; eventByte2.ub.bit2 = 1; } + if (state->events.scrubberState) { + eventByte1.ub.bit7 = 1; + eventByte2.ub.bit3 = 1; + } //Add EventByte 1 if(eventByte1.uw > 0) @@ -510,8 +517,9 @@ } if (state->events.compassHeadingUpdate) { // New heading and type of heading - sample[length++] = state->events.info_compassHeadingUpdate & 0xFF; - sample[length++] = (state->events.info_compassHeadingUpdate & 0xFF00) >> 8; + pdata = (uint8_t*)&state->events.info_compassHeadingUpdate; + sample[length++] = *pdata++; + sample[length++] = *pdata++; } if (state->events.gnssPositionUpdate) { pdata = (uint8_t*)&state->events.info_gnssPosition.fLon; @@ -525,6 +533,11 @@ sample[length++] = *pdata++; sample[length++] = *pdata++; } + if (state->events.scrubberState) { + pdata = (uint8_t*)&state->events.info_scrubberState; + sample[length++] = *pdata++; + sample[length++] = *pdata++; + } if(divisor.temperature == 0) { @@ -1321,8 +1334,23 @@ { //InitdiveProfile pSettings->totalDiveCounter++; - logbook_initNewdiveProfile(pStateReal,settingsGetPointer()); + logbook_initNewdiveProfile(pStateReal, pSettings); min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius; + if (isScrubberTimerRunning(pStateReal, pSettings)) { + int16_t maxScrubberTime = INT16_MIN; + SScrubberData *longestScrubberData = NULL; + for (unsigned timerId = 0; timerId < 2; timerId++) { + if (pSettings->scrubberActiveId & (1 << timerId)) { + SScrubberData *scrubberData = &pStateReal->scrubberDataDive[timerId]; + if (scrubberData->TimerCur > maxScrubberTime) { + maxScrubberTime = scrubberData->TimerCur; + longestScrubberData = scrubberData; + } + } + } + + logScrubberState(longestScrubberData); + } //Write logbook sample logbook_writeSample(pStateReal); @@ -2146,5 +2174,19 @@ dummyReadIdx += length; } +void logScrubberState(const SScrubberData *scrubberData) +{ + uint16_t scrubberState = scrubberData->TimerCur & 0x0FFF; // truncate to 12 bit + if (isScrubberError(scrubberData)) { + scrubberState |= SCRUBBER_ERROR_FLAG; + } + + if (isScrubberWarning(scrubberData)) { + scrubberState |= SCRUBBER_WARNING_FLAG; + } + + stateUsedWrite->events.scrubberState = 1; + stateUsedWrite->events.info_scrubberState = scrubberState; +} /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- a/Discovery/Src/settings.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/settings.c Sun May 11 16:18:20 2025 +0200 @@ -330,7 +330,7 @@ .autoSetpoint = 0, .scrubTimerMax_Obsolete = 0, .scrubTimerCur_Obsolete = 0, - .scrubTimerMode = SCRUB_TIMER_OFF, + .scrubTimerMode = SCRUB_TIMER_MINUTES, .ext_sensor_map[0] = SENSOR_OPTIC, .ext_sensor_map[1] = SENSOR_OPTIC, .ext_sensor_map[2] = SENSOR_OPTIC, @@ -501,7 +501,7 @@ // no break case 0xFFFF0018: pSettings->cv_configuration = 0xFFFFFFFF; - pSettings->cv_configuration &= pSettings->cv_configuration ^= 1 << (CVIEW_Timer); + pSettings->cv_configuration &= ~(1 << CVIEW_sensors | 1 << CVIEW_sensors_mV | 1 << CVIEW_Timer); // no break case 0xFFFF0019: pSettings->MotionDetection = MOTION_DETECT_OFF; @@ -509,13 +509,13 @@ case 0xFFFF001A: /* deactivate new views => to be activated by customer */ pSettings->cv_config_BigScreen = 0xFFFFFFFF; - pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_Navigation + LEGACY_T3_START_ID_PRE_TIMER); - pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_DepthData + LEGACY_T3_START_ID_PRE_TIMER); + pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_Navigation + LEGACY_T3_START_ID_PRE_TIMER); + pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_DepthData + LEGACY_T3_START_ID_PRE_TIMER); // no break case 0xFFFF001B: pSettings->compassInertia = 0; /* no inertia */ pSettings->tX_customViewPrimaryBF = CVIEW_T3_Decostop; - pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_DecoTTS + LEGACY_T3_START_ID_PRE_TIMER); + pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_DecoTTS + LEGACY_T3_START_ID_PRE_TIMER); // no break case 0xFFFF001C: pSettings->viewPortMode = 0; @@ -534,7 +534,7 @@ pSettings->autoSetpoint = 0; pSettings->scrubTimerMax_Obsolete = 0; pSettings->scrubTimerCur_Obsolete = 0; - pSettings->scrubTimerMode = SCRUB_TIMER_OFF; + pSettings->scrubTimerMode = SCRUB_TIMER_MINUTES; // no break case 0xFFFF001F: pSettings->pscr_lung_ratio = 10; @@ -547,7 +547,7 @@ pSettings->ext_uart_protocol = 0; // no break; case 0xFFFF0022: - pSettings->scubberActiveId = 0; + pSettings->scrubberActiveId = 0; pSettings->scrubberData[0].TimerCur = pSettings->scrubTimerCur_Obsolete; pSettings->scrubberData[0].TimerMax = pSettings->scrubTimerMax_Obsolete; pSettings->scrubberData[0].lastDive.WeekDay = 0; @@ -1767,11 +1767,11 @@ setFirstCorrection(parameterId); } parameterId++; /* 91 */ - if(Settings.scubberActiveId > 3) /* scrubber active is used as bitfield => two timer => 2 bits in use */ - { - Settings.scubberActiveId = 0; - corrections++; - setFirstCorrection(parameterId); + if (Settings.scrubberActiveId > 0x03) { + /* scrubber active is used as bitfield => two timer => 2 bits in use */ + Settings.scrubberActiveId = 0x00; + corrections++; + setFirstCorrection(parameterId); } parameterId++; /* 92 */ if((Settings.scrubberData[0].TimerMax > MAX_SCRUBBER_TIME) || Settings.scrubberData[0].TimerCur < MIN_SCRUBBER_TIME || Settings.scrubberData[0].TimerCur > (int16_t)MAX_SCRUBBER_TIME) @@ -1790,9 +1790,8 @@ setFirstCorrection(parameterId); } parameterId++; /* 94 */ - if(Settings.scrubTimerMode > SCRUB_TIMER_END) - { - Settings.scrubTimerMode = SCRUB_TIMER_OFF; + if (Settings.scrubTimerMode == INVALID_SCRUB_TIMER_OFF || Settings.scrubTimerMode > SCRUB_TIMER_END) { + Settings.scrubTimerMode = SCRUB_TIMER_MINUTES; corrections++; setFirstCorrection(parameterId); } @@ -1996,7 +1995,7 @@ memset(pSettings->customtext,0,60); sprintf(pSettings->customtext," <your name>\n <address>"); - pSettings->cv_configuration &= (pSettings->cv_configuration ^= 1 << (CVIEW_Timer)); + pSettings->cv_configuration &= ~(1 << CVIEW_sensors | 1 << CVIEW_sensors_mV | 1 << CVIEW_Timer); set_new_settings_missing_in_ext_flash(); check_and_correct_settings(); @@ -3389,7 +3388,26 @@ { settingsWarning = 0; } + inline uint8_t isSettingsWarning() { return settingsWarning; } + +bool isScrubberError(const SScrubberData *scrubberData) +{ + if (scrubberData->TimerCur <= SCRUBBER_ERROR_TIME) { + return true; + } + + return false; +} + +bool isScrubberWarning(const SScrubberData *scrubberData) +{ + if (scrubberData->TimerCur <= SCRUBBER_WARNING_TIME) { + return true; + } + + return false; +}
--- a/Discovery/Src/simulation.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/simulation.c Sun May 11 16:18:20 2025 +0200 @@ -43,6 +43,7 @@ #include "vpm.h" #include "buehlmann.h" #include "logbook_miniLive.h" +#include "logbook.h" #include "configuration.h" @@ -111,7 +112,8 @@ stateSim.lifeData.apnea_total_max_depth_meter = 0; - memcpy(stateSim.scrubberDataDive, settingsGetPointer()->scrubberData, sizeof(stateSim.scrubberDataDive)); + SSettings *settings = settingsGetPointer(); + memcpy(stateSim.scrubberDataDive, settings->scrubberData, sizeof(stateSim.scrubberDataDive)); memset(simSensmVOffset,0,sizeof(simSensmVOffset)); if(getReplayOffset() != 0xFFFF) { @@ -151,7 +153,6 @@ SDiveState * pDiveState = &stateSim; const SDiveState * pRealState = stateRealGetPointer(); SSettings *pSettings; - uint8_t timerId = 0; static int last_second = -1; static _Bool two_second = 0; @@ -245,27 +246,35 @@ pDiveState->lifeData.ascent_rate_meter_per_min = 0; } - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (pDiveState->mode == MODE_DIVE) && isLoopMode(pDiveState->diveSettings.diveMode)) - { - simScrubberTimeoutCount++; - if(simScrubberTimeoutCount >= 60) /* resolution is minutes */ - { - simScrubberTimeoutCount = 0; - for(timerId = 0; timerId < 2; timerId++) - { - if(pSettings->scubberActiveId & (1 << timerId)) - { - if(pDiveState->scrubberDataDive[timerId].TimerCur > MIN_SCRUBBER_TIME) - { - pDiveState->scrubberDataDive[timerId].TimerCur--; - } - translateDate(stateUsed->lifeData.dateBinaryFormat, &pDiveState->scrubberDataDive[timerId].lastDive); - } - } - } + if (isScrubberTimerRunning(pDiveState, pSettings)) { + simScrubberTimeoutCount++; + + if (simScrubberTimeoutCount >= 60) { + /* resolution is minutes */ + simScrubberTimeoutCount = 0; + + int16_t maxScrubberTime = INT16_MIN; + SScrubberData *longestScrubberData = NULL; + for (unsigned timerId = 0; timerId < 2; timerId++) { + if (pSettings->scrubberActiveId & (1 << timerId)) { + SScrubberData *scrubberData = &pDiveState->scrubberDataDive[timerId]; + if (scrubberData->TimerCur > MIN_SCRUBBER_TIME) { + scrubberData->TimerCur--; + } + + if (scrubberData->TimerCur > maxScrubberTime) { + maxScrubberTime = scrubberData->TimerCur; + longestScrubberData = scrubberData; + } + + translateDate(stateUsed->lifeData.dateBinaryFormat, &scrubberData->lastDive); + } + } + + logScrubberState(longestScrubberData); + } } - if(lastPressure_bar > 0) { //1 second * 60 == 1 minute, bar * 10 = meter
--- a/Discovery/Src/t3.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/t3.c Sun May 11 16:18:20 2025 +0200 @@ -33,6 +33,7 @@ #include "t3.h" #include "data_exchange_main.h" +#include "settings.h" #include "decom.h" #include "gfx_fonts.h" #include "math.h" @@ -1334,14 +1335,13 @@ GFX_write_string(&FontT105,tXc1,text,1); } - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && isLoopMode(pSettings->dive_mode)) - { + if (isScrubberTimerEnabled(pSettings)) { snprintf(text,TEXTSIZE,"\032\002\f%c",TXT_ScrubTime); GFX_write_string(&FontT42,tXc1,text,0); textpointer = 0; text[textpointer++] = '\002'; - textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings); + textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings, false); GFX_write_string(&FontT105,tXc1,text,1); } } @@ -1996,41 +1996,45 @@ return t3_selection_customview; } -int printScrubberText(char *text, size_t size, const SScrubberData *scrubberData, SSettings *settings) +unsigned printScrubberText(char *text, size_t size, const SScrubberData scrubberData[], const SSettings *settings, bool useTwoLines) { - uint8_t timerId = 0; - int16_t currentTimerMinutes = 0; - char colour = 0; - uint8_t textIndex = 0; + unsigned textIndex = 0; + for (unsigned timerId = 0; timerId < 2; timerId++) { + if (settings->scrubberActiveId & (1 << timerId)) { + const SScrubberData *currentScrubberData = &scrubberData[timerId]; + char colour = '\020'; + if (isScrubberError(currentScrubberData)) { + colour = '\025'; + } else if (isScrubberWarning(currentScrubberData)) { + colour = '\024'; + } + + if (useTwoLines) { + textIndex += snprintf(&text[textIndex], size, "\016\016"); + } - for(timerId = 0; timerId < 2; timerId++) - { - if(settings->scubberActiveId & (1 << timerId)) - { - currentTimerMinutes = scrubberData[timerId].TimerCur; - colour = '\020'; - if (currentTimerMinutes <= 0) - { - colour = '\025'; + int16_t currentTimerMinutes = currentScrubberData->TimerCur; + if (settings->scrubTimerMode == SCRUB_TIMER_MINUTES || currentTimerMinutes < 0) { + textIndex += snprintf(&text[textIndex], size, "%c%3i'", colour, currentTimerMinutes); + } else { + if (useTwoLines) { + textIndex += snprintf(&text[textIndex], size, "%c%u%%", colour, currentTimerMinutes * 100 / settings->scrubberData[timerId].TimerMax); + } else { + textIndex += snprintf(&text[textIndex], size, "%c%u\016\016%%\017", colour, currentTimerMinutes * 100 / settings->scrubberData[timerId].TimerMax); + } + } + + if (settings->scrubberActiveId == 0x03 && timerId == 0) { + /* both timers are active => print separator */ + if (useTwoLines) { + textIndex += snprintf(&text[textIndex], size, "\r\n"); + } else { + textIndex += snprintf(&text[textIndex], size, "\020|"); + } } - else if (currentTimerMinutes <= 30) - { - colour = '\024'; - } - if (settings->scrubTimerMode == SCRUB_TIMER_MINUTES || currentTimerMinutes < 0) - { - textIndex += snprintf(&text[textIndex], size, "%c%3i'", colour, currentTimerMinutes); - } - else - { - textIndex += snprintf(&text[textIndex], size, "%c%u\016\016%%\017", colour, currentTimerMinutes * 100 / settingsGetPointer()->scrubberData[timerId].TimerMax); - } - if((settings->scubberActiveId == 3) && (timerId == 0)) /* both timers are active => print separator */ - { - textIndex += snprintf(&text[textIndex], size, " | "); - } - } - } + } + } + return textIndex; }
--- a/Discovery/Src/t7.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/t7.c Sun May 11 16:18:20 2025 +0200 @@ -1835,7 +1835,7 @@ } bool showScrubberTime = false; - if (settings->scrubTimerMode != SCRUB_TIMER_OFF) { + if (isScrubberTimerEnabled(settings)) { numLines++; showScrubberTime = true; } @@ -1982,19 +1982,8 @@ data[dataIndex++] = '\n'; data[dataIndex++] = '\r'; - data[dataIndex++] = '\002'; - if(settings->scubberActiveId == 3) /* switch to small font size to avoid bad alignment */ - { - data[dataIndex++] = '\016'; - data[dataIndex++] = '\016'; - } - dataIndex += printScrubberText(&data[dataIndex], 10, settings->scrubberData, settings); - if(settings->scubberActiveId == 3) - { - data[dataIndex++] = ' '; - data[dataIndex++] = ' '; - } - + data[dataIndex++] = '\t'; + dataIndex += printScrubberText(&data[dataIndex], 10, settings->scrubberData, settings, false); } heading[headingIndex++] = '\017'; @@ -3283,18 +3272,18 @@ { selection_custom_field++; } - if((selection_custom_field == LLC_ScrubberTime) && ((settingsGetPointer()->scrubTimerMode == SCRUB_TIMER_OFF) || (!isLoopMode(settingsGetPointer()->dive_mode)))) - { + SSettings *settings = settingsGetPointer(); + if (selection_custom_field == LLC_ScrubberTime && !isScrubberTimerEnabled(settings)) { selection_custom_field++; } #ifdef ENABLE_PSCR_MODE - if((selection_custom_field == LCC_SimPpo2) && (settingsGetPointer()->dive_mode != DIVEMODE_PSCR)) + if((selection_custom_field == LCC_SimPpo2) && (settings->dive_mode != DIVEMODE_PSCR)) { selection_custom_field++; } #endif #ifdef ENABLE_CO2_SUPPORT - if((selection_custom_field == LCC_CO2) && (settingsGetPointer()->co2_sensor_active == 0)) + if((selection_custom_field == LCC_CO2) && (settings->co2_sensor_active == 0)) { selection_custom_field++; } @@ -3315,9 +3304,7 @@ char headerText[10]; char text[TEXTSIZE]; - char tmpString[TEXTSIZE]; uint8_t textpointer = 0; - uint8_t index = 0; _Bool tinyHeaderFont = 0; uint8_t line = 0; #ifdef ENABLE_BOTTLE_SENSOR @@ -3433,26 +3420,8 @@ tinyHeaderFont = 1; headerText[2] = TXT_ScrubTime; - textpointer = printScrubberText(text, TEXTSIZE, stateUsed->scrubberDataDive, pSettings); - if (pSettings->scubberActiveId == 3) /* both timer active */ - { - snprintf(tmpString,TEXTSIZE,"\016\016%s",text); - for(index = 0; index < textpointer; index++) - { - if(tmpString[index] == '\017') /* remove switch to normal font */ - { - tmpString[index] = ' '; - } - if(tmpString[index] == '|') /* replace separator with new line */ - { - tmpString[index] = '\n'; - tmpString[index+1] = '\r'; - break; - } - } - line = 1; - strcpy(text,tmpString); - } + bool useTwoLines = (pSettings->scrubberActiveId == 0x03); + textpointer = printScrubberText(text, TEXTSIZE, stateUsed->scrubberDataDive, pSettings, useTwoLines); break; #ifdef ENABLE_PSCR_MODE @@ -4226,7 +4195,7 @@ t7cY0free.WindowLineSpacing = 48; t7cY0free.WindowNumberOfTextLines = 6; - t7cY0free.WindowTab = 420; + t7cY0free.WindowTab = 380; // header textpointer = 0; @@ -4248,10 +4217,9 @@ text[textpointer++] = TXT_FutureTTS; text[textpointer++] = '\n'; text[textpointer++] = '\r'; - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode))) - { - text[textpointer++] = TXT_ScrubTime; - + if (isScrubberTimerEnabled(pSettings)) { + text[textpointer++] = TXT_2BYTE; + text[textpointer++] = TXT2BYTE_Scrubber; } text[textpointer++] = '\017'; text[textpointer++] = 0; @@ -4297,13 +4265,12 @@ else textpointer += snprintf(&text[textpointer],10,"\020%ih", (pDecoinfoFuture->output_time_to_surface_seconds + 59) / 3600); - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode))) - { + if (isScrubberTimerEnabled(pSettings)) { text[textpointer++] = '\n'; text[textpointer++] = '\r'; text[textpointer++] = '\t'; - textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings); + textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings, false); } text[textpointer++] = 0; Gfx_colorsscheme_mod(text, 0);
--- a/Discovery/Src/tCCR.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/tCCR.c Sun May 11 16:18:20 2025 +0200 @@ -34,6 +34,7 @@ #include "data_exchange.h" #include "check_warning.h" #include "configuration.h" +#include "logbook.h" #include <math.h> /* Private types -------------------------------------------------------------*/ @@ -322,7 +323,6 @@ void tCCR_tick(void) { SSettings* pSettings = settingsGetPointer(); - uint8_t timerId = 0; if(pSettings->ppo2sensors_source == O2_SENSOR_SOURCE_OPTIC) { @@ -341,23 +341,30 @@ // If we are in the simulator the counter is updated in `simulator.c` if (!is_stateUsedSetToSim()) { /* decrease scrubber timer only if we are not bailed out */ - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (stateUsed->mode == MODE_DIVE) && isLoopMode(stateUsed->diveSettings.diveMode)) - { + if (isScrubberTimerRunning(stateUsed, pSettings)) { ScrubberTimeoutCount++; - if(ScrubberTimeoutCount >= 600) /* resolution is minutes */ - { + if (ScrubberTimeoutCount >= 600) { /* resolution is minutes */ ScrubberTimeoutCount = 0; - for(timerId = 0; timerId < 2; timerId++) - { - if(pSettings->scubberActiveId & (1 << timerId)) - { - if(stateUsed->scrubberDataDive[timerId].TimerCur > MIN_SCRUBBER_TIME) - { - stateUsedWrite->scrubberDataDive[timerId].TimerCur--; - } - translateDate(stateUsed->lifeData.dateBinaryFormat, &stateUsedWrite->scrubberDataDive[timerId].lastDive); - } + + int16_t maxScrubberTime = INT16_MIN; + SScrubberData *longestScrubberData = NULL; + for (unsigned timerId = 0; timerId < 2; timerId++) { + if (pSettings->scrubberActiveId & (1 << timerId)) { + SScrubberData *scrubberData = &stateUsedWrite->scrubberDataDive[timerId]; + if (scrubberData->TimerCur > MIN_SCRUBBER_TIME) { + scrubberData->TimerCur--; + } + + if (scrubberData->TimerCur > maxScrubberTime) { + maxScrubberTime = scrubberData->TimerCur; + longestScrubberData = scrubberData; + } + + translateDate(stateUsed->lifeData.dateBinaryFormat, &scrubberData->lastDive); + } } + + logScrubberState(longestScrubberData); } } }
--- a/Discovery/Src/tMenuCvOption.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/tMenuCvOption.c Sun May 11 16:18:20 2025 +0200 @@ -67,7 +67,6 @@ { text[textPointer++] = '\031'; /* change text color */ textPointer += snprintf(&text[textPointer], 21, "%c%c\t%u:%02u \016\016[m:ss]\017", TXT_2BYTE, TXT2BYTE_Timer, data->timerDurationS / 60, data->timerDurationS % 60); - disableLine(StMOption_Timer); text[textPointer++] = '\020'; /* restore text color */ } else
--- a/Discovery/Src/tMenuEditCvOption.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/tMenuEditCvOption.c Sun May 11 16:18:20 2025 +0200 @@ -328,6 +328,8 @@ tMenuEdit_newInput(editId, settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0); } + settings->cv_configuration |= (1 << CVIEW_Timer); + return EXIT_TO_MENU; } case ACTION_BUTTON_NEXT:
--- a/Discovery/Src/tMenuEditPlanner.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/tMenuEditPlanner.c Sun May 11 16:18:20 2025 +0200 @@ -396,11 +396,7 @@ resultPage = 0; pDecoinfo = simulation_decoplaner(tMplan_depth_meter, tMplan_intervall_time_minutes, tMplan_dive_time_minutes, gasChangeList); - simulation_evaluate_profil( &tMplan_pGasConsumption, - &tMplan_Summary, - tMplan_depth_meter, tMplan_dive_time_minutes, tMplan_gasConsumTravel, tMplan_gasConsumDeco, - pDecoinfo, - gasChangeList); + simulation_evaluate_profil(&tMplan_pGasConsumption[0], &tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, tMplan_gasConsumTravel, tMplan_gasConsumDeco, pDecoinfo, gasChangeList); // simulation_gas_consumption(tMplan_pGasConsumption, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, tMplan_gasConsumTravel, tMplan_gasConsumDeco, gasChangeList); // simulation_helper_change_points(&tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, gasChangeListDepth);
--- a/Discovery/Src/tMenuEditXtra.c Sat May 10 21:27:06 2025 +0200 +++ b/Discovery/Src/tMenuEditXtra.c Sun May 11 16:18:20 2025 +0200 @@ -229,7 +229,7 @@ snprintf(&text[0], 32,"%c \002#%d",TXT_ScrubTime,scrubberMenuId); write_field_button(StMXTRA_ScrubTimer, 20, 780, ME_Y_LINE1, &FontT48, text); - if(pSettings->scubberActiveId & (1 << scrubberMenuId)) + if(pSettings->scrubberActiveId & (1 << scrubberMenuId)) { snprintf(&text[0], 32,"%c %c \002\005", TXT_ScrubTime, TXT_Active); } @@ -255,9 +255,7 @@ if(pSettings->scrubberData[scrubberMenuId].lastDive.WeekDay != 0) { - snprintf(&text[0], 32,"%c%c\002 %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, pSettings->scrubberData[scrubberMenuId].lastDive.Date, - pSettings->scrubberData[scrubberMenuId].lastDive.Month, - pSettings->scrubberData[scrubberMenuId].lastDive.Year); + snprintf(&text[0], 32, "%c%c\002 %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, pSettings->scrubberData[scrubberMenuId].lastDive.Date, pSettings->scrubberData[scrubberMenuId].lastDive.Month, pSettings->scrubberData[scrubberMenuId].lastDive.Year); } else { @@ -265,16 +263,17 @@ } write_label_var( 20, 780, ME_Y_LINE5, &FontT48, text); - switch(pSettings->scrubTimerMode) - { - case SCRUB_TIMER_OFF: - default: snprintf(&text[0], 32,"%c\002%c%c",TXT_ScrubTimeMode, TXT_2BYTE, TXT2BYTE_MoCtrlNone ); - break; - case SCRUB_TIMER_MINUTES: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes ); - break; - case SCRUB_TIMER_PERCENT: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent ); - break; - } + switch (pSettings->scrubTimerMode) { + case SCRUB_TIMER_MINUTES: + default: + snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes ); + + break; + case SCRUB_TIMER_PERCENT: + snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent ); + + break; + } write_field_button(StMXTRA_ScrubTimer_OP_Mode, 20, 780, ME_Y_LINE6, &FontT48, text); setEvent(StMXTRA_ScrubTimer, (uint32_t)OnAction_ScrubberTimerId); @@ -478,7 +477,6 @@ SSettings *pSettings; pSettings = settingsGetPointer(); - if(scrubberMenuId == 0) { scrubberMenuId = 1; @@ -498,9 +496,7 @@ if(pSettings->scrubberData[scrubberMenuId].lastDive.WeekDay != 0) { - snprintf(&text[0], 32,"%c%c\002 %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, pSettings->scrubberData[scrubberMenuId].lastDive.Date, - pSettings->scrubberData[scrubberMenuId].lastDive.Month, - pSettings->scrubberData[scrubberMenuId].lastDive.Year); + snprintf(&text[0], 32, "%c%c\002 %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, pSettings->scrubberData[scrubberMenuId].lastDive.Date, pSettings->scrubberData[scrubberMenuId].lastDive.Month, pSettings->scrubberData[scrubberMenuId].lastDive.Year); } else { @@ -509,7 +505,7 @@ clean_content( 20, 780, ME_Y_LINE5, &FontT48); write_label_var( 20, 780, ME_Y_LINE5, &FontT48, text); - if(pSettings->scubberActiveId & (1 << scrubberMenuId)) + if(pSettings->scrubberActiveId & (1 << scrubberMenuId)) { snprintf(&text[0], 32,"%c %c \002\005", TXT_ScrubTime, TXT_Active); } @@ -589,22 +585,22 @@ SSettings *pSettings; pSettings = settingsGetPointer(); newMode = pSettings->scrubTimerMode + 1; - if(newMode >= SCRUB_TIMER_END) - { - newMode = SCRUB_TIMER_OFF; + if (newMode >= SCRUB_TIMER_END) { + newMode = SCRUB_TIMER_MINUTES; } pSettings->scrubTimerMode = newMode; - switch(pSettings->scrubTimerMode) - { - case SCRUB_TIMER_OFF: - default: snprintf(&text[0], 32,"%c\002%c%c",TXT_ScrubTimeMode, TXT_2BYTE, TXT2BYTE_MoCtrlNone ); - break; - case SCRUB_TIMER_MINUTES: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes ); - break; - case SCRUB_TIMER_PERCENT: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent ); - break; - } + switch (pSettings->scrubTimerMode) { + case SCRUB_TIMER_MINUTES: + default: + snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes ); + + break; + case SCRUB_TIMER_PERCENT: + snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent ); + + break; + } tMenuEdit_newButtonText(StMXTRA_ScrubTimer_OP_Mode, text); return UNSPECIFIC_RETURN; @@ -616,14 +612,14 @@ SSettings *pSettings; pSettings = settingsGetPointer(); - if(pSettings->scubberActiveId & (1 << scrubberMenuId)) + if(pSettings->scrubberActiveId & (1 << scrubberMenuId)) { - pSettings->scubberActiveId &= ~(1 << scrubberMenuId); + pSettings->scrubberActiveId &= ~(1 << scrubberMenuId); snprintf(&text[0], 32,"%c %c \002\006", TXT_ScrubTime, TXT_Active); } else { - pSettings->scubberActiveId |= (1 << scrubberMenuId); + pSettings->scrubberActiveId |= (1 << scrubberMenuId); snprintf(&text[0], 32,"%c %c \002\005", TXT_ScrubTime, TXT_Active); }