diff Discovery/Src/check_warning.c @ 981:c6c781a2e85b default

Merge into default
author heinrichsweikamp
date Tue, 11 Feb 2025 18:12:00 +0100
parents 33e24b77cc6c
children 8507a87f6401
line wrap: on
line diff
--- a/Discovery/Src/check_warning.c	Tue Aug 13 13:24:54 2024 +0200
+++ b/Discovery/Src/check_warning.c	Tue Feb 11 18:12:00 2025 +0100
@@ -43,6 +43,7 @@
 
 
 #define DEBOUNCE_FALLBACK_TIME_MS	(5000u)		/* set warning after 5 seconds of pending error condition */
+#define GUI_BUZZER_TIMEOUT_MS		(200u)      /* the buzzer should be active while Warning string is shown, but diver may be in a menu... */
 
 #define SETPOINT_DECO_START_RANGE_M 3.0
 #define SWITCH_DEPTH_LOW_MINIMUM_M 1.0
@@ -53,6 +54,7 @@
 static uint8_t betterSetpointId = 1;
 static int8_t fallback = 0;
 static uint16_t debounceFallbackTimeMS = 0;
+static uint8_t buzzerRequestActive = 0;
 
 /* Private function prototypes -----------------------------------------------*/
 static int8_t check_fallback(SDiveState * pDiveState);
@@ -72,9 +74,70 @@
 static int8_t check_co2(SDiveState * pDiveState);
 #endif
 static int8_t check_helper_same_oxygen_and_helium_content(SGasLine * gas1, SGasLine * gas2);
+#ifdef HAVE_DEBUG_WARNINGS
+static int8_t check_debug(SDiveState * pDiveState);
+#endif
+static uint8_t buzzerOn = 0;			/* current state of the buzzer */
 
+static void setBuzzer(int8_t warningActive);
 /* Exported functions --------------------------------------------------------*/
 
