Index: trunk/firmware/CubeMX/Inc/main.h
===================================================================
--- trunk/firmware/CubeMX/Inc/main.h	(revision 4)
+++ trunk/firmware/CubeMX/Inc/main.h	(revision 7)
@@ -59,5 +59,7 @@
 /* USER CODE BEGIN EFP */
 
+#ifdef VARIANT_24V
 #define DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF
+#endif
 
 #ifdef DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF
@@ -141,6 +143,4 @@
 /* USER CODE BEGIN Private defines */
 
-#define INVERTER_CAP_PRECHARGE
-
 #ifdef DEBUG
 	#define DEVICE_TYPE_ID						201
@@ -148,4 +148,5 @@
 	#ifdef VARIANT_24V
 		#define DEVICE_TYPE_ID					202
+		#define INVERTER_CAP_PRECHARGE
 	#else
 		#define DEVICE_TYPE_ID					201
@@ -183,7 +184,7 @@
 #ifdef VARIANT_24V
 	#define CONTROL_CURRENT_A					380		// [A] long-term current limit of the device.
-	#define SHORTCUT_CURRENT_mV					2000	// [mV] Some big value to pass test sequence
-	#define INRUSH_CURRENT_mV					1100	// [mV] Some big value to pass test sequence
-	#define COPPER_V_DROP_AT_CONTROL_CURRENT_mV	100		// [mV] - must be measured on the board
+	#define SHORTCUT_CURRENT_mV					1100	// [mV] Some big value to pass test sequence
+	#define INRUSH_CURRENT_mV					550		// [mV] Some big value to pass test sequence
+	#define COPPER_V_DROP_AT_CONTROL_CURRENT_mV	200		// [mV] - must be measured on the board
 #else
 	#define CONTROL_CURRENT_A					500		// [A] long-term current limit of the device.
@@ -202,5 +203,5 @@
 #define CURRENT_INTEGRAL_FREQ					320000U		// (7.5cycles + 12.5cycles)*1channels + (3.5cycles + 12.5cycles)*5channels = 20 + 80 = 100cycles @ 32MHz = 320 kHz
 #ifdef VARIANT_24V
-	#define CURRENT_INTEGRATION_PERIOD			575			// µs
+	#define CURRENT_INTEGRATION_PERIOD			1500		// µs
 #else
 	#define CURRENT_INTEGRATION_PERIOD			1700		// µs
@@ -286,11 +287,12 @@
 #define COMMAND_TURN_OVERLOAD_DETECTION_ON		30405
 
-#define U_BAT_CALC_PERIOD				        5	// ms
+//#define U_BAT_CALC_PERIOD				        5	// ms
 #ifdef VARIANT_24V
 #define U_BAT_CRITICAL_VOLTAGE			        20000 // mV	(If voltage on battery is lower than 10V, then there is a probability that MOSFETs will not open/close properly)
 #define U_BAT_RECOVERY_VOLTAGE			        24000 // mV	(If voltage on battery is higher than 12V, then it is fully recovered from possible previous discharge)
 #else
-#define U_BAT_CRITICAL_VOLTAGE			        10000 // mV	(If voltage on battery is lower than 10V, then there is a probability that MOSFETs will not open/close properly)
-#define U_BAT_RECOVERY_VOLTAGE			        12000 // mV	(If voltage on battery is higher than 12V, then it is fully recovered from possible previous discharge)
+#define U_BAT_CRITICAL_VOLTAGE_mV		        10000 // mV	(If voltage on battery is lower than 10V, then there is a probability that MOSFETs will not open/close properly)
+#define U_BAT_RECOVERY_VOLTAGE_mV		        12000 // mV	(If voltage on battery is higher than 12V, then it is fully recovered from possible previous discharge)
+#define ADC_BAT_CRITICAL_VOLTAGE				((((U_BAT_CRITICAL_VOLTAGE_mV / 1000) * R22) * (ADC_MAX_VALUE + 1)) / ((R23 + R22) * (ADC_VREF / 1000)))
 #endif
 
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();
