changeset 367:e309f78f89a5 MotionDetection

Merge default
author Ideenmodellierer
date Sat, 20 Jul 2019 21:42:45 +0200
parents 3c7030d6d67a (current diff) be1f74d5b3cb (diff)
children 50ea68c7a153
files Current build/OSTC4update_190506.bin Discovery/Src/base.c Discovery/Src/t7.c Small_CPU/Inc/compass_LSM303DLHC.h
diffstat 35 files changed, 441 insertions(+), 748 deletions(-) [+]
line wrap: on
line diff
--- a/Common/Inc/data_central.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Common/Inc/data_central.h	Sat Jul 20 21:42:45 2019 +0200
@@ -152,13 +152,6 @@
 }		SDeviceState;
 */
 
-typedef struct
-{
-	uint32_t average_depth_meter_Count;
-	uint32_t average_depth_last_update_dive_time_seconds_without_surface_time;
-	int32_t stopwatch_start_at_this_dive_time_seconds;
-} 	SHelper;
-
 /* struct SLifeData
  * contains data all actual data (pressure, stuturation, etc. as received from second ship
  * and has actualGas to be send to Small CPU (second chip)
@@ -213,7 +206,6 @@
 	float			apnea_total_max_depth_meter;
 	float			apnea_last_max_depth_meter;
 	int32_t 	apnea_last_dive_time_seconds;
-	int32_t		stopwatch_seconds;
 	uint16_t	bottle_bar[2 * NUM_GASES +1];
 	uint16_t	bottle_bar_age_MilliSeconds[2 * NUM_GASES + 1];
 	uint16_t	apnea_total_counter;
@@ -221,7 +213,6 @@
 	/* control of DataEX_copy_to_LifeData()
 	 */
 	uint8_t boolResetAverageDepth;
-	uint8_t boolResetStopwatch;
 	uint8_t bool_temp1;
 	uint8_t bool_temp2;
 
@@ -230,10 +221,6 @@
 	 float ppO2Sensor_bar[3];
 	 float sensorVoltage_mV[3];
 	 float HUD_battery_voltage_V;
-
-	/* used by DataEX_copy_to_LifeData()
-	 */
-	SHelper internal;
 } 	SLifeData;
 
 
Binary file Current build/OSTC4update_190506.bin has changed
Binary file Current build/OSTC4update_190720.bin has changed
--- a/Discovery/Inc/data_exchange_main.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Inc/data_exchange_main.h	Sat Jul 20 21:42:45 2019 +0200
@@ -48,7 +48,7 @@
 uint32_t DataEX_lost_connection_count(void);
 void DataEX_control_connection_while_asking_for_sleep(void);
 uint8_t DataEX_check_RTE_version__needs_update(void);
-
+void setAvgDepth(SDiveState *pStateReal);
 
 SDataReceiveFromMaster * dataOutGetPointer(void);
 
--- a/Discovery/Inc/gfx_engine.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Inc/gfx_engine.h	Sat Jul 20 21:42:45 2019 +0200
@@ -182,6 +182,9 @@
 void gfx_write_page_number(GFX_DrawCfgScreen *tMscreen, uint8_t page, uint8_t total, uint8_t color);
 
 void GFX_draw_image_monochrome(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, const tImage *image, uint8_t color);
+void GFX_build_logo_frame(void);
+void GFX_build_hw_background_frame(void);
+
 void GFX_logoAutoOff(void);
 uint8_t GFX_logoStatus(void);
 void GFX_hwBackgroundOn(void);
--- a/Discovery/Inc/ostc.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Inc/ostc.h	Sat Jul 20 21:42:45 2019 +0200
@@ -69,7 +69,6 @@
 #ifdef USART_IR_HUD
 extern UART_HandleTypeDef UartIR_HUD_Handle;
 #endif
-extern __IO ITStatus UartReadyHUD;
 
 #ifdef USART_PIEZO
 extern UART_HandleTypeDef UartPiezoTxHandle;
--- a/Discovery/Inc/tCCR.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Inc/tCCR.h	Sat Jul 20 21:42:45 2019 +0200
@@ -38,6 +38,8 @@
 void tCCR_restart(void);
 void tCCR_tick(void);
 
+void tCCR_SetRXIndication(void);
+
 float get_ppO2Sensor_bar(uint8_t sensor_id);
 float get_sensorVoltage_mV(uint8_t sensor_id);
 float get_HUD_battery_voltage_V(void);
--- a/Discovery/Src/base.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/base.c	Sat Jul 20 21:42:45 2019 +0200
@@ -206,7 +206,6 @@
 #include "display.h"
 #include "gfx_engine.h"
 #include "show_logbook.h"
-//#include "test_vpm.h"
 #include "text_multilanguage.h"
 #include "tHome.h"
 #include "tInfo.h"
@@ -215,7 +214,6 @@
 #include "tMenuEdit.h"
 #include "tMenuEditGasOC.h"
 #include "tStructure.h"
-//#include "gfx_specialeffects.h"
 #include "externLogbookFlash.h"
 #include "tComm.h"
 #include "tCCR.h"
@@ -252,34 +250,26 @@
 //#define	QUICK_SLEEP
 
 /* Private define ------------------------------------------------------------*/
-//#define BUFFER_SIZE         ((uint32_t)0x00177000)
-//#define WRITE_READ_ADDR     ((uint32_t)0x0000)
 #define REFRESH_COUNT       ((uint32_t)0x0569)   /**< for SDRAM refresh counter (90Mhz SD clock) */
 #define INVALID_BUTTON ((uint8_t) 0xFF)
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 
-RTC_HandleTypeDef		RtcHandle; /* used to change time and date, no RTC is running on this MCU */
+static RTC_HandleTypeDef		RtcHandle; /* used to change time and date, no RTC is running on this MCU */
 TIM_HandleTypeDef   TimHandle; /* used in stm32f4xx_it.c too */
-TIM_HandleTypeDef   TimBacklightHandle; /* used in stm32f4xx_it.c too */
+static TIM_HandleTypeDef   TimBacklightHandle;
 #ifdef DEMOMODE
 TIM_HandleTypeDef   TimDemoHandle; /* used in stm32f4xx_it.c too */
 #endif
 
-uint8_t LastButtonPressed;
-uint32_t LastButtonPressedTick;
-uint32_t BaseTick100ms;			/* Tick at last 100ms cycle */
-
-/*
-uint32_t time_before;
-uint32_t time_between;
-uint32_t time_after;
-*/
+static uint8_t LastButtonPressed;
+static uint32_t LastButtonPressedTick;
+static uint32_t BaseTick100ms;			/* Tick at last 100ms cycle */
 
 /* SDRAM handler declaration */
-SDRAM_HandleTypeDef hsdram;
-FMC_SDRAM_TimingTypeDef SDRAM_Timing;
-FMC_SDRAM_CommandTypeDef command;
+static SDRAM_HandleTypeDef hsdram;
+static FMC_SDRAM_TimingTypeDef SDRAM_Timing;
+static FMC_SDRAM_CommandTypeDef command;
 
 /* This was used for Dual Boot */
 //FLASH_OBProgramInitTypeDef    OBInit;
@@ -287,16 +277,12 @@
 
 /* Private variables with external access ------------------------------------*/
 
-uint32_t globalStateID = 0;
-uint8_t globalModeID = SURFMODE;
-uint32_t time_without_button_pressed_deciseconds = 0; /**< langbeschreibung (eigenes Feld) warum diese variable verwendet wird um den sleepmode zu aktivieren */
+static uint32_t globalStateID = 0;
+static uint32_t time_without_button_pressed_deciseconds = 0; /**< langbeschreibung (eigenes Feld) warum diese variable verwendet wird um den sleepmode zu aktivieren */
 uint8_t bootToBootloader = 0;	///< set  in tComm.c to install firmware updates, calls resetToFirmwareUpdate()
-//uint8_t dataEx_VPM_call = 0;
-uint8_t returnFromCommCleanUpRequest = 0; ///< use this to exit bluetooth mode and call tComm_exit()
+static uint8_t returnFromCommCleanUpRequest = 0; ///< use this to exit bluetooth mode and call tComm_exit()
 uint32_t base_tempLightLevel = 0;
-uint8_t	updateButtonsToDefault = 0;
-uint8_t	wasFirmwareUpdateCheckBattery = 0;
-
+static uint8_t	wasFirmwareUpdateCheckBattery = 0;
 static uint8_t DoDisplayRefresh = 0;	/* trigger to refresh display data */
 
 /* Private function prototypes -----------------------------------------------*/
@@ -366,7 +352,6 @@
 #endif
 
     detectionState_t shakestate;
-
     set_globalState( StBoot0 );
     LastButtonPressed = 0;
 
@@ -393,23 +378,11 @@
     }
     //settingsGetPointer()->bluetoothActive = 0; 	/* MX_Bluetooth_PowerOff();  unnecessary as part of MX_GPIO_Init() */
     //settingsGetPointer()->compassBearing = 0;
-    set_new_settings_missing_in_ext_flash(); // inlcudes update of firmware version  161121
+    set_new_settings_missing_in_ext_flash(); // includes update of firmware version  161121
 
     GFX_init( &pLayerInvisible );
     TIM_BACKLIGHT_init();
 
-    /*
-        GFX_helper_font_memory_list(&FontT24);
-        GFX_helper_font_memory_list(&FontT42);
-        GFX_helper_font_memory_list(&FontT48);
-        GFX_helper_font_memory_list(&FontT54);
-        GFX_helper_font_memory_list(&FontT84);
-        GFX_helper_font_memory_list(&FontT105);
-        GFX_helper_font_memory_list(&FontT144);
-    */
-
-
-
     // new 170508: bluetooth on at start
     settingsGetPointer()->bluetoothActive = 1;
     MX_Bluetooth_PowerOn();
@@ -454,7 +427,6 @@
     display_power_on__2_of_2__post_RGB();
     GFX_use_colorscheme( settingsGetPointer()->tX_colorscheme );
 
-// -----------------------------
     tHome_init();
     tI_init();
     tM_init();
@@ -501,10 +473,6 @@
         if( bootToBootloader )
             resetToFirmwareUpdate();
 
-        // this will allways reset after RTE reset -> no good!
-//		if(DataEX_was_power_on()) // new to allow for update after RTE update
-//			resetToFirmwareUpdate();
-
         tCCR_control();
         if( tComm_control() )// will stop while loop if tComm Mode started until exit from UART
         {
@@ -953,7 +921,7 @@
 }
 
 