+void requestBuzzerActivation(uint8_t active)
+{
+	buzzerRequestActive = active;
+}
+
+uint8_t getBuzzerActivationState()
+{
+	return buzzerOn;
+}
+
+static void setBuzzer(int8_t warningActive)
+{
+	static uint32_t guiTimeoutCnt = 0;		/* max delay till buzzer will be activated independend from gui request */
+	static uint32_t stateTick = 0;			/* activation tick of current state */
+	static uint8_t lastWarningState = 0;	/* the parameter value of the last call*/
+
+	uint32_t tick =  HAL_GetTick();
+
+	if(warningActive)
+	{
+		if(!lastWarningState)				/* init structures */
+		{
+			guiTimeoutCnt = tick;
+			stateTick = tick;
+		}
+		if(buzzerOn)
+		{
+			if(time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_STABLE_TIME_MS)	/* buzzer has to be on for a certain time */
+			{
+				if((!buzzerRequestActive) || (time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_ON_TIME_MS))
+				{
+					buzzerOn = 0;
+					stateTick = tick;
+					guiTimeoutCnt = tick;
+				}
+			}
+		}
+		else
+		{
+			if(time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_STABLE_TIME_MS)	/* buzzer has to be off for a certain time */
+			{
+				if((buzzerRequestActive) || (time_elapsed_ms(guiTimeoutCnt, tick) > EXT_INTERFACE_BUZZER_ON_TIME_MS + GUI_BUZZER_TIMEOUT_MS))
+				{
+					buzzerOn = 1;
+					stateTick = tick;
+				}
+			}
+		}
+	}
+	else
+	{
+		buzzerOn = 0;
+	}
+	lastWarningState = warningActive;
+}
+
 void check_warning(void)
 {
   check_warning2(stateUsedWrite);
@@ -85,21 +148,33 @@
 {
   pDiveState->warnings.numWarnings = 0;
 
-	pDiveState->warnings.numWarnings += check_aGF(pDiveState);
+/* Warnings checked before the SetBuzzer call will activate the buzzer */
 	pDiveState->warnings.numWarnings += check_AscentRate(pDiveState);
-	pDiveState->warnings.numWarnings += check_CNS(pDiveState);
 	pDiveState->warnings.numWarnings += check_Deco(pDiveState);
 	pDiveState->warnings.numWarnings += check_ppO2(pDiveState);
 	pDiveState->warnings.numWarnings += check_O2_sensors(pDiveState);
+	pDiveState->warnings.numWarnings += check_fallback(pDiveState);
+#ifdef ENABLE_CO2_SUPPORT
+	pDiveState->warnings.numWarnings += check_co2(pDiveState);
+#endif
+
+	if(settingsGetPointer()->warningBuzzer)
+	{
+		setBuzzer(pDiveState->warnings.numWarnings);
+	}
+
+/* Warnings checked after this line will not cause activation of the buzzer */
+	pDiveState->warnings.numWarnings += check_aGF(pDiveState);
+	pDiveState->warnings.numWarnings += check_CNS(pDiveState);
 	pDiveState->warnings.numWarnings += check_BetterGas(pDiveState);
 	pDiveState->warnings.numWarnings += check_BetterSetpoint(pDiveState);
 	pDiveState->warnings.numWarnings += check_Battery(pDiveState);
-	pDiveState->warnings.numWarnings += check_fallback(pDiveState);
 #ifdef ENABLE_BOTTLE_SENSOR
 	pDiveState->warnings.numWarnings += check_pressureSensor(pDiveState);
 #endif
-#ifdef ENABLE_CO2_SUPPORT
-	pDiveState->warnings.numWarnings += check_co2(pDiveState);
+
+#ifdef HAVE_DEBUG_WARNINGS
+	pDiveState->warnings.numWarnings += check_debug(pDiveState);
 #endif
 }
 
@@ -157,7 +232,7 @@
 
 static int8_t check_ppO2(SDiveState * pDiveState)
 {
-	if((pDiveState->mode != MODE_DIVE) || (pDiveState->warnings.fallback))
+	if((pDiveState->mode != MODE_DIVE) || ((isLoopMode(pDiveState->diveSettings.diveMode) && (pDiveState->warnings.fallback))))
 	{
 		pDiveState->warnings.ppO2Low = 0;
 		pDiveState->warnings.ppO2High = 0;
@@ -201,7 +276,7 @@
 	pDiveState->warnings.sensorOutOfBounds[2] = 0;
 
 	if(isLoopMode(pDiveState->diveSettings.diveMode) && (pDiveState->diveSettings.CCR_Mode == CCRMODE_Sensors))
-
+	{
 		if(settingsGetPointer()->ppo2sensors_source == O2_SENSOR_SOURCE_OPTIC)
 		{
 			{
@@ -209,7 +284,8 @@
 					pDiveState->warnings.sensorLinkLost = 1;
 			}
 		}
-	test_O2_sensor_values_outOfBounds(&pDiveState->warnings.sensorOutOfBounds[0], &pDiveState->warnings.sensorOutOfBounds[1], &pDiveState->warnings.sensorOutOfBounds[2]);
+		test_O2_sensor_values_outOfBounds(&pDiveState->warnings.sensorOutOfBounds[0], &pDiveState->warnings.sensorOutOfBounds[1], &pDiveState->warnings.sensorOutOfBounds[2]);
+	}
 	return 		pDiveState->warnings.sensorLinkLost
 					+ pDiveState->warnings.sensorOutOfBounds[0]
 					+ pDiveState->warnings.sensorOutOfBounds[1]
@@ -220,9 +296,10 @@
 static uint8_t getBetterGasId(bool getDiluent, uint8_t startingGasId, SDiveState *diveState)
 {
     SDiveSettings diveSettings = diveState->diveSettings;
-
+    SGasLine localGas;
     uint8_t betterGasIdLocal = startingGasId;
     uint8_t bestGasDepth = 255;
+    uint8_t i;
 
     uint8_t gasIdOffset;
     if (getDiluent) {
@@ -231,30 +308,29 @@
         gasIdOffset = 0;
     }
 
-    if (betterGasIdLocal == NO_GAS_ID) {
-        for (unsigned i = gasIdOffset + 1; i <= gasIdOffset + 5; i++) {
-            if (diveSettings.gas[i].note.ub.active && diveSettings.gas[i].note.ub.first) {
-                betterGasIdLocal = i;
-            }
-        }
-    }
-
 	/* life data is float, gas data is uint8 */
     if (actualLeftMaxDepth(diveState)) { /* deco gases */
-        for (int i=1+gasIdOffset; i<= 5+gasIdOffset; i++) {
-            if ((diveSettings.gas[i].note.ub.active)
-                && (diveSettings.gas[i].note.ub.deco)
-                && (diveSettings.gas[i].depth_meter)
-                && (diveSettings.gas[i].depth_meter >= (diveState->lifeData.depth_meter - 0.01f ))
-                && (diveSettings.gas[i].depth_meter <= bestGasDepth)) {
+        for (i=1+gasIdOffset; i<= 5+gasIdOffset; i++) {
+        	memcpy(&localGas,&diveSettings.gas[i],sizeof(SGasLine));
+        	if((localGas.note.ub.first) && (diveSettings.diveMode == DIVEMODE_PSCR))	/* handle first gas as if it would be a deco gas set to MOD */
+        	{
+        		localGas.note.ub.active = 1;
+        		localGas.note.ub.deco = 1;
+        		localGas.depth_meter = calc_MOD(i);
+        	}
+            if ((localGas.note.ub.active)
+                && (localGas.note.ub.deco)
+                && (localGas.depth_meter)
+                && (localGas.depth_meter >= (diveState->lifeData.depth_meter - 0.9f ))
+                && (localGas.depth_meter <= bestGasDepth)) {
                 betterGasIdLocal = i;
                 bestGasDepth = diveSettings.gas[i].depth_meter;
             }
         }
     } else { /* travel gases */
         bestGasDepth = 0;
-        //check for travelgas
-        for (int i = 1 + gasIdOffset; i <= 5 + gasIdOffset; i++) {
+        //check for travalgas
+        for (i = 1 + gasIdOffset; i <= 5 + gasIdOffset; i++) {
             if ((diveSettings.gas[i].note.ub.active)
                 && (diveSettings.gas[i].note.ub.travel)
                 && (diveSettings.gas[i].depth_meter_travel)
@@ -265,6 +341,18 @@
             }
         }
     }
+    if((!getDiluent) && (betterGasIdLocal > NUM_OFFSET_DILUENT))	/* an OC gas was requested but Id is pointing to a diluent => return first OC */
+    {
+    	for (i = 1 ; i <= NUM_OFFSET_DILUENT; i++)
+    	{
+    		if(diveSettings.gas[i].note.ub.first)
+    		{
+    			betterGasIdLocal = i;
+    			break;
+    		}
+    	}
+    }
+
 
     return betterGasIdLocal;
 }
@@ -285,7 +373,7 @@
 
     if (isLoopMode(diveSettings.diveMode)) {
         betterGasId = getBetterGasId(true, lifeData.actualGas.GasIdInSettings, diveState);
-        betterBailoutGasId = getBetterGasId(false, NO_GAS_ID, diveState);
+        betterBailoutGasId = getBetterGasId(false, lifeData.lastDiluent_GasIdInSettings, diveState);
     } else {
         betterGasId = getBetterGasId(false, lifeData.actualGas.GasIdInSettings, diveState);
     }
@@ -566,7 +654,7 @@
 #ifdef ENABLE_CO2_SUPPORT
 static int8_t check_co2(SDiveState * pDiveState)
 {
-	if(pDiveState->mode != MODE_DIVE)
+	if((pDiveState->mode != MODE_DIVE) || (settingsGetPointer()->co2_sensor_active == 0))
 	{
 		pDiveState->warnings.co2High = 0;
 	}
@@ -585,6 +673,27 @@
 }
 #endif
 
+#ifdef HAVE_DEBUG_WARNINGS
+static int8_t check_debug(SDiveState * pDiveState)
+{
+	uint8_t index = 0;
+
+	pDiveState->warnings.debug = 0;
+
+	if((settingsGetPointer()->ppo2sensors_source == O2_SENSOR_SOURCE_DIGITAL) || (settingsGetPointer()->ppo2sensors_source == O2_SENSOR_SOURCE_ANADIG))
+	{
+	    for(index=0; index<3; index++)
+	    {
+        	if(((pDiveState->lifeData.extIf_sensor_map[index] == SENSOR_DIGO2M) && (((SSensorDataDiveO2*)(stateUsed->lifeData.extIf_sensor_data[index]))->status & DVO2_FATAL_ERROR)))
+        	{
+        		pDiveState->warnings.debug = 1;
+        	}
+	    }
+	}
+	return pDiveState->warnings.debug;
+}
+#endif
+
 uint8_t debounce_warning_fallback(uint16_t debounceStepms)
 {
 	uint8_t retVal = 0;