Index: trunk/firmware/CubeMX/Src/gpio.c
===================================================================
--- trunk/firmware/CubeMX/Src/gpio.c	(revision 4)
+++ trunk/firmware/CubeMX/Src/gpio.c	(revision 7)
@@ -74,6 +74,7 @@
   /*Configure GPIO pin : PtPin */
   GPIO_InitStruct.Pin = TP4_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(TP4_GPIO_Port, &GPIO_InitStruct);
 
Index: trunk/firmware/CubeMX/Src/main.c
===================================================================
--- trunk/firmware/CubeMX/Src/main.c	(revision 4)
+++ trunk/firmware/CubeMX/Src/main.c	(revision 7)
@@ -193,4 +193,5 @@
 void ExternalRedLED2ShortOnThen2LongOnThenLongPauseBlinking(void);
 void RS485DisableButtonManagement(uint32_t new_time);
+static void BatteryLowVoltageProtection(/*uint32_t current_time*/);
 
 /* USER CODE END PFP */
@@ -278,4 +279,5 @@
   SEGGER_RTT_printf(0, "Free space for statistics in fake EEPROM: %u bytes\n", FEEPROM_StatFreeBytes());
   SEGGER_RTT_printf(0, "MAX_POSSIBLE_DIFF_TO_MEASURE: %u\n", MAX_POSSIBLE_DIFF_TO_MEASURE);
+  SEGGER_RTT_printf(0, "ADC_BAT_CRITICAL_VOLTAGE: %u\n", ADC_BAT_CRITICAL_VOLTAGE);
   SEGGER_RTT_printf(0, "CPU Freq: %u Hz\n", HAL_RCC_GetSysClockFreq());
 
@@ -374,5 +376,11 @@
   while (1)																		// Main loop
   {
+	  TP4_GPIO_Port->BSRR = TP4_Pin;
+
 	  ABVoltageDropCalculation();
+
+	  BatteryLowVoltageProtection();
+
+	  TP4_GPIO_Port->BRR = TP4_Pin;
 
 	  //TIM2->CNT = 0;
@@ -448,5 +456,23 @@
 		  case SWITCH_AUTO:
 			  // Checking whether temperature, current and battery voltage are within limits
-			  if ((temperature_shutdown_is_active == 1) || (low_bat_shutdown_is_active == 1))
+			  if (temperature_shutdown_is_active == 1)
+			  {
+				  if (!restartAutoMode)
+				  {
+					  // If so, opening both MOSFETs (i.e. disconnecting load/charger from battery)
+					  /*
+#ifdef DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF
+					  DisableShortCutDetection();
+#endif
+					  HAL_NVIC_DisableIRQ(ADC_DMA_IRQ);
+					  MOSFETS_Management = &ADC_Open_Both_MOSFETs;
+					  sys_data.s.relay_status = RELAY_IS_OPENED;
+					  HAL_NVIC_EnableIRQ(ADC_DMA_IRQ);
+					  ExternalRedLED_Management = &ExternalRedLED1ShortOnThenLongPauseBlinking;
+					  */
+					  restartAutoMode = 1;
+				  }
+			  }
+			  else if (low_bat_shutdown_is_active == 1)
 			  {
 				  if (!restartAutoMode)
@@ -457,9 +483,9 @@
 #endif
 					  HAL_NVIC_DisableIRQ(ADC_DMA_IRQ);
-					  MOSFETS_Management = &ADC_Open_Both_MOSFETs;
+					  MOSFETS_Management = &DoNothing;
+					  OpenBothMOSFETSVeryFast();
 					  sys_data.s.relay_status = RELAY_IS_OPENED;
 					  HAL_NVIC_EnableIRQ(ADC_DMA_IRQ);
-					  if (temperature_shutdown_is_active == 1) ExternalRedLED_Management = &ExternalRedLED1ShortOnThenLongPauseBlinking;
-					  if (low_bat_shutdown_is_active == 1) ExternalRedLED_Management = &ExternalRedLED5ShortOnThenLongPauseBlinking;
+					  ExternalRedLED_Management = &ExternalRedLED5ShortOnThenLongPauseBlinking;
 					  restartAutoMode = 1;
 				  }
@@ -722,4 +748,5 @@
   sys_data.s.command = 0;
   sys_data.s.device_status = 0;
+  sys_data.s.ubsenseb_voltage = 1;
 }
 