-void EvaluateButton()
+static void EvaluateButton()
 {
 	uint8_t action = 0;
 	SStateList status;
@@ -1033,7 +1001,7 @@
 	}
 }
 
-void gotoSleep(void)
+static void gotoSleep(void)
 {
     /* not at the moment of testing */
 //	ext_flash_erase_firmware_if_not_empty();
@@ -1044,21 +1012,6 @@
 
 // -----------------------------
 
-uint8_t get_globalMode(void)
-{
-    return globalModeID;
-}
-
-
-void set_globalMode(uint8_t newMode)
-{
-    if((newMode != DIVEMODE) && (newMode != SURFMODE))
-        return;
-
-    globalModeID = newMode;
-}
-
-
 uint32_t get_globalState(void)
 {
     return globalStateID;
@@ -1675,7 +1628,7 @@
 #endif
 
 
-void deco_loop(void)
+static void deco_loop(void)
 {
     typedef enum
     {
@@ -1756,7 +1709,7 @@
     counter++;
 }
 
-void resetToFirmwareUpdate(void)
+static void resetToFirmwareUpdate(void)
 {
     __HAL_RCC_CLEAR_RESET_FLAGS();
     HAL_NVIC_SystemReset();
--- a/Discovery/Src/buehlmann.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/buehlmann.c	Sat Jul 20 21:42:45 2019 +0200
@@ -123,7 +123,7 @@
 	
 	stoplist = pDecoInfo->output_stop_length_seconds;
 
-	if(pLifeData->dive_time_seconds < 60)
+	if(pLifeData->dive_time_seconds_without_surface_time < 60)
 		return;
 
 	// clean stop list
--- a/Discovery/Src/data_central.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/data_central.c	Sat Jul 20 21:42:45 2019 +0200
@@ -75,7 +75,7 @@
 SDiveState stateSim = { 0 };
 SDiveState stateDeco = { 0 };
 
-SDevice stateDevice =
+static SDevice stateDevice =
 {
 	/* max is 0x7FFFFFFF, min is 0x80000000 but also defined in stdint.h :-) */
 
@@ -94,7 +94,7 @@
 	.voltageMinimum.value_int32 = INT32_MAX,
 };
 
-SVpmRepetitiveData stateVPM =
+static SVpmRepetitiveData stateVPM =
 {
 	.repetitive_variables_not_valid = 1,
 	.is_data_from_RTE_CPU = 0,
@@ -175,65 +175,26 @@
 
 
 uint8_t decoLock = DECO_CALC_undefined;
-int ascent_rate_meter_per_min  = 12;
-int descent_rate_meter_per_min  = 20;
-int max_depth = 70;
-int bottom_time = 10;
+
+static int descent_rate_meter_per_min  = 20;
+static int max_depth = 70;
+static int bottom_time = 10;
 
 _Bool vpm_crush(SDiveState* pDiveState);
 void setSimulationValues(int _ascent_rate_meter_per_min, int _descent_rate_meter_per_min, int _max_depth, int _bottom_time )
 {
-    ascent_rate_meter_per_min = _ascent_rate_meter_per_min;
     descent_rate_meter_per_min = _descent_rate_meter_per_min;
     max_depth = _max_depth;
     bottom_time = _bottom_time;
 }
 
-
-
 int current_second(void) {
 
     return HAL_GetTick() / 1000;
-    // printf("milliseconds: %lld\n", milliseconds);
-    //return milliseconds;
 }
 
-
-
 #define OXY_ONE_SIXTIETH_PART 			0.0166667f
 
-/*void oxygen_calculate_cns(float* oxygen_cns, float pressure_oxygen_real)
-{
-	int cns_no_range = 0;
-	_Bool not_found = 1;
-    //for the cns calculation
-    const float cns_ppo2_ranges[60][2] = {	{0.50, 0.00}, {0.60, 0.14}, {0.64, 0.15}, {0.66, 0.16}, {0.68, 0.17}, {0.70, 0.18},
-										{0.74, 0.19}, {0.76, 0.20}, {0.78, 0.21}, {0.80, 0.22}, {0.82, 0.23}, {0.84, 0.24},
-										{0.86, 0.25}, {0.88, 0.26}, {0.90, 0.28}, {0.92, 0.29}, {0.94, 0.30}, {0.96, 0.31},
-										{0.98, 0.32}, {1.00, 0.33}, {1.02, 0.35}, {1.04, 0.36}, {1.06, 0.38}, {1.08, 0.40},
-										{1.10, 0.42}, {1.12, 0.43}, {1.14, 0.43}, {1.16, 0.44}, {1.18, 0.46}, {1.20, 0.47},
-										{1.22, 0.48}, {1.24, 0.51},	{1.26, 0.52}, {1.28, 0.54}, {1.30, 0.56}, {1.32, 0.57},
-										{1.34, 0.60}, {1.36, 0.62}, {1.38, 0.63}, {1.40, 0.65}, {1.42, 0.68}, {1.44, 0.71},
-										{1.46, 0.74}, {1.48, 0.78}, {1.50, 0.83}, {1.52, 0.93}, {1.54, 1.04}, {1.56, 1.19},
-										{1.58, 1.47}, {1.60, 2.22}, {1.62, 5.00}, {1.65, 6.25}, {1.67, 7.69}, {1.70, 10.0},
-										{1.72,12.50}, {1.74,20.00}, {1.77,25.00}, {1.79,31.25}, {1.80,50.00}, {1.82,100.0}};
-	//find the correct cns range for the corresponding ppo2
-	cns_no_range = 58;
-	while (cns_no_range && not_found)
-	{
-		if (pressure_oxygen_real > cns_ppo2_ranges[cns_no_range][0])
-		{
-			cns_no_range++;
-			not_found = 0;
-		}
-		else
-			cns_no_range--;
-	}
-
-	//calculate cns for the actual ppo2 for 1 second
-	*oxygen_cns += OXY_ONE_SIXTIETH_PART * cns_ppo2_ranges[cns_no_range][1];
-}*/
-
 uint8_t calc_MOD(uint8_t gasId)
 {
 	int16_t oxygen, maxppO2, result;
@@ -261,40 +222,6 @@
 	return result;
 }
 
-uint8_t calc_MinOD(uint8_t gasId)
-{
-	int16_t oxygen, minppO2, result;
-	SSettings *pSettings;
-
-	pSettings = settingsGetPointer();
-
-	oxygen = (int16_t)(pSettings->gas[gasId].oxygen_percentage);
-	minppO2 =(int16_t)(pSettings->ppO2_min);
-	result = 10 *  minppO2;
-	result += 9;
-	result /= oxygen;
-	result -= 10;
-
-	if(result < 0)
-		return 0;
-
-	if(result > 255)
-		return 255;
-
-	return result;
-}
-/*
-float calc_ppO2(float input_ambient_pressure_bar, SGas* pGas)
-{
-    float percent_N2 = 0;
-	float percent_He = 0;
-	float percent_O2 = 0;
-    decom_get_inert_gases(input_ambient_pressure_bar, pGas, &percent_N2, &percent_He);
-    percent_O2 = 1 - percent_N2 - percent_He;
-
-    return  (input_ambient_pressure_bar - WATER_VAPOUR_PRESSURE) * percent_O2;
-}*/
-
 float get_ambiant_pressure_simulation(long dive_time_seconds, float surface_pressure_bar )
 {
   static
@@ -651,7 +578,7 @@
 }
 
 
-int32_t helper_days_from_civil(int32_t y, uint32_t m, uint32_t d)
+static int32_t helper_days_from_civil(int32_t y, uint32_t m, uint32_t d)
 {
 		y += 2000;
     y -= m <= 2;
@@ -663,7 +590,7 @@
 }
 
 
-uint8_t helper_weekday_from_days(int32_t z)
+static uint8_t helper_weekday_from_days(int32_t z)
 {
     return (uint8_t)(z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6);
 }
@@ -714,95 +641,12 @@
   sTime->SubSeconds = 0;
 }
 
-
-/*
-void initDiveState(SDiveSettings * pDiveSettings, SVpm * pVpm)
-{
-    SSettings* pSettings = settingsGetPointer();
-    for(int i = 0; i< NUM_GASES; i++)
-    {
-        pDiveSettings->gas[i] =  pSettings->gas[i];
-        pDiveSettings->gas[NUM_OFFSET_DILUENT + i] =  pSettings->gas[NUM_OFFSET_DILUENT + i];
-        pDiveSettings->setpoint[i] =  pSettings->setpoint[i];
-    }
-    pDiveSettings->diveMode = pSettings->dive_mode;
-
-    pDiveSettings->gf_high = pSettings->GF_high;
-    pDiveSettings->gf_low = pSettings->GF_low;
-    pDiveSettings->last_stop_depth_bar = ((float)pSettings->last_stop_depth_meter) / 10.0;
-    pDiveSettings->ascentRate_meterperminute = 10;
-    pDiveSettings->vpm_conservatism = 1;
-
-    pDiveSettings->input_next_stop_increment_depth_bar = ((float)pSettings->stop_increment_depth_meter) / 10.0f;
-
-    vpm_init(pVpm,  pDiveSettings->vpm_conservatism, 0, 0);
-}
-*/
-_Bool deco_zone_reached(void)
-{
-  	if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
-      return stateUsed->lifeData.pressure_ambient_bar <= stateUsed->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero;
-    else
-      return stateUsed->vpm.deco_zone_reached;
-
-}
-
-
 void resetEvents(const SDiveState *pStateUsed)
 {
 	memset((void *)&pStateUsed->events, 0, sizeof(SEvents));
 }
 
 
-/* This is derived from crc32b but does table lookup. First the table
-itself is calculated, if it has not yet been set up.
-Not counting the table setup (which would probably be a separate
-function), when compiled to Cyclops with GCC, this function executes in
-7 + 13n instructions, where n is the number of bytes in the input
-message. It should be doable in 4 + 9n instructions. In any case, two
-of the 13 or 9 instrucions are load byte.
-   This is Figure 14-7 in the text. */
-
-/* http://www.hackersdelight.org/ i guess ;-)  *hw */
-
-uint32_t crc32c_checksum(uint8_t* message, uint16_t length, uint8_t* message2, uint16_t length2) {
-	int i, j;
-	uint32_t byte, crc, mask;
-	static unsigned int table[256] = {0};
-
-	/* Set up the table, if necessary. */
-	if (table[1] == 0) {
-		for (byte = 0; byte <= 255; byte++) {
-			 crc = byte;
-			 for (j = 7; j >= 0; j--) {    // Do eight times.
-					mask = -(crc & 1);
-					crc = (crc >> 1) ^ (0xEDB88320 & mask);
-			 }
-			 table[byte] = crc;
-		}
-	}
-
-	/* Through with table setup, now calculate the CRC. */
-	i = 0;
-	crc = 0xFFFFFFFF;
-	while (length--) {
-		byte = message[i];
-		crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
-		i = i + 1;
-	}
-	if(length2)
-	{
-	 i = 0;
-	 while (length2--) {
-			byte = message2[i];
-			crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
-			i = i + 1;
-	 }
-	}
-	return ~crc;
-}
-
-
 uint32_t	CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words)
 {
  cm_t        crc_model;
@@ -916,10 +760,12 @@
      return (cm_crc(&crc_model));
 }
  
-
+// This code is also in RTE. Keep it in sync when editing
 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData)
 {
-	if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.04f))
+	if (lifeData->pressure_ambient_bar > 1.16)
+		return false;
+	else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f))
 		return true;
 	else
 		return false;
--- a/Discovery/Src/data_exchange_main.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/data_exchange_main.c	Sat Jul 20 21:42:45 2019 +0200
@@ -860,7 +860,6 @@
 			//Init dive Mode
 			decoLock = DECO_CALC_init_as_is_start_of_dive;
 			pStateReal->lifeData.boolResetAverageDepth = 1;
-			pStateReal->lifeData.boolResetStopwatch = 1;
 		}
 
 		pStateReal->lifeData.cns = dataIn.data[dataIn.boolToxicData].cns;
@@ -890,14 +889,7 @@
 		pStateReal->mode = dataIn.mode;
 		pStateReal->chargeStatus = dataIn.chargeStatus;
 	
-		if(is_ambient_pressure_close_to_surface(&pStateReal->lifeData))
-		{
-			pStateReal->lifeData.depth_meter = 0;
-		}
-		else
-		{
-			pStateReal->lifeData.depth_meter = meter;
-		}
+		pStateReal->lifeData.depth_meter = meter;
 
 		pStateReal->lifeData.temperature_celsius = getTemperature(&dataIn);
 		pStateReal->lifeData.ascent_rate_meter_per_min = dataIn.data[dataIn.boolPressureData].ascent_rate_meter_per_min;
@@ -999,48 +991,40 @@
 		// reset max_depth_meter, average_depth_meter and internal values
 			pStateReal->lifeData.max_depth_meter = 0;
 			pStateReal->lifeData.boolResetAverageDepth = 1;
-			pStateReal->lifeData.boolResetStopwatch = 1;
 		}
 	}
 
-	/* average depth 
-	 */
+	setAvgDepth(pStateReal);
+}
+
+void setAvgDepth(SDiveState *pStateReal) {
+
 	float *AvgDepthValue = &pStateReal->lifeData.average_depth_meter;
 	float	DepthNow = pStateReal->lifeData.depth_meter; 
-	uint32_t *AvgDepthCount = &pStateReal->lifeData.internal.average_depth_meter_Count;
-	uint32_t *AvgDepthTimer = &pStateReal->lifeData.internal.average_depth_last_update_dive_time_seconds_without_surface_time;
+	static uint32_t AvgDepthCount = 0;
+	static uint32_t AvgDepthTimer = 0;
 	uint32_t AvgSecondsSinceLast;
 	uint32_t DiveTime = pStateReal->lifeData.dive_time_seconds_without_surface_time;
-	
+
 	if(pStateReal->lifeData.boolResetAverageDepth)
 	{
 		*AvgDepthValue = DepthNow;
-		*AvgDepthCount = 1;
-		*AvgDepthTimer = DiveTime;
+		AvgDepthCount = 0;
+		AvgDepthTimer = DiveTime;
 		pStateReal->lifeData.boolResetAverageDepth = 0;
 	}
-	else if (DiveTime > *AvgDepthTimer)
+	else if (DiveTime > AvgDepthTimer)
 	{
-		AvgSecondsSinceLast = DiveTime - *AvgDepthTimer;
+		AvgSecondsSinceLast = DiveTime - AvgDepthTimer;
 		for(int i=0;i<AvgSecondsSinceLast;i++)
 		{
-			*AvgDepthValue = (*AvgDepthValue * *AvgDepthCount + DepthNow) / (*AvgDepthCount + 1);
-			*AvgDepthCount += 1;
+			*AvgDepthValue = (*AvgDepthValue * AvgDepthCount + DepthNow) / (AvgDepthCount + 1);
+			AvgDepthCount += 1;
 		}
-		*AvgDepthTimer = DiveTime;
+		AvgDepthTimer = DiveTime;
 	}
-	if(*AvgDepthCount == 0)
-		*AvgDepthValue = 0;
-
-
-	/* stop watch
-	 */
-	if(pStateReal->lifeData.boolResetStopwatch)
-	{
-		pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds = pStateReal->lifeData.dive_time_seconds;
-		pStateReal->lifeData.boolResetStopwatch = 0;
-	}
-	pStateReal->lifeData.stopwatch_seconds = pStateReal->lifeData.dive_time_seconds - pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds;
+	if(AvgDepthCount == 0)
+		*AvgDepthValue = DepthNow;
 }
 
 
--- a/Discovery/Src/display.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/display.c	Sat Jul 20 21:42:45 2019 +0200
@@ -34,7 +34,7 @@
 }
 
 
-void send(uint8_t *pData, uint16_t inputlength)
+static void send(uint8_t *pData, uint16_t inputlength)
 {
 	HAL_GPIO_WritePin(DISPLAY_CSB_GPIO_PORT,DISPLAY_CSB_PIN,GPIO_PIN_RESET); // chip select
 
@@ -48,7 +48,7 @@
 }
 
 
-uint16_t convert8to9to8(uint8_t *pInput, uint8_t *pOutput,uint16_t inputlength)
+static uint16_t convert8to9to8(uint8_t *pInput, uint8_t *pOutput,uint16_t inputlength)
 {
 	uint16_t outputlength;
 	uint8_t readbit =  0x80;//0b1000000;
@@ -227,55 +227,6 @@
 }
 
 
-void display_power_off(void)
-{
-	uint8_t aTxBuffer[1];
-	uint8_t bTxBuffer[9];
-	uint16_t i,length;
-
-	for(i=0;i<9;i++)
-		bTxBuffer[i] = 0;
-
-	aTxBuffer[0] = DISPLAY_OFF;
-	length = convert8to9to8((uint8_t*)aTxBuffer,(uint8_t*)bTxBuffer,1);
-	send((uint8_t*)bTxBuffer, length);
-	HAL_Delay(5);
-
-	aTxBuffer[0] = SLEEP_IN;
-	length = convert8to9to8((uint8_t*)aTxBuffer,(uint8_t*)bTxBuffer,1);
-	send((uint8_t*)bTxBuffer, length);
-}
-
-
-void display_sleep(void)
-{
-	uint8_t aTxBuffer[1];
-	uint8_t bTxBuffer[9];
-	uint16_t i,length;
-
-	for(i=0;i<9;i++)
-		bTxBuffer[i] = 0;
-
-	aTxBuffer[0] = SLEEP_IN;
-	length = convert8to9to8((uint8_t*)aTxBuffer,(uint8_t*)bTxBuffer,1);
-	send((uint8_t*)bTxBuffer, length);
-}
-
-
-void display_sleep_release(void)
-{
-	uint8_t aTxBuffer[1];
-	uint8_t bTxBuffer[9];
-	uint16_t i,length;
-
-	for(i=0;i<9;i++)
-		bTxBuffer[i] = 0;
-
-	aTxBuffer[0] = SLEEP_OUT;
-	length = convert8to9to8((uint8_t*)aTxBuffer,(uint8_t*)bTxBuffer,1);
-	send((uint8_t*)bTxBuffer, length);
-}
-
 static void Display_Error_Handler(void)
 {
   while(1)
--- a/Discovery/Src/externCPU2bootloader.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/externCPU2bootloader.c	Sat Jul 20 21:42:45 2019 +0200
@@ -35,37 +35,26 @@
 /* Exported variables --------------------------------------------------------*/
 
 /* Private types -------------------------------------------------------------*/
-#define BOOTLOADSPITIMEOUT 5000
 
 /* Private variables ---------------------------------------------------------*/
 
 /* Private function prototypes -----------------------------------------------*/
 
-uint8_t boot_sync_frame(void);
-uint8_t boot_ack(void);
-uint8_t boot_get(uint8_t *RxBuffer);
-uint8_t boot_get_id(uint8_t *RxBuffer);
-uint8_t boot_get_version(uint8_t *RxBuffer);
-//uint8_t boot_go(uint32_t address);
-uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data);
-//uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers);
-uint8_t boot_erase_memory(void);
-uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes);
-/*
-uint8_t boot_write_unprotect(void);
-uint8_t boot_readout_protect(void);
-uint8_t boot_readout_unprotect(void);
-*/
-void	Bootoader_send_command(uint8_t command);
-void Bootloader_spi_single(uint8_t TxByte);
-void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer);
-void Bootloader_Error_Handler(void);
+static uint8_t boot_sync_frame(void);
+static uint8_t boot_ack(void);
+static uint8_t boot_get_id(uint8_t *RxBuffer);
+static uint8_t boot_get_version(uint8_t *RxBuffer);
+static uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data);
+static uint8_t boot_erase_memory(void);
+static void	Bootloader_send_command(uint8_t command);
+static void Bootloader_spi_single(uint8_t TxByte);
+static void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer);
+static void Bootloader_Error_Handler(void);
 
 /* Exported functions --------------------------------------------------------*/
 
 uint8_t extCPU2bootloader_start(uint8_t *version, uint16_t *chipID)
 {
-//	uint8_t aTxBuffer[256] = { 0 };
 	uint8_t aRxBuffer[256] = { 0 };
 
 	HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
@@ -89,7 +78,7 @@
 {
   uint8_t version = 0;
   uint16_t chipID = 0;
-//  uint8_t ret;
+
   if(!extCPU2bootloader_start(&version,&chipID))
     return 0;
 	if(!boot_erase_memory())
@@ -135,28 +124,16 @@
 
 /* Private functions --------------------------------------------------------*/
 
-uint8_t boot_sync_frame(void)
+static uint8_t boot_sync_frame(void)
 {
 	Bootloader_spi_single(0x5a);
 	return boot_ack();
 }
 
-
-uint8_t boot_get(uint8_t *RxBuffer)
+static uint8_t boot_get_version(uint8_t *RxBuffer)
 {
 	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x00);
-	if(!boot_ack())
-		return 0;
-	Bootloader_spi(14, NULL, RxBuffer);
-	return boot_ack();
-}
-
-
-uint8_t boot_get_version(uint8_t *RxBuffer)
-{
-	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x01);
+	Bootloader_send_command(0x01);
 	if(!boot_ack())
 		return 0;
 	Bootloader_spi(3, NULL, RxBuffer);
@@ -164,23 +141,16 @@
 }
 
 