@@ -2180,8 +2207,12 @@
 static inline __attribute__((always_inline)) void CalculatingAndAveragingVoltageOnContactB(void)
 {
-	static int32_t ubsenseb_voltage_accum = U_BAT_RECOVERY_VOLTAGE * 32;		// << ubsenseb_voltage_accum_avg;
+	const uint32_t AVG_VALUE = 64U;
+	static int32_t ubsenseb_voltage_accum = U_BAT_RECOVERY_VOLTAGE_mV * AVG_VALUE;		// << ubsenseb_voltage_accum_avg;
+
+	// Special case for Battery undervoltage condition. During normal operation ubsenseb_voltage will never be zero
+	//if (sys_data.s.ubsenseb_voltage == 0) ubsenseb_voltage_accum = 0;
 
 	// Calculating and averaging battery side voltage
-	int32_t temp = ADC_values[U_BAT_CHANNEL];									// Converting ADC value into int32_t type
+	int32_t temp = ADC_values[U_BAT_CHANNEL];									
 	temp = (temp*ADC_VREF)>>ADC_RESOLUTION;										// Getting voltage value on ADC input [0:3000]mV
 #ifdef VARIANT_24V
@@ -2193,27 +2224,56 @@
 	if (ubsenseb_voltage_accum < 0) ubsenseb_voltage_accum = 0;
 	ubsenseb_voltage_accum += temp;
-	sys_data.s.ubsenseb_voltage = ubsenseb_voltage_accum / 32;					//>> ubsenseb_voltage_accum_avg;
-}
-
-//------------------------------------------------------------------------------
-
-inline __attribute__((always_inline)) void TestingForLowVoltageShutdown(void)
-{
+	sys_data.s.ubsenseb_voltage = ubsenseb_voltage_accum / AVG_VALUE;			//>> ubsenseb_voltage_accum_avg;
+}
+
+//------------------------------------------------------------------------------
+
+static inline __attribute__((always_inline)) void TestingForLowVoltageShutdown(void)
+{
+	const uint32_t REACTIVATION_DELAY_ms = 10000;
+	static uint32_t low_bat_event_last_time; 
+
 	// If voltage on contact B is lower than critical one, then we must initiate "low voltage shutdown"
-	if (sys_data.s.ubsenseb_voltage < U_BAT_CRITICAL_VOLTAGE)
+	if (sys_data.s.ubsenseb_voltage < U_BAT_CRITICAL_VOLTAGE_mV)
 	{
 		if (low_bat_shutdown_is_active == 0)
 		{
+#ifdef DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF
+			DisableShortCutDetection();
+#endif
+			HAL_NVIC_DisableIRQ(ADC_DMA_IRQ);
+			MOSFETS_Management = &DoNothing;
+			OpenBothMOSFETSVeryFast();
+			sys_data.s.relay_status = RELAY_IS_OPENED;
+			HAL_NVIC_EnableIRQ(ADC_DMA_IRQ);
+			ExternalRedLED_Management = &ExternalRedLED5ShortOnThenLongPauseBlinking;
+
 			low_bat_shutdown_is_active = 1;
 			sys_data.s.device_status |= (1 << LOWBAT_ERROR);
 			sys_data.s.lowbat_error_cnt++;
 			statDataChanged = 1;
-		}
-	}
-	else if (sys_data.s.ubsenseb_voltage > U_BAT_RECOVERY_VOLTAGE)
+
+			low_bat_event_last_time = HAL_GetTick();
+		}
+	}
+	else if (sys_data.s.ubsenseb_voltage > U_BAT_RECOVERY_VOLTAGE_mV)
+	{
+		if (low_bat_event_last_time + REACTIVATION_DELAY_ms < HAL_GetTick())
+		{
+			low_bat_shutdown_is_active = 0;
+			sys_data.s.device_status &= ~(1 << LOWBAT_ERROR);
+		}
+	}
+
+	/*if (low_bat_shutdown_is_active == 1)
+	{
+		
+	}
+
+	if (sys_data.s.ubsenseb_voltage > U_BAT_RECOVERY_VOLTAGE_mV)
 	{
 		low_bat_shutdown_is_active = 0;
 		sys_data.s.device_status &= ~(1 << LOWBAT_ERROR);
-	}
+	}*/
 }
 
@@ -2309,4 +2369,21 @@
 //------------------------------------------------------------------------------
 
+static inline __attribute__((always_inline)) void BatteryLowVoltageProtection(/*uint32_t current_time*/)
+{
+	//static uint32_t last_time = 0;
+
+	// During first start, somtimes we read 0s from ADC, so we need to wait for a while before calculating Min & Max values, especially Min values
+	//if (current_time - last_time >= 0U)
+	{
+		//last_time = current_time;
+
+		CalculatingAndAveragingVoltageOnContactB();
+
+		TestingForLowVoltageShutdown();
+	}
+}
+
+//------------------------------------------------------------------------------
+
 void HeavyCalculations(uint32_t current_time)
 {
@@ -2332,7 +2409,7 @@
 		CalculatingMinMaxVoltagesForContactA();
 
-		CalculatingAndAveragingVoltageOnContactB();
-
-		TestingForLowVoltageShutdown();
+		//CalculatingAndAveragingVoltageOnContactB();
+
+		//TestingForLowVoltageShutdown();
 
 		CalculatingMinMaxVoltagesForContactB();
Index: trunk/firmware/CubeMX/Src/stm32g0xx_it.c
===================================================================
--- trunk/firmware/CubeMX/Src/stm32g0xx_it.c	(revision 4)
+++ trunk/firmware/CubeMX/Src/stm32g0xx_it.c	(revision 7)
@@ -100,4 +100,5 @@
 //extern uint32_t overload_shutdown_time;
 extern void (*InrushCurrentManagement)(void);
+extern int low_bat_shutdown_is_active;
 
 //extern uint16_t i_samples[I_RMS_SAMPLES_COUNT];
@@ -219,4 +220,17 @@
 
   rawMOSFETsVoltageDrop = ADC_values[MOSFETS_VDROP_CHANNEL];
+
+  /*if (ADC_values[U_BAT_CHANNEL] < ADC_BAT_CRITICAL_VOLTAGE)
+  {
+	  MOSFETS_Management = &OpenBothMOSFETSVeryFast;
+	  if (low_bat_shutdown_is_active == 0)
+	  {
+			sys_data.s.ubsenseb_voltage = 0;
+			low_bat_shutdown_is_active = 1;
+			sys_data.s.device_status |= (1 << LOWBAT_ERROR);
+			sys_data.s.lowbat_error_cnt++;
+			statDataChanged = 1;
+	  }
+  }*/
 
   MOSFETS_Management();