-uint8_t boot_get_id(uint8_t *RxBuffer)
+static uint8_t boot_get_id(uint8_t *RxBuffer)
 {
 	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x02);
+	Bootloader_send_command(0x02);
 	if(!boot_ack())
 		return 0;
 	Bootloader_spi(5, NULL, RxBuffer);
 	return boot_ack();
 }
 
-/*
-uint8_t boot_go(uint32_t address)
-{
-
-}
-*/
-
 
 uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data)
 {
@@ -189,7 +159,7 @@
 	uint16_t length;
 
 	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x31);
+	Bootloader_send_command(0x31);
 	if(!boot_ack())
 		return 1;
 	HAL_Delay(5);
@@ -223,13 +193,12 @@
   return 1;
 }
 
-//uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers)
-uint8_t boot_erase_memory(void)
+static uint8_t boot_erase_memory(void)
 {
 	uint8_t special_erase_with_checksum[3] = {0xFF, 0xFF, 0x00};
 
 	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x44);
+	Bootloader_send_command(0x44);
 	if(!boot_ack())
 		return 0;
 	Bootloader_spi(3, special_erase_with_checksum, NULL);
@@ -243,30 +212,13 @@
 uint8_t boot_write_unprotect(void)
 {
 	Bootloader_spi_single(0x5a);
-	Bootoader_send_command(0x73);
+	Bootloader_send_command(0x73);
 	if(!boot_ack())
 		return 0;
 	return boot_ack();
 }
 
-/*
-uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes)
-{
-
-}
-
-uint8_t boot_readout_protect(void)
-{
-
-}
-
-uint8_t boot_readout_unprotect(void)
-{
-
-}
-*/
-
-uint8_t boot_ack(void)
+static uint8_t boot_ack(void)
 {
 	uint8_t answer = 0;
 
@@ -287,7 +239,7 @@
 		return 0;
 }
 
-void	Bootoader_send_command(uint8_t command)
+static void	Bootloader_send_command(uint8_t command)
 {
 	uint8_t send[2];
 	uint8_t receive[2];
@@ -297,13 +249,13 @@
 	Bootloader_spi(2, send, receive);
 }
 
-void Bootloader_spi_single(uint8_t TxByte)
+static void Bootloader_spi_single(uint8_t TxByte)
 {
 	Bootloader_spi(1,&TxByte, 0);
 }
 
 
-void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer)
+static void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer)
 {
 	uint8_t dummy[256] = { 0 };
 	uint8_t *tx_data;
@@ -334,10 +286,7 @@
 }
 
 
-void Bootloader_Error_Handler(void)
+static void Bootloader_Error_Handler(void)
 {
 	while(1);
 }
-
-
-
--- a/Discovery/Src/gfx_engine.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/gfx_engine.c	Sat Jul 20 21:42:45 2019 +0200
@@ -250,7 +250,7 @@
 }
 
 
-static void GFX_build_hw_background_frame(void)
+void GFX_build_hw_background_frame(void)
 {
 	GFX_DrawCfgScreen	tLogoTemp;
 	SWindowGimpStyle windowGimp;
@@ -284,7 +284,7 @@
 }
 
 
-static void GFX_build_logo_frame(void)
+void GFX_build_logo_frame(void)
 {
 	GFX_DrawCfgScreen	tLogoTemp;
 	SWindowGimpStyle windowGimp;
--- a/Discovery/Src/logbook.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/logbook.c	Sat Jul 20 21:42:45 2019 +0200
@@ -1201,6 +1201,7 @@
 		logbook_SetMaxCNS(pStateReal->lifeData.cns);
 		logbook_SetCompartmentDesaturation(pStateReal);
 		logbook_SetLastStop(pStateReal->diveSettings.last_stop_depth_bar);
+		header.batteryVoltage = pStateReal->lifeData.battery_voltage * 1000;
 		logbook_EndDive();
 		bDiveMode = 0;
 	} else
--- a/Discovery/Src/logbook_miniLive.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/logbook_miniLive.c	Sat Jul 20 21:42:45 2019 +0200
@@ -32,9 +32,9 @@
   */
 	
 #define MLLsize (296)
-uint16_t MLLdataDepth[MLLsize];
-uint16_t MLLpointer  = 0;
-uint8_t MLLtickIntervallSeconds = 2;
+static uint16_t MLLdataDepth[MLLsize];
+static uint16_t MLLpointer  = 0;
+static uint8_t MLLtickIntervallSeconds = 2;
 	
 
 uint16_t *getMiniLiveLogbookPointerToData(void)
--- a/Discovery/Src/ostc.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/ostc.c	Sat Jul 20 21:42:45 2019 +0200
@@ -40,11 +40,12 @@
 
 
 UART_HandleTypeDef UartHandle;
+#ifdef USART_PIEZO
 UART_HandleTypeDef UartPiezoTxHandle;
+#endif
 UART_HandleTypeDef UartIR_HUD_Handle;
 
 __IO ITStatus UartReady = RESET;
-__IO ITStatus UartReadyHUD = RESET;
 
 /* Private types -------------------------------------------------------------*/
 
@@ -90,42 +91,6 @@
     HAL_SPI_Init(&cpu2DmaSpi);
 }
 
-
-void MX_GPIO_Backlight_max_static_only_Init(void)
-{
-    GPIO_InitTypeDef GPIO_InitStruct;
-    TIM_BACKLIGHT_GPIO_ENABLE();
-
-    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;//GPIO_PULLUP; /* should be normally high */
-    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-
-    GPIO_InitStruct.Pin = TIM_BACKLIGHT_PIN;
-    HAL_GPIO_Init(TIM_BACKLIGHT_GPIO_PORT, &GPIO_InitStruct);
-
-    HAL_GPIO_WritePin(TIM_BACKLIGHT_GPIO_PORT,TIM_BACKLIGHT_PIN,GPIO_PIN_SET);
-}
-
-
-void MX_GPIO_One_Button_only_Init(void)
-{
-    GPIO_InitTypeDef GPIO_InitStruct;
-    BUTTON_NEXT_GPIO_ENABLE();
-
-    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;//GPIO_PULLUP; /* should be normally high */
-    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-
-    GPIO_InitStruct.Pin = BUTTON_NEXT_PIN;
-    HAL_GPIO_Init(BUTTON_NEXT_GPIO_PORT, &GPIO_InitStruct);
-}
-
-
-GPIO_PinState MX_GPIO_Read_The_One_Button(void)
-{
-    return HAL_GPIO_ReadPin(BUTTON_NEXT_GPIO_PORT, BUTTON_NEXT_PIN);
-}
-
 void MX_GPIO_Init(void)
 {
     GPIO_InitTypeDef GPIO_InitStruct;
@@ -263,26 +228,6 @@
 #endif
 }
 
-
-void MX_SmallCPU_NO_Reset_Helper(void)
-{
-#ifdef SMALLCPU_NRESET_PIN
-    GPIO_InitTypeDef GPIO_InitStruct;
-
-    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
-    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-
-    SMALLCPU_NRESET_GPIO_ENABLE();
-    HAL_GPIO_Init(SMALLCPU_NRESET_GPIO_PORT, &GPIO_InitStruct);
-    HAL_GPIO_WritePin(SMALLCPU_NRESET_GPIO_PORT,SMALLCPU_NRESET_PIN,GPIO_PIN_SET);
-//	HAL_Delay(100);
-//  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-//  HAL_GPIO_Init(SMALLCPU_NRESET_GPIO_PORT, &GPIO_InitStruct);
-#endif
-}
-
-
 void MX_SmallCPU_Reset_To_Standard(void)
 {
 #ifdef SMALLCPU_NRESET_PIN
@@ -303,23 +248,6 @@
 #endif
 }
 
-
-uint8_t MX_UART_ButtonAdjust(uint8_t *array)
-{
-#ifdef USART_PIEZO
-    uint8_t answer[4];
-    HAL_UART_Transmit(&UartPiezoTxHandle,array,4,1000);
-    HAL_UART_Receive(&UartPiezoTxHandle,answer,4,2000);
-    if(	(answer[0] == array[0])
-        &&(answer[1] == array[1])
-        &&(answer[2] == array[2])
-        &&(answer[3] == array[3]))
-    return 1;
-#endif
-    return 0;
-}
-
-
 void MX_UART_Init(void)
 {
   /*##-1- Configure the UART peripheral ######################################*/
@@ -376,8 +304,6 @@
 }
 
 
-
-//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
     if(huart == &UartHandle)
@@ -385,7 +311,7 @@
     else
     if(huart == &UartIR_HUD_Handle)
     {
-        UartReadyHUD = SET;
+    	tCCR_SetRXIndication();
     }
 }
 
--- a/Discovery/Src/settings.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/settings.c	Sat Jul 20 21:42:45 2019 +0200
@@ -36,7 +36,7 @@
 SSettings Settings;
 
 const uint8_t RTErequiredHigh = 1;
-const uint8_t RTErequiredLow = 8;
+const uint8_t RTErequiredLow = 9;
 
 const uint8_t FONTrequiredHigh = 1;
 const uint8_t FONTrequiredLow =	0;
@@ -55,8 +55,8 @@
 {
     .versionFirst   = 1,
     .versionSecond 	= 4,
-    .versionThird   = 8,
-    .versionBeta    = 0,
+    .versionThird   = 9,
+    .versionBeta    = 1,
 
     /* 4 bytes with trailing 0 */
     .signature = "mh",
@@ -1391,7 +1391,7 @@
 
 uint8_t firmwareVersion_16bit_high(void)
 {
-    return ((firmware_FirmwareData.versionFirst & 0x1F)  << 3)	+ ((firmware_FirmwareData.versionSecond & 0x1C) >> 5);
+    return ((firmware_FirmwareData.versionFirst & 0x1F)  << 3)	+ ((firmware_FirmwareData.versionSecond & 0x1C) >> 2);
 }
 
 uint8_t firmwareVersion_16bit_low(void)
--- a/Discovery/Src/simulation.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/simulation.c	Sat Jul 20 21:42:45 2019 +0200
@@ -37,6 +37,7 @@
 #include "decom.h"
 #include "calc_crush.h"
 #include "data_exchange.h"
+#include "data_exchange_main.h"
 #include "timer.h"
 #include "check_warning.h"
 #include "vpm.h"
@@ -51,7 +52,7 @@
 
 
 //Private functions
-static float sim_get_ambiant_pressure(SDiveState * pDiveState);
+static float sim_get_ambient_pressure(SDiveState * pDiveState);
 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState);
 static void simulation_set_aim_depth(int depth_meter);
 
@@ -157,12 +158,7 @@
     pDiveState->lifeData.sensorVoltage_mV[2] = stateRealGetPointer()->lifeData.sensorVoltage_mV[2];
 
     pDiveState->lifeData.dive_time_seconds += 1;
-    pDiveState->lifeData.pressure_ambient_bar = sim_get_ambiant_pressure(pDiveState);
-
-    if(!is_ambient_pressure_close_to_surface(&pDiveState->lifeData) && !(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) )
-    {
-        pDiveState->lifeData.dive_time_seconds_without_surface_time += 1;
-    }
+    pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState);
 
     if(is_ambient_pressure_close_to_surface(&pDiveState->lifeData)) // new hw 170214
     {
@@ -185,6 +181,11 @@
         pDiveState->lifeData.counterSecondsShallowDepth = 0;
     }
 
+    if(!is_ambient_pressure_close_to_surface(&pDiveState->lifeData) && !(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) )
+    {
+    	pDiveState->lifeData.dive_time_seconds_without_surface_time += 1;
+    }
+
     pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f;
     if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter)
             pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter;
@@ -201,38 +202,10 @@
             pDiveState->lifeData.dive_time_seconds = 0;
             pDiveState->lifeData.max_depth_meter = 0;
             pDiveState->lifeData.boolResetAverageDepth = 1;
-            pDiveState->lifeData.boolResetStopwatch = 1;
         }
     }
 
-    /* average depth
-     */
-    float *AvgDepthValue = &pDiveState->lifeData.average_depth_meter;
-    float	DepthNow = pDiveState->lifeData.depth_meter;
-    uint32_t *AvgDepthCount = &pDiveState->lifeData.internal.average_depth_meter_Count;
-    uint32_t *AvgDepthTimer = &pDiveState->lifeData.internal.average_depth_last_update_dive_time_seconds_without_surface_time;
-    uint32_t AvgSecondsSinceLast;
-    uint32_t DiveTime = pDiveState->lifeData.dive_time_seconds_without_surface_time;
-
-    if(pDiveState->lifeData.boolResetAverageDepth)
-    {
-        *AvgDepthValue = DepthNow;
-        *AvgDepthCount = 1;
-        *AvgDepthTimer = DiveTime;
-        pDiveState->lifeData.boolResetAverageDepth = 0;
-    }
-    else if (DiveTime > *AvgDepthTimer)
-    {
-        AvgSecondsSinceLast = DiveTime - *AvgDepthTimer;
-        for(int i=0;i<AvgSecondsSinceLast;i++)
-        {
-            *AvgDepthValue = (*AvgDepthValue * *AvgDepthCount + DepthNow) / (*AvgDepthCount + 1);
-            *AvgDepthCount += 1;
-        }
-        *AvgDepthTimer = DiveTime;
-    }
-    if(*AvgDepthCount == 0)
-        *AvgDepthValue = 0;
+    setAvgDepth(pDiveState);
 
     /* Exposure Tissues
      */
@@ -303,14 +276,14 @@
 
 /**
   ******************************************************************************
-  * @brief  simulates ambiant pressure depending on aim depth
+  * @brief  simulates ambient pressure depending on aim depth
   ******************************************************************************
   * @note if aim_depth != actual depth, the depth change within one second
   *       (depending on descent or ascent) rate is calculated
   * @param  SDiveState* pDiveState:
-  * @return float : new ambiant pressure
+  * @return float : new ambient pressure
   */
-static float sim_get_ambiant_pressure(SDiveState * pDiveState)
+static float sim_get_ambient_pressure(SDiveState * pDiveState)
 {
     //Calc next depth
     uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState);
@@ -351,7 +324,7 @@
   * @param  SDiveState* pDiveState:
   * @return void
   */
-void sim_reduce_deco_time_one_second(SDiveState* pDiveState)
+static void sim_reduce_deco_time_one_second(SDiveState* pDiveState)
 {
     SDecoinfo* pDecoinfo;
     if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE)
--- a/Discovery/Src/t7.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/t7.c	Sat Jul 20 21:42:45 2019 +0200
@@ -1864,7 +1864,15 @@
         t7cC.WindowLineSpacing = 95;
         t7cC.WindowNumberOfTextLines = 3;
         text[textpointer] = 0;
+        if(pSettings->FlipDisplay)
+        {
+        	t7cC.WindowY1 -= 40;
+        }
         GFX_write_string(&FontT105,&t7cC,text,1);
+        if(pSettings->FlipDisplay)
+        {
+        	t7cC.WindowY1 += 40;
+        }
         break;
 
     case CVIEW_sensors_mV:
@@ -1894,7 +1902,15 @@
         t7cC.WindowLineSpacing = 95;
         t7cC.WindowNumberOfTextLines = 3;
         text[textpointer] = 0;
+        if(pSettings->FlipDisplay)
+        {
+        	t7cC.WindowY1 -= 40;
+        }
         GFX_write_string(&FontT48,&t7cC,text,1);
+        if(pSettings->FlipDisplay)
+        {
+        	t7cC.WindowY1 += 40;
+        }
         break;
 
     case CVIEW_Compass:
@@ -3085,6 +3101,11 @@
         fCNS = 999;
 
     t7cY0free.WindowY0 = t7cC.WindowY0 - 10;
+    if(settingsGetPointer()->FlipDisplay)
+    {
+    	t7cY0free.WindowY1 = 400;
+    }
+
     t7cY0free.WindowLineSpacing = 48;
     t7cY0free.WindowNumberOfTextLines = 6;
     t7cY0free.WindowTab = 420;
@@ -3109,12 +3130,23 @@
     text[textpointer++] = TXT_FutureTTS;
     text[textpointer++] = '\017';
     text[textpointer++] = 0;
-    t7cY0free.WindowX0 += 10;
-    t7cY0free.WindowY0 += 10;
-    GFX_write_string(&FontT24, &t7cY0free, text, 1);
-    t7cY0free.WindowX0 -= 10;
-    t7cY0free.WindowY0 -= 10;
-
+
+    if(!settingsGetPointer()->FlipDisplay)
+    {
+		t7cY0free.WindowX0 += 10;
+		t7cY0free.WindowY0 += 10;
+		GFX_write_string(&FontT24, &t7cY0free, text, 1);
+		t7cY0free.WindowX0 -= 10;
+		t7cY0free.WindowY0 -= 10;
+    }
+    else
+    {
+		t7cY0free.WindowY1 -= 10;
+		t7cY0free.WindowX1 -= 10;
+		GFX_write_string(&FontT24, &t7cY0free, text, 1);
+		t7cY0free.WindowY1 += 10;
+		t7cY0free.WindowX1 += 10;
+    }
     textpointer = 0;
     text[textpointer++] = '\t';
     textpointer += snprintf(&text[textpointer],10,"\020%01.2f",	stateUsed->lifeData.ppO2);
--- a/Discovery/Src/tCCR.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/tCCR.c	Sat Jul 20 21:42:45 2019 +0200
@@ -46,15 +46,24 @@
     uint16_t checksum;
 } 	SIrLink;
 
-/* Private variables ---------------------------------------------------------*/
-SIrLink receiveHUD[2];
-uint8_t boolHUDdata = 0;
-uint8_t data_old__lost_connection_to_HUD = 1;
+#define HUD_BABBLING_IDIOT			(30u)		/* 30 Bytes received without break */
+#define HUD_RX_FRAME_LENGTH			(15u)		/* Length of a HUD data frame */
+#define HUD_RX_FRAME_BREAK_MS		(100u)		/* Time used to detect a gap between two byte receptions => frame start */
+#define HUD_RX_START_DELAY_MS		(500u)		/* Delay for start of RX function to avoid start of reception while a transmission is ongoing. */
+												/* Based on an assumed cycle time by the sensor of 1 second. Started at time of last RX */
 
-uint8_t receiveHUDraw[16];
+/* Private variables ---------------------------------------------------------*/
+static SIrLink receiveHUD[2];
+static uint8_t boolHUDdata = 0;
+static uint8_t data_old__lost_connection_to_HUD = 1;
 
-uint8_t StartListeningToUART_HUD = 0;
-uint16_t count = 0;
+static uint8_t receiveHUDraw[16];
+
+static uint8_t StartListeningToUART_HUD = 0;
+static uint16_t HUDTimeoutCount = 0;
+
+static __IO ITStatus UartReadyHUD = RESET;
+static uint32_t LastReceivedTick_HUD = 0;
 
 /* Private variables with external access via get_xxx() function -------------*/
 
@@ -289,36 +298,69 @@
     */
 void tCCR_tick(void)
 {
-    if(count < 3 * 10)
-        count++;
+    if(HUDTimeoutCount < 3 * 10)
+        HUDTimeoutCount++;
     else
     {
         data_old__lost_connection_to_HUD = 1;
-        if(count < 20 * 10)
-            count++;
+        if(HUDTimeoutCount < 20 * 10)
+            HUDTimeoutCount++;
         else
             tCCR_fallbackToFixedSetpoint();
     }
 }
 
+void tCCR_SetRXIndication(void)
+{
+	static uint8_t floatingRXCount = 0;
+
+	if((UartIR_HUD_Handle.RxXferSize == HUD_RX_FRAME_LENGTH) || (UartIR_HUD_Handle.RxXferSize == HUD_RX_FRAME_LENGTH - 1))	/* we expected a complete frame */
+	{
+		UartReadyHUD = SET;
+		LastReceivedTick_HUD = HAL_GetTick();
+		floatingRXCount = 0;
+	}
+	else	/* follow up of error handling */
+	{
+		if(time_elapsed_ms(LastReceivedTick_HUD, HAL_GetTick()) > HUD_RX_FRAME_BREAK_MS)	/* Reception took a while => frame start detected */
+		{
+			HAL_UART_Receive_IT(&UartIR_HUD_Handle, &receiveHUDraw[1], 14);					/* We have already the first byte => get the missing 14 */
+		}
+		else
+		{
+			if(floatingRXCount++ < HUD_BABBLING_IDIOT)
+			{
+				HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1);					/* Start polling of incoming bytes */
+			}
+			else																			/* Significant amount of data comming in without break => disable input */
+			{																				/* by not reactivation HUD RX, no recovery fromthis state */
+				stateUsedWrite->diveSettings.ppo2sensors_deactivated = 0x07;				/* Display deactivation */
+			}
+		}
+	}
+
+}
 
 void tCCR_restart(void)
 {
-    HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/
+	HAL_UART_AbortReceive_IT(&UartIR_HUD_Handle);	/* Called by the error handler. RX will be restarted by control function */
+	StartListeningToUART_HUD = 1;
 }
 
 
 void tCCR_control(void)
 {
-    if((UartReadyHUD == RESET) && StartListeningToUART_HUD)
-    {
-            StartListeningToUART_HUD = 0;
-            HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/
-    }
+
+	if((UartReadyHUD == RESET) && StartListeningToUART_HUD && (time_elapsed_ms(LastReceivedTick_HUD, HAL_GetTick()) > HUD_RX_START_DELAY_MS))
+	{
+		StartListeningToUART_HUD = 0;
+		HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, HUD_RX_FRAME_LENGTH);
+	}
 
     if(UartReadyHUD == SET)
     {
             UartReadyHUD = RESET;
+            StartListeningToUART_HUD = 1;
 
             memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11);
             receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]);
@@ -333,10 +375,18 @@
             if(checksum == receiveHUD[!boolHUDdata].checksum)
             {
                 boolHUDdata = !boolHUDdata;
-                count = 0;
+                HUDTimeoutCount = 0;
                 data_old__lost_connection_to_HUD = 0;
             }
-            StartListeningToUART_HUD = 1;
+            else
+            {
+            	if(data_old__lost_connection_to_HUD)	/* we lost connection, maybe due to RX shift => start single byte read to resynchronize */
+            	{
+            		HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1);
+            		StartListeningToUART_HUD = 0;
+            	}
+            }
+            memset(receiveHUDraw,0,sizeof(receiveHUDraw));
     }
 }
 
--- a/Discovery/Src/tComm.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/tComm.c	Sat Jul 20 21:42:45 2019 +0200
@@ -103,10 +103,11 @@
 uint8_t updateSettingsAndMenuOnExit = 0;
 
 /* Private types -------------------------------------------------------------*/
-#define BYTE_DOWNLOAD_MODE		(0xBB)
-#define BYTE_SERVICE_MODE		(0xAA)
+#define BYTE_DOWNLOAD_MODE			(0xBB)
+#define BYTE_SERVICE_MODE			(0xAA)
 
-#define UART_TIMEOUT_SECONDS	(120u)		/* Timeout for keeping connection open and waiting for data */
+#define UART_TIMEOUT_SECONDS		(120u)		/* Timeout for keeping connection open and waiting for data */
+#define UART_TIMEOUT_LARGE_BLOCK 	(6000u)		/* Timeout (ms) for receiption of an 16K data block (typical RX time ~4,5seconds) */
 
 const uint8_t id_Region1_firmware = 0xFF;
 const uint8_t id_RTE = 0xFE;
@@ -147,8 +148,18 @@
     tCwindow.WindowTab = 400;
     tCwindow.WindowX0 = 20;
     tCwindow.WindowX1 = 779;
-    tCwindow.WindowY0 = 0;
-    tCwindow.WindowY1 = 799;
+
+
+    if(!settingsGetPointer()->FlipDisplay)
+    {
+        tCwindow.WindowY0 = 0;
+        tCwindow.WindowY1 = 479;
+    }
+    else
+    {
+    	tCwindow.WindowY0 = 479 - 390;
+    	tCwindow.WindowY1 = 479 - 25;
+    }
 
     StartListeningToUART = 1;
 
@@ -225,7 +236,7 @@
     }
     else if(display_text[255])
     {
-      display_text[display_text[255]] = 0;
+        display_text[(uint8_t)display_text[255]] = 0;
         releaseFrame(18,tCscreen.FBStartAdress);
         tCscreen.FBStartAdress = getFrame(18);
         write_content_simple(&tCscreen, 0, 800, 480-24, &FontT24,"Exit",CLUT_ButtonSurfaceScreen);
@@ -1194,28 +1205,29 @@
 
 HAL_StatusTypeDef receive_uart_large_size(UART_HandleTypeDef *huart, uint8_t *pData, uint32_t Size)
 {
-    uint16_t length_16_blocks;
-    uint16_t length_16_remainder;
+    uint16_t length_16k_blocks;
+    uint16_t length_16k_remainder;
     uint32_t temp;
     HAL_StatusTypeDef result = HAL_OK;
     uint32_t pDataLocal;
 
-    length_16_blocks = (uint16_t) (Size / 0xFFFF);
-    temp = length_16_blocks;
-    temp *= 0xFFFF;
-    length_16_remainder = (uint16_t) ( Size - temp);
+    length_16k_blocks = (uint16_t) (Size / 0x3FFF);
+    temp = length_16k_blocks;
+    temp *= 0x3FFF;
+    length_16k_remainder = (uint16_t) ( Size - temp);
 
     pDataLocal = (uint32_t)pData;
 
-    while((result == HAL_OK) && length_16_blocks)
+
+    while((result == HAL_OK) && length_16k_blocks)
     {
-        result = HAL_UART_Receive(&UartHandle, (uint8_t *)pDataLocal, 0xFFFF , 60000);
-        pDataLocal += 0xFFFF;
-        length_16_blocks--;
+        result = HAL_UART_Receive(&UartHandle, (uint8_t *)pDataLocal, 0x3FFF , UART_TIMEOUT_LARGE_BLOCK);
+        pDataLocal += 0x3FFF;
+        length_16k_blocks--;
     }
-    if((result == HAL_OK) && length_16_remainder)
+    if((result == HAL_OK) && length_16k_remainder)
     {
-        result = HAL_UART_Receive(&UartHandle, (uint8_t *)pDataLocal, length_16_remainder , 60000);
+        result = HAL_UART_Receive(&UartHandle, (uint8_t *)pDataLocal, length_16k_remainder , UART_TIMEOUT_LARGE_BLOCK);
     }
     return result;
 }
--- a/Discovery/Src/tMenuEditHardware.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/tMenuEditHardware.c	Sat Jul 20 21:42:45 2019 +0200
@@ -134,7 +134,8 @@
     tMenuEdit_init();
     tInfoLog_init();
     tM_build_pages();
-
+    GFX_build_logo_frame();
+    GFX_build_hw_background_frame();
 
     exitEditWithUpdate();
     exitMenuEdit_to_Home();
--- a/Discovery/Src/tMenuHardware.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/tMenuHardware.c	Sat Jul 20 21:42:45 2019 +0200
@@ -153,7 +153,7 @@
         }
 //		textPointer += snprintf(&text[textPointer],25,"%i  %i  %i",button[0],button[1],button[2]);
         textPointer += snprintf(&text[textPointer],25,
-            "%i"
+            "%li"
             "\016\016"
             " %%"
             "\017",
--- a/Discovery/Src/timer.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/timer.c	Sat Jul 20 21:42:45 2019 +0200
@@ -28,18 +28,17 @@
 
 #include "data_central.h"
 
-static long stopWatchTime_Second = 0;
 static _Bool bStopWatch = false;
 static float stopWatchAverageDepth_Meter = 0.0f;
 static long safetyStopCountDown_Second = 0;
+static long stopWatchOffset = 0;
 
 void timer_init(void)
 {
-  stopWatchTime_Second = 0;
   stopWatchAverageDepth_Meter = 0.0f;
   bStopWatch = true;
   safetyStopCountDown_Second = 0;
-
+  stopWatchOffset = 0;
 }
 
 void timer_UpdateSecond(_Bool checkOncePerSecond)
@@ -47,6 +46,7 @@
     static int last_second = -1;
     static _Bool bSafetyStop = false;
     static float last_depth_meter = 0;
+    long stopWatchTime_Second = 0;
 
     if(checkOncePerSecond)
     {
@@ -57,18 +57,13 @@
     }
 
     /** Stopwatch **/
-    if(bStopWatch && stateUsed->lifeData.depth_meter > 1)
+    stopWatchTime_Second = stateUsed->lifeData.dive_time_seconds_without_surface_time - stopWatchOffset;
+    if(bStopWatch && !is_ambient_pressure_close_to_surface(&stateUsedWrite->lifeData))
     {
-        if((stopWatchTime_Second == 0) && (stateUsed->lifeData.dive_time_seconds >= 1))
-        {
-            stopWatchTime_Second = stateUsed->lifeData.dive_time_seconds - 1;
-            stopWatchAverageDepth_Meter = stateUsed->lifeData.average_depth_meter * (stopWatchTime_Second - 1) / stopWatchTime_Second;
-        }
+        if(stopWatchTime_Second == 0)
+            stopWatchAverageDepth_Meter = stateUsed->lifeData.depth_meter;
         else
-        {
             stopWatchAverageDepth_Meter = (stopWatchAverageDepth_Meter * stopWatchTime_Second + stateUsed->lifeData.depth_meter)/ (stopWatchTime_Second + 1);
-            stopWatchTime_Second++;
-        }
     }
 
     /** SafetyStop **/
@@ -125,9 +120,9 @@
 
 void timer_Stopwatch_Restart(void)
 {
-  stopWatchTime_Second = 1;
   stopWatchAverageDepth_Meter = stateUsed->lifeData.depth_meter;
   bStopWatch = true;
+  stopWatchOffset = stateUsed->lifeData.dive_time_seconds_without_surface_time;
 }
 
 void timer_Stopwatch_Stop(void)
@@ -137,7 +132,7 @@
 
 long timer_Stopwatch_GetTime(void)
 {
-  return stopWatchTime_Second;
+  return stateUsed->lifeData.dive_time_seconds_without_surface_time - stopWatchOffset;
 }
 
 float timer_Stopwatch_GetAvarageDepth_Meter(void)
--- a/Discovery/Src/vpm.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Discovery/Src/vpm.c	Sat Jul 20 21:42:45 2019 +0200
@@ -240,7 +240,7 @@
         pDECOINFO->output_stop_length_seconds[i] = 0;
     }
 
-    if(pINPUT->dive_time_seconds < 60)
+    if(pINPUT->dive_time_seconds_without_surface_time < 60)
     {
         vpm_calc_status = CALC_NDL;
         return vpm_calc_status;
--- a/Small_CPU/Inc/batteryGasGauge.h	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Inc/batteryGasGauge.h	Sat Jul 20 21:42:45 2019 +0200
@@ -29,6 +29,8 @@
 
 /* Includes ------------------------------------------------------------------*/
 
+#include <stdint.h>
+
 void init_battery_gas_gauge(void);
 
 float get_voltage(void);
@@ -37,6 +39,7 @@
 void battery_gas_gauge_get_data(void);
 void battery_gas_gauge_set_charge_full(void);
 void battery_gas_gauge_set(float percentage);
+uint8_t battery_gas_gauge_CheckConfigOK(void);
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Inc/compass_LSM303DLHC.h	Mon Jun 17 19:56:38 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    compass_LSM303DLHC.h
-  * @author  heinrichs weikamp gmbh
-  * @date    17-August-2017
-  * @version V0.1.0
-  * @since   17-August-2017
-  * @brief   STMicroelectronics LSM303DLHC accelerometer & magnetometer driver
-  *           
-  @verbatim                 
-  ============================================================================== 
-                        ##### How to use #####
-  ============================================================================== 
-  @endverbatim
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; COPYRIGHT(c) 2017 heinrichs weikamp</center></h2>
-  *
-  ******************************************************************************
-  */ 
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef COMPASS_LSM303DLHC_H
-#define COMPASS_LSM303DLHC_H
-
-/* Exported constants --------------------------------------------------------*/
-
-//#include "compass_LSM303D.h"
-
-#define DLHC_CTRL_REG1_A		0x20
-#define DLHC_CTRL_REG2_A		0x21
-#define DLHC_CTRL_REG3_A		0x22
-#define DLHC_CTRL_REG4_A		0x23
-#define DLHC_CTRL_REG5_A		0x24
-#define DLHC_CTRL_REG6_A		0x25
-
-#define DLHC_CRA_REG_M			0x00
-#define DLHC_CRB_REG_M			0x01
-#define DLHC_MR_REG_M				0x02
-
-#define DLHC_OUT_X_L_M      0x03
-#define DLHC_OUT_X_H_M			0x04
-#define DLHC_OUT_Y_L_M      0x05
-#define DLHC_OUT_Y_H_M			0x06
-#define DLHC_OUT_Z_L_M			0x07
-#define DLHC_OUT_Z_H_M			0x08
-
-// identisch mit 303D
-#define DLHC_OUT_X_L_A			0x28
-#define DLHC_OUT_X_H_A			0x29
-#define DLHC_OUT_Y_L_A			0x2A
-#define DLHC_OUT_Y_H_A			0x2B
-#define DLHC_OUT_Z_L_A			0x2C
-#define DLHC_OUT_Z_H_A			0x2D
-
-#endif /* COMPASS_LSM303DLHC_H */
-
-/******************* (C) COPYRIGHT 2017 heinrichs weikamp *****END OF FILE****/
--- a/Small_CPU/Src/baseCPU2.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/baseCPU2.c	Sat Jul 20 21:42:45 2019 +0200
@@ -162,7 +162,7 @@
 // See CPU2-RTE.ld
 const SFirmwareData cpu2_FirmwareData __attribute__(( section(".firmware_data") ))= {
 		.versionFirst = 1,
-		.versionSecond = 8,
+		.versionSecond = 9,
 		.versionThird = 0,
 		.versionBeta = 0,
 
@@ -170,8 +170,8 @@
 		.signature = "mh",
 
 		.release_year = 19,
-		.release_month = 5,
-		.release_day = 6,
+		.release_month = 7,
+		.release_day = 1,
 		.release_sub = 0,
 
 		/* max 48 with trailing 0 */
@@ -302,19 +302,25 @@
 
 /*	printf("CPU2-RTE running...\n"); */
 
+	HAL_Delay(100);
+
 	MX_I2C1_Init();
-	if (global.I2C_SystemStatus != HAL_OK) {
+	if (global.I2C_SystemStatus != HAL_OK)
+	{
 		if (MX_I2C1_TestAndClear() == GPIO_PIN_RESET) {
 			MX_I2C1_TestAndClear(); // do it a second time
 		}
 		MX_I2C1_Init();
 	}
 
+
+
 	//dangerous:	TM_OTP_Write(0,0, 0x01);
 #ifdef REGULAR_RUN
 	global.sensorError[SENSOR_PRESSURE_ID] = init_pressure();
 	global.I2C_SystemStatus = global.sensorError[SENSOR_PRESSURE_ID];
-	if (global.I2C_SystemStatus != HAL_OK) {
+	if (global.I2C_SystemStatus != HAL_OK)
+	{
 		if (MX_I2C1_TestAndClear() == GPIO_PIN_RESET) {
 			MX_I2C1_TestAndClear(); // do it a second time
 		}
@@ -325,7 +331,11 @@
 
 	global.dataSendToMaster.sensorErrors =
 			global.sensorError[SENSOR_PRESSURE_ID];
-	init_surface_ring();
+
+	if(is_init_pressure_done())
+	{
+		init_surface_ring();
+	}
 	init_battery_gas_gauge();
 	HAL_Delay(10);
 	battery_gas_gauge_get_data();
--- a/Small_CPU/Src/batteryGasGauge.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/batteryGasGauge.c	Sat Jul 20 21:42:45 2019 +0200
@@ -22,6 +22,7 @@
   ******************************************************************************
   */ 
 /* Includes ------------------------------------------------------------------*/
+#include <string.h>	/* memset */
 #include "batteryGasGauge.h"
 #include "baseCPU2.h"
 #include "stm32f4xx_hal.h"
@@ -71,6 +72,25 @@
 	I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
 }
 
+uint8_t battery_gas_gauge_CheckConfigOK(void)
+{
+	#ifdef OSTC_ON_DISCOVERY_HARDWARE
+		return;
+	#endif
+
+	uint8_t retval = 0;
+	uint8_t bufferReceive[10];
+
+	memset(bufferReceive,0,sizeof(bufferReceive));
+
+	I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10);
+	if(bufferReceive[1] == 0xf8)
+	{
+		retval = 1;
+	}
+	return retval;
+}
+
 static void disable_adc(void)
 {
 	uint8_t buffer[2];
--- a/Small_CPU/Src/compass.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/compass.c	Sat Jul 20 21:42:45 2019 +0200
@@ -32,7 +32,6 @@
 
 #include "compass.h"
 #include "compass_LSM303D.h"
-#include "compass_LSM303DLHC.h"
 
 #include "i2c.h"
 #include "spi.h"
--- a/Small_CPU/Src/i2c.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/i2c.c	Sat Jul 20 21:42:45 2019 +0200
@@ -31,39 +31,51 @@
 void HAL_I2C_Send_One_CLOCK(void)
 {
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_RESET);
-	HAL_Delay(10);
+	HAL_Delay(1); 
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_SET);
-	HAL_Delay(10);
+	HAL_Delay(1);
 }
 
 GPIO_PinState MX_I2C1_TestAndClear(void)
 {
+	GPIO_PinState retval;
+	uint8_t repeatcnt = 3;
+
 	I2C_DeInit();
 	HAL_I2C_ManualControl_MspInit();
-	for(int i=0; i<9;i++)
+	
+/* The SDA line is expected to be HIGH if no com is pending => send dummy clock signals if that is not the case */
+	do
 	{
-		if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
-			HAL_I2C_Send_One_CLOCK();
-		else
-			break;
-	}
-	return HAL_I2C_Read_Data_PIN();
+		for(int i=0; i<20;i++)
+		{
+			if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
+				HAL_I2C_Send_One_CLOCK();
+			else
+				break;
+		}
+		retval = HAL_I2C_Read_Data_PIN();
+	}while ((repeatcnt-- > 0) && (retval != GPIO_PIN_SET));
+
+	return retval;
 }
 
 HAL_StatusTypeDef MX_I2C1_Init(void)
 {
-	I2cHandle.Instance             = I2Cx;
+  I2cHandle.Instance             = I2Cx;
   I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
-  I2cHandle.Init.ClockSpeed      = 100000;//400000; REDUCED for compatibility with  HMC5583L + MMA8452Q
-  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
+  I2cHandle.Init.ClockSpeed      = 88000; /* Reduced to avoid behavior described in errata: Mismatch on the “Setup time for a repeated Start condition” */
+  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;				/* don't care if not in fast mode */
   I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
   I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
-  I2cHandle.Init.OwnAddress1     = 0x01;
+  I2cHandle.Init.OwnAddress1     = 0x01;						/* don't care because of master mode */
+
+/* According to documentation setting filters before I2C initialization is recommended */
+	/* HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED); */
+	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	global.I2C_SystemStatus = HAL_I2C_Init(&I2cHandle);
-	HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED);
-	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	if(global.dataSendToSlavePending)
 	{
@@ -85,12 +97,13 @@
 	i2c_errors++;
 }
 
+
 HAL_StatusTypeDef I2C_Master_Transmit(  uint16_t DevAddress, uint8_t *pData, uint16_t Size)
 {
 	if(global.I2C_SystemStatus != HAL_OK)
 		return global.I2C_SystemStatus;
 
-	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 2);
+	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 10);
 	if(global.I2C_SystemStatus != HAL_OK)
 	{
 		I2C_Error_count();
--- a/Small_CPU/Src/pressure.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/pressure.c	Sat Jul 20 21:42:45 2019 +0200
@@ -28,7 +28,7 @@
  the last 30 minutes will be saved once per minute in a endless loop
  at the beginning of a dive the oldest value will be used
 */
-
+#include "math.h"
 #include "scheduler.h"
 #include "pressure.h"
 #include "i2c.h"
@@ -46,6 +46,9 @@
 #define CMD_ADC_4096 0x08 // ADC OSR=4096
 #define CMD_PROM_RD 0xA0 // Prom read command
 
+#define PRESSURE_HISTORY_SIZE			(8u)
+#define PRESSURE_JUMP_VALID_MBAR	    (500.0f)		/* values are measure several times a second => jumps > 5m very unlikely */
+
 static uint16_t get_ci_by_coef_num(uint8_t coef_num);
 //void pressure_calculation_new(void);
 //void pressure_calculation_old(void);
@@ -74,10 +77,12 @@
 */
 
 static float ambient_temperature = 0;
-static float ambient_pressure_mbar = 0;
-static float surface_pressure_mbar = 1000;
+static float ambient_pressure_mbar = 1000.0;
+static float surface_pressure_mbar = 1000.0;
 static float surface_ring_mbar[31] = { 0 };
 
+static float pressure_history_mbar[PRESSURE_HISTORY_SIZE];
+
 uint8_t secondCounterSurfaceRing = 0;
 
 float get_temperature(void)
@@ -104,6 +109,13 @@
 	surface_pressure_mbar = ambient_pressure_mbar;
 }
 
+void init_pressure_history(void)
+{
+	for(int i=0; i<PRESSURE_HISTORY_SIZE; i++)
+	{
+		pressure_history_mbar[i] = 1000.0;
+	}
+}
 
 /* the ring has one place with 0
  * after that comes the oldest value
@@ -119,17 +131,20 @@
 	
 	secondCounterSurfaceRing = 0;
 	
-	int hole;
-	for(hole=30;hole>0;hole--)
-		if(surface_ring_mbar[hole] == 0) { break; }
-
-	surface_ring_mbar[hole] = ambient_pressure_mbar;
+	if(is_init_pressure_done())
+	{
+		int hole;
+		for(hole=30;hole>0;hole--)
+			if(surface_ring_mbar[hole] == 0) { break; }
 
-	hole++;
-	if(hole > 30)
-		hole = 0;
-	surface_pressure_mbar = surface_ring_mbar[hole];
-	surface_ring_mbar[hole] = 0;
+		surface_ring_mbar[hole] = ambient_pressure_mbar;
+
+		hole++;
+		if(hole > 30)
+			hole = 0;
+		surface_pressure_mbar = surface_ring_mbar[hole];
+		surface_ring_mbar[hole] = 0;
+	}
 }
 
 #ifdef DEMOMODE
@@ -209,29 +224,6 @@
 }
 #endif
 
-
-/* called just once on power on */
-/* TBD old DR5 code? */
-void init_pressure_DRx(void)
-{
-	uint8_t resetCommand[1] = {0x1E};
-
-	I2C_Master_Transmit(  DEVICE_PRESSURE, resetCommand, 1);
-	HAL_Delay(3);
-
-	C[1] =	get_ci_by_coef_num(0x02);
-	C[2] =	get_ci_by_coef_num(0x04);
-	C[3] =	get_ci_by_coef_num(0x06);
-	C[4] =	get_ci_by_coef_num(0x08);
-	C[5] =	get_ci_by_coef_num(0x0A);
-	C[6] =	get_ci_by_coef_num(0x0C);
-	
-	C5_x_2p8  = C[5] * 256;
-	C2_x_2p16 = C[2] * 65536;
-	C1_x_2p15 = C[1] * 32768;
-	pressure_update();
-}
-
 uint8_t is_init_pressure_done(void)
 {
 	return pressureSensorInitSuccess;
@@ -243,7 +235,10 @@
 	buffer[0] = 0x1e;
 	uint8_t retValue = 0xFF;
 	
-	
+	pressureSensorInitSuccess = false;
+	init_pressure_history();
+
+/* Send reset request to pressure sensor */
 	retValue = I2C_Master_Transmit(  DEVICE_PRESSURE, buffer, 1);
 	if(retValue != HAL_OK)
 	{
@@ -264,8 +259,10 @@
 	if(global.I2C_SystemStatus == HAL_OK)
 	{
 		pressureSensorInitSuccess = 1;
+		retValue = pressure_update();
+
 	}
-	return pressure_update();
+	return retValue;
 }
 
 
@@ -416,6 +413,40 @@
 	pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015();
 }
 
+static uint8_t pressure_plausible(float pressurevalue)
+{
+	static uint8_t pressurewriteindex = 0;
+	uint8_t retval = 0;
+	uint8_t index;
+	float pressure_average = 0;
+
+	for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
+	{
+		pressure_average += pressure_history_mbar[index];
+	}
+	pressure_average /= PRESSURE_HISTORY_SIZE;
+	if(pressure_average == 1000.0) /* first pressure calculation */
+	{
+		if(fabs(pressurevalue - pressure_average) < 11000.0)  /* just in case a reset occure during dive assume value equal < 100m as valid */
+		{
+			for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
+			{
+				pressure_history_mbar[index] = pressurevalue;	/* set history to current value */
+				retval = 1;
+			}
+		}
+	}
+	else
+	{
+		if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR)
+		pressure_history_mbar[pressurewriteindex++] = pressurevalue;
+		pressurewriteindex &= 0x7;	/* wrap around if necessary */
+		retval = 1;
+	}
+
+	return retval;
+}
+
 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void)
 {
 	uint32_t local_D1; // ADC value of the pressure conversion
@@ -426,6 +457,8 @@
 	int64_t local_OFF; // offset at actual temperature
 	int64_t local_SENS; // sensitivity at actual temperature
 
+	float calc_pressure;
+
 	int64_t T2;
 	int64_t OFF2;
 	int64_t SENS2;
@@ -479,7 +512,12 @@
 								/  8192 );//     )) / 10; // pow(2,21), pow(2,13)
 
 	ambient_temperature 	= ((float)local_Tx100) / 100;
-	ambient_pressure_mbar	= ((float)local_Px10) / 10;
+
+	calc_pressure = ((float)local_Px10) / 10;
+	if(pressure_plausible(calc_pressure))
+	{
+		ambient_pressure_mbar = calc_pressure;
+	}
 }
 
 
--- a/Small_CPU/Src/scheduler.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/scheduler.c	Sat Jul 20 21:42:45 2019 +0200
@@ -85,7 +85,6 @@
 static void schedule_update_timer_helper(int8_t thisSeconds);
 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow);
 
-_Bool scheduleCheck_pressure_reached_dive_mode_level(void);
 void scheduleSetDate(SDeviceLine *line);
 
 /* Exported functions --------------------------------------------------------*/
@@ -618,10 +617,7 @@
 			{
 				MX_I2C1_TestAndClear();
 				MX_I2C1_Init();
-				if(!is_init_pressure_done())
-				{
-					init_pressure();
-				}
+				init_pressure();
 			}
 		}
 		if(ticksdiff >= 1000)
@@ -771,7 +767,7 @@
 				copyPressureData();
 				Scheduler.counterPressure100msec++;
 				
-				if(scheduleCheck_pressure_reached_dive_mode_level())
+				if (!is_ambient_pressure_close_to_surface(&global.lifeData))
 					global.mode = MODE_DIVE;
 		}
 		
@@ -847,14 +843,23 @@
 			copyBatteryData();
 			copyDeviceData();
 
-			// new hw 170523
+/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */
 			if(global.I2C_SystemStatus != HAL_OK)
 			{
 				MX_I2C1_TestAndClear();
 				MX_I2C1_Init();
-				if(!is_init_pressure_done())
+				if(global.I2C_SystemStatus == HAL_OK)
 				{
 					init_pressure();
+					if(is_init_pressure_done())		/* Init surface data with initial measurement */
+					{
+						init_surface_ring();
+					}
+
+					if(!battery_gas_gauge_CheckConfigOK())
+					{
+						 init_battery_gas_gauge();
+					}
 				}
 			}
 		}
@@ -998,6 +1003,17 @@
 		MX_I2C1_Init();
 		pressure_sensor_get_pressure_raw();
 
+/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */
+		if(global.I2C_SystemStatus != HAL_OK)
+		{
+			MX_I2C1_TestAndClear();
+			MX_I2C1_Init();
+			if(global.I2C_SystemStatus == HAL_OK)
+			{
+				init_pressure();
+			}
+		}
+
 		if(secondsCount >= 30)
 		{
 			pressure_sensor_get_temperature_raw();
@@ -1029,7 +1045,7 @@
 			}
 		}
 
-		if(scheduleCheck_pressure_reached_dive_mode_level())
+		if (!is_ambient_pressure_close_to_surface(&global.lifeData))
 			global.mode = MODE_BOOT;
 
 		scheduleUpdateLifeData(2000);
@@ -1046,27 +1062,6 @@
 
 /* Private functions ---------------------------------------------------------*/
 
-
-/**
-  ******************************************************************************
-	* @brief   scheduleCheck_pressure_reached_dive_mode_level
-  * @author  heinrichs weikamp gmbh
-  * @version V0.0.1 from inline code
-  * @date    09-Sept-2015
-  ******************************************************************************
-  */
-_Bool scheduleCheck_pressure_reached_dive_mode_level(void)
-{
-		if(get_pressure_mbar() > 1160)
-			return 1;
-		else
-		if((global.mode == MODE_SURFACE) && (get_pressure_mbar() > (get_surface_mbar() + 100)) && (get_surface_mbar() > 880))
-			return 1;
-		else
-			return 0;
-}
-		
-
 /**
   ******************************************************************************
 	* @brief   scheduleUpdateLifeData / calculates tissues
@@ -1582,9 +1577,15 @@
 }
 
 /* same as in data_central.c */
-_Bool is_ambient_pressure_close_to_surface(SLifeData *lifeDataCall)
+_Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData)
 {
-	if(lifeDataCall->pressure_ambient_bar < (lifeDataCall->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f
+	if(lifeData->pressure_ambient_bar == INVALID_PREASURE_VALUE)	/* as long as no valid data is available expect we are close to surface */
+	{
+		return true;
+	}
+	if (lifeData->pressure_ambient_bar > 1.16)
+		return false;
+	else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f
 		return true;
 	else
 		return false;
--- a/Small_CPU/Src/stm32f4xx_hal_msp_v3.c	Mon Jun 17 19:56:38 2019 +0200
+++ b/Small_CPU/Src/stm32f4xx_hal_msp_v3.c	Sat Jul 20 21:42:45 2019 +0200
@@ -110,7 +110,7 @@
   /* I2C TX GPIO pin configuration  */
   GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;
   GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
-  GPIO_InitStruct.Pull      = GPIO_PULLUP;
+  GPIO_InitStruct.Pull      = GPIO_NOPULL;
   GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
   GPIO_InitStruct.Alternate = I2Cx_SCL_AF;
   
@@ -124,10 +124,14 @@
     
   /*##-3- Configure the NVIC for I2C #########################################*/   
   /* NVIC for I2C1 */
+
+ /* The callbacks are not used => no need to activate the interrupts */
+ /*
   HAL_NVIC_SetPriority(I2Cx_ER_IRQn, 1, 2);
   HAL_NVIC_EnableIRQ(I2Cx_ER_IRQn);
   HAL_NVIC_SetPriority(I2Cx_EV_IRQn, 1, 3);
   HAL_NVIC_EnableIRQ(I2Cx_EV_IRQn);
+*/
 }
 
 /**