changeset 1048:493a5903ec20 GasConsumption

Merge with 9d9d506a82d3162b6b2323819cc08652887d7dd4 (Bootloader)
author Ideenmodellierer
date Sat, 15 Nov 2025 19:29:44 +0100
parents 6fb16ca39125 (diff) 9d9d506a82d3 (current diff)
children d91345e9c009
files BootLoader/Src/base_bootlader.c BootLoader/Src/display_mini.c BootLoader/Src/externLogbookFlash_mini.c BootLoader/Src/gfx_engine_mini.c BootLoader/Src/ostc_mini.c BootLoader/Src/tComm_mini.c Discovery/Inc/tComm.h OtherSources/data_central_mini.c
diffstat 99 files changed, 5315 insertions(+), 2037 deletions(-) [+]
line wrap: on
line diff
--- a/BootLoader/Src/base_bootlader.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/base_bootlader.c	Sat Nov 15 19:29:44 2025 +0100
@@ -262,8 +262,8 @@
 	.signature = "mh",
 
 	.release_year   = 25,
-	.release_month  = 1,
-	.release_day    = 13,
+	.release_month  = 11,
+	.release_day    = 15,
 	.release_sub    = 0,
 
 	/* max 48 with trailing 0 */
@@ -280,7 +280,7 @@
 {
 
 	// first 52 bytes
-	.primarySerial = 0xFFFF,
+	.primarySerial = 0x06a4,
 	.primaryLicence	= 0x00,
 	.revision8bit = 0x02,
 	.production_year = 0x19,
@@ -688,7 +688,7 @@
 	tComm_init();
 
 	tInfo_button_text("exit","","sleep");
-	tInfo_newpage("bootloader 251102");
+	tInfo_newpage("bootloader 251115");
 	tInfo_write("start bluetooth");
 	tInfo_write(textVersion);
 #if 0
--- a/BootLoader/Src/display_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/display_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -175,7 +175,7 @@
 	aTxBuffer[1] = OLED_VFP_SET_13h;
 	send((uint8_t*)aTxBuffer, 2);
 	aTxBuffer[0] = 0x72;
-	aTxBuffer[1] = 0x08;
+	aTxBuffer[1] = 0x0C;
 	send((uint8_t*)aTxBuffer, 2);
 
 	aTxBuffer[0] = 0x70;
--- a/BootLoader/Src/externLogbookFlash_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/externLogbookFlash_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -80,17 +80,6 @@
 
 #define HEADER2OFFSET 0x400
 
-typedef enum{
-	EF_HEADER,
-	EF_SAMPLE,
-	EF_DEVICEDATA,
-	EF_VPMDATA,
-	EF_SETTINGS,
-	EF_FIRMWARE,
-	EF_FIRMWARE2,
-}which_ring_enum;
-
-
 typedef struct{
 uint8_t IsBusy:1;
 uint8_t IsWriteEnabled:1;
@@ -320,7 +309,11 @@
 		}
 		else if(pSample2)
 		{
-			actualAddress += length1;
+			/* actualAddress += length1; do dummy read to get EEPROM to the correct address */
+			for(uint32_t i = 0; i<length1; i++)
+			{
+				ext_flash_read_block(&pSample2[0], EF_FIRMWARE2);
+			}
 			for(uint32_t i = 0; i<length2; i++)
 			{
 				ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);
--- a/BootLoader/Src/gfx_engine_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/gfx_engine_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -850,7 +850,7 @@
 
 
 /* this is NOT fast nor optimized */
-static void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color)
+void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color)
 {
 	uint16_t* pDestination;
 
@@ -2544,7 +2544,7 @@
 
 #define		Vsync_d1	2
 #define		VFP_d1		4	// make sure this value * VSYNC is also set in display.c for OLED_VFP_SET
-#define		VBP_d1		4	// make sure this value * VSYNC is also set in display.c for OLED_VBP_SET
+#define		VBP_d1		6	// make sure this value * VSYNC is also set in display.c for OLED_VBP_SET
 
   /* Horizontal synchronization width = Hsync - 1 */
   LtdcHandle.Init.HorizontalSync = Hsync_d1 - 1;
--- a/BootLoader/Src/ostc_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/ostc_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -350,7 +350,7 @@
     UartHandle.Init.StopBits   = UART_STOPBITS_1;
     UartHandle.Init.Parity     = UART_PARITY_NONE;
     UartHandle.Init.Mode       = UART_MODE_TX_RX;
-    HAL_UART_Init(&UartHandle);
+    /* HAL_UART_Init(&UartHandle); moved final init step into BT config function to avoid problems while module power is off */
 
 #ifdef USART_PIEZO
     UartPiezoTxHandle.Instance        = USART_PIEZO;
--- a/BootLoader/Src/tComm_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/BootLoader/Src/tComm_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -750,16 +750,16 @@
     // get model + features
     case 0x60:
         aTxBuffer[count++] = 0x00; // hardware descriptor HIGH byte
-        aTxBuffer[count++] = 0x3B; // hardware descriptor LOW byte // 0x3B is OSTC4 //  0x1A is OTSC3
+        aTxBuffer[count++] = 0x3B; // hardware descriptor LOW byte // 0x3B is OSTC 4/5 //  0x1A is OTSC3
         aTxBuffer[count++] = 0x00; // feature descriptor HIGH byte
         aTxBuffer[count++] = 0x00; // feature descriptor LOW byte
-        aTxBuffer[count++] = 0x43; // model id
+        aTxBuffer[count++] = 0x44; // model id OSTC5
         aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
 
     // get model
     case 0x6A:
-        aTxBuffer[count++] = 0x3B; // 0x3B is OSTC4 //  0x1A is OTSC3
+        aTxBuffer[count++] = 0x3B; // 0x3B is OSTC 4/5 //  0x1A is OTSC3
         aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
 
@@ -1076,6 +1076,7 @@
     const uint8_t id_Region1_firmware = 0xFF;
     const uint8_t id_RTE = 0xFE;
     uint8_t textpointer = 0;
+    uint32_t index = 0;
 
     //Get length
     if(HAL_UART_Receive(&UartHandle, sBuffer, 4,5000)!= HAL_OK) // 58000
@@ -1233,7 +1234,7 @@
             return 0xFF;
     }
     else
-    //if(region == 2)
+    if(id == id_FONT)
     {
         uint8_t ptr = 0;
         ptr += gfx_number_to_string(7,0,&display_text[ptr],lengthTotal);
@@ -1248,7 +1249,7 @@
     }
 
 
-    // only non RTE !!
+    /* only non RTE !! (at this point RTE path already performed a return some lines above */
     uint8_t* pBufferCompare = (uint8_t*)getFrame(20);
     ByteCompareStatus = 0;
 
@@ -1262,14 +1263,14 @@
 
         if(lengthCompare != length1)
             ByteCompareStatus = 10000;
-        for(int i = 0; i < length1; i++)
+        for(index = 0; index < length1; index++)
         {
-            if(pBuffer1[0] != pBufferCompare[0])
+            if(pBuffer1[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
     }
     else
-    //if(region == 2)
+    if(id == id_FONT)
     {
         /* upper region firmware can be larger (1MB) */
         if(ext_flash_read_firmware2(0, pBufferCompare,4, 0,0) != 0xFFFFFFFF)
@@ -1281,16 +1282,16 @@
             ByteCompareStatus = 10000;
         if(offsetTotal != offsetCompare)
             ByteCompareStatus += 20000;
-        for(int i = 0; i < length1; i++)
+        for(index = 0; index < length1; index++)
         {
-            if(pBuffer1[0] != pBufferCompare[0])
+            if(pBuffer1[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
 
         lengthCompare = ext_flash_read_firmware2(0, 0,768000, pBufferCompare,768000);
-        for(int i = 0; i < length2; i++)
+        for(index = 0; index < length2; index++)
         {
-            if(pBuffer2[0] != pBufferCompare[0])
+            if(pBuffer2[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
     }
@@ -1553,7 +1554,14 @@
 			{
 				if(indexRef != 0)
 				{
-					indexRef = 0;
+					if((answerOkay[0] == aRxBuffer[indexBuf]))
+					{
+						indexRef = 1;
+					}
+					else
+					{
+						indexRef = 0;
+					}
 				}
 			}
 			indexBuf++;
@@ -1747,12 +1755,13 @@
 
 void tComm_StartBlueModConfig()
 {
+	HAL_UART_Init(&UartHandle);
+
 #ifdef OSTC4_HW
 	uint8_t answer = HAL_OK;
 	uint8_t RxBuffer[UART_CMD_BUF_SIZE];
 	uint8_t index = 0;
 
-
 	BmTmpConfig = BM_CONFIG_ECHO;
 	do	/* flush RX buffer */
 	{
@@ -1838,16 +1847,19 @@
 										BmTmpConfig++;
 									break;
 			case BM_INIT_POWERON:		MX_Bluetooth_PowerOn();
+										HAL_UART_Init(&UartHandle);
 										BmTmpConfig++;
 									break;
-			case BM_INIT_TRIGGER_ON:	HAL_Delay(2000);
-										HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+			case BM_INIT_COMMAND_ON:	HAL_Delay(2600);
+										HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_SET);
 										BmTmpConfig++;
 									break;
+#if 0
 			case BM_INIT_TRIGGER_OFF:	HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_SET);
 										HAL_Delay(2000);
 										BmTmpConfig++;
 									break;
+#endif
 			case BM_INIT_ECHO:
 			case BM_INIT_ECHO2:			sprintf(TxBuffer,"ATE0\r");
 				break;
@@ -1878,6 +1890,7 @@
 									break;
 			case BM_INIT_DONE:			tInfo_write("Done");
 										BmTmpConfig = BM_CONFIG_DONE;
+										HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
 									break;
 			default:
 				break;
--- a/Common/CPU1-F429.ld	Sun Nov 02 19:30:58 2025 +0100
+++ b/Common/CPU1-F429.ld	Sat Nov 15 19:29:44 2025 +0100
@@ -208,7 +208,7 @@
     /* Define Known Address for Each Font */
     /* Flash Sector 23 is protected (bootloader font + image) => use end of sector 22 */
 
-.lower_fonts 	0x080A0000  : {
+.lower_fonts 	0x080AA000  : {
 	 *(.lower_fonts.image_data_*)
 	 
 	 *(.lower_fonts.*) 
--- a/Common/Inc/configuration.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Common/Inc/configuration.h	Sat Nov 15 19:29:44 2025 +0100
@@ -72,8 +72,14 @@
 /* Enable to have CO2 sensor functionality available */
 #define ENABLE_CO2_SUPPORT
 
-/* Enable to have GPS sensor functionality available */
-/* #define ENABLE_GNSS_SUPPORT */
+/* Enable to have external GPS sensor functionality available */
+/*#define ENABLE_GNSS_EXTERN*/
+
+/* Enable to have internal (OSTC5) GPS sensor functionality available */
+/*#define ENABLE_GNSS_INTERN*/
+
+/* Enable to provide UTC time to GNSS module at startup. ! CAUTION ! Incorrect time will reduce performance of module */
+/* #define ENABLE_GNSS_TIME_INIT */
 
 /* Enable to have Sentinel rebreather interface available */
 /* #define ENABLE_SENTINEL_MODE */
@@ -90,11 +96,20 @@
 /* Enable to have a faster transfer speed between bluetooth module and CPU */
 #define ENABLE_FAST_COMM
 
-/* Enable to have position sensor support active */
-/* #define ENABLE_GPIO_V2 */
+/* Enable to have support of Polar HC10 heartbeat sensor active */
+/* #define ENABLE_PULSE_SENSOR_BT */
 
 /* Enable RTE sleep mode debugging */
 /* #define ENABLE_SLEEP_DEBUG */
 
+/* Enable to receive data from the radio connection usart */
+/* #define ENABLE_USART_RADIO */
+
+/* Enable to show messages which are den during runtime in a popup window */
+/* #define ENABLE_LOGGER_WINDOW */
+
+/* Enable to have the possibility to switch between four individual sets of settings */
+/* #define ENABLE_SETTING_PROFILES */
+
 
 #endif
--- a/Common/Inc/data_central.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Common/Inc/data_central.h	Sat Nov 15 19:29:44 2025 +0100
@@ -44,7 +44,8 @@
 #define EXT_INTERFACE_SENSOR_CNT	(8u)		/* 1 MUX + 7 sensors may be connected to the external interface (1 MUX + 3 ADC + 4 UART) */
 #define EXT_INTERFACE_MUX_OFFSET	(3u)		/* the sensor struct starts with 3 ADC sensors */
 
-#define EXT_INTERFACE_BUZZER_ON_TIME_MS (2000u)		/* max time the buzzer should be active without break */
+#define EXT_INTERFACE_BUZZER_ON_TIME_MS (2000u)		/* max time the buzzer should be active without break (continuous Operation) */
+#define EXT_INTERFACE_BUZZER_PING_TIME_MS (1000u)	/* max time the buzzer should be active for single ping */
 #define EXT_INTERFACE_BUZZER_STABLE_TIME_MS (500u)	/* min time a state (ON / OFF) should be stable before it may be changed */
 
 
@@ -343,6 +344,8 @@
     uint16_t info_compassHeadingUpdate;
     int16_t gnssPositionUpdate;
     SGnssCoord info_gnssPosition;
+    int16_t scrubberState;
+    uint16_t info_scrubberState;
 } SEvents;
 
 
@@ -591,10 +594,13 @@
 
 uint8_t drawingColor_from_ascentspeed(float speed);
 
+void formatStringOfTime(char* pString, uint8_t strLen, RTC_TimeTypeDef Stime, uint8_t showAlive, uint8_t showSeconds);
 void convertStringOfDate_DDMMYY(char* pString, uint8_t strLen, uint8_t day, uint8_t month, uint8_t year);
 void getStringOfFormat_DDMMYY(char* pString, uint8_t strLen);
 void convertUTCToLocal(uint8_t utcHours, uint8_t utcMinutes, uint8_t* pLocalHours, uint8_t* pLocalMinutes);
 
 uint8_t calculateSlowExit(uint16_t* pCountDownSec, float* pExitDepthMeter, uint8_t* pColor);
 
+bool isScrubberTimerEnabled(const SSettings *settings);
+bool isScrubberTimerRunning(const SDiveState *diveState, const SSettings *settings);
 #endif // DATA_CENTRAL_H
--- a/Common/Inc/data_exchange.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Common/Inc/data_exchange.h	Sat Nov 15 19:29:44 2025 +0100
@@ -339,7 +339,7 @@
 
 	uint8_t revisionHardware;
 	uint8_t revisionCRCx0x7A;
-	uint8_t spare1_3;
+	uint8_t displayVersion;
 	uint8_t spare1_4;
 
 	uint8_t setAccidentFlag;
--- a/Common/Inc/settings.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Common/Inc/settings.h	Sat Nov 15 19:29:44 2025 +0100
@@ -32,8 +32,7 @@
 
 // From Common/Inc:
 #include "FirmwareData.h"
-
-//#include "data_central.h"
+#include "firmwareEraseProgram.h"
 
 #include "global_constants.h"
 // From Common/Drivers/
@@ -76,10 +75,16 @@
 #define PRESSURE_OFFSET_LIMIT_MBAR	50
 
 #define MAX_COMPASS_COMP 		(2u)
+
+#define MAX_COMPASS_DECLINATION_DEG 99
+
 #define MAX_VIEWPORT_MODE 		(0x7F)
 
-#define MAX_SCRUBBER_TIME 		(999u)
+#define MAX_SCRUBBER_TIME		(999u)
 #define MIN_SCRUBBER_TIME       -99
+#define SCRUBBER_WARNING_TIME   30
+#define SCRUBBER_ERROR_TIME     0
+
 #define MIN_PPO2_SP_CBAR		(40u)
 
 #define PSCR_MAX_O2_DROP		(15u)
@@ -90,6 +95,8 @@
 
 #define FUTURE_SPARE_SIZE		(0u)		/* Applied for reuse of old, not used, scooter block (was 32 bytes)*/
 
+#define NUMBER_OF_PROFILES		(4u)
+
 typedef enum
 {
 	O2_SENSOR_SOURCE_OPTIC = 0,
@@ -105,7 +112,7 @@
 
 typedef enum
 {
-	SCRUB_TIMER_OFF = 0,
+	INVALID_SCRUB_TIMER_OFF = 0,
 	SCRUB_TIMER_MINUTES,
 	SCRUB_TIMER_PERCENT,
 	SCRUB_TIMER_END
@@ -255,7 +262,7 @@
 	uint8_t co2_sensor_active;									/* redefined in 0xFFFF0021 */
 	uint8_t ext_uart_protocol;									/* redefined in 0xFFFF0022 */
 
-	uint8_t scubberActiveId;									/* redefined in 0xFFFF0023 */
+	uint8_t scrubberActiveId;									/* redefined in 0xFFFF0023 */
 	SScrubberData scrubberData[2];
 	uint8_t ext_sensor_map_Obsolete[5];
 	uint8_t buttonLockActive;									/* redefined in 0xFFFF0025 */
@@ -324,35 +331,11 @@
 	/* new in 0xFFFF002c */
 	StimeZone timeZone;
 	uint8_t warningBuzzer;
+	/* new in 0xFFFF002d */
+	uint8_t profileName[NUMBER_OF_PROFILES][9];
+	uint8_t activeProfile;
 } SSettings;
 
-typedef struct
-{
-	// 8 bytes
-	uint16_t primarySerial;
-	uint8_t primaryLicence;
-	uint8_t revision8bit;
-	uint8_t production_year;
-	uint8_t production_month;
-	uint8_t production_day;
-	uint8_t production_bluetooth_name_set;
-
-	// 44 bytes
-	char production_info[44];
-
-	// 8 bytes
-	uint16_t secondarySerial;
-	uint8_t secondaryLicence;
-	uint8_t secondaryReason8bit;
-	uint8_t secondary_year;
-	uint8_t secondary_month;
-	uint8_t secondary_day;
-	uint8_t secondary_bluetooth_name_set;
-
-	// 4 bytes
-	char secondary_info[4];
-} SHardwareData;
-
 uint8_t writeData(uint8_t *);
 uint8_t readData(uint8_t what,uint8_t *);
 uint8_t readDataLimits__8and16BitValues_4and7BytesOutput(uint8_t what, uint8_t * data);
@@ -364,9 +347,11 @@
 uint8_t getDecoType(void);
 uint8_t getFutureTTS(void);
 
+uint16_t settingsGetSize();
 SSettings* settingsGetPointer(void);
+SSettings* profileGetPointer(uint8_t number);
 const SSettings* settingsGetPointerStandard(void);
-void set_settings_to_Standard(void);
+void set_settings_to_Standard(uint8_t whichSettings);
 void mod_settings_for_first_start_with_empty_ext_flash(void);
 const SFirmwareData* firmwareDataGetPointer(void);
 const SHardwareData* hardwareDataGetPointer(void);
@@ -382,8 +367,9 @@
 void setActualRTEversion(uint8_t high, uint8_t low);
 void getActualRTEandFONTversion(uint8_t *RTEhigh, uint8_t *RTElow, uint8_t *FONThigh, uint8_t *FONTlow);
 
-void set_new_settings_missing_in_ext_flash(void);
-uint8_t check_and_correct_settings(void);
+void setFlipDisplay(uint8_t flipDisplay);
+void set_new_settings_missing_in_ext_flash(uint8_t whichSettings);
+uint8_t check_and_correct_settings(uint8_t whichSettings);
 uint8_t newFirmwareVersionCheckViaSettings(void);
 void set_settings_button_to_factory_with_individual_buttonBalance(void);
 uint8_t getLicence(void);
@@ -405,4 +391,7 @@
 uint8_t isSettingsWarning();
 
 bool checkAndFixSetpointSettings(void);
+
+bool isScrubberWarning(const SScrubberData *scrubberData);
+bool isScrubberError(const SScrubberData *scrubberData);
 #endif // SETTINGS_H
Binary file Current build/OSTC4update_230925.bin has changed
Binary file Current build/OSTC4update_251115.bin has changed
--- a/Current build/readme.txt	Sun Nov 02 19:30:58 2025 +0100
+++ b/Current build/readme.txt	Sat Nov 15 19:29:44 2025 +0100
@@ -1,3 +1,3 @@
-Heinrichs Weikamp OSTC4 update files.
+Heinrichs Weikamp OSTC4 / OSTC 5 update files.
 
 The builds are for testing purposes only. Be careful, they might not work and are definitely not recommended for real dives. 
\ No newline at end of file
--- a/Discovery/Inc/base.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/base.h	Sat Nov 15 19:29:44 2025 +0100
@@ -111,6 +111,7 @@
 void set_globalState_Menu_Line(uint8_t line);
 uint8_t get_globalState_Menu_Line(void);
 void get_idSpecificStateList(uint32_t id, SStateList *output);
+uint8_t get_lineOfID(uint32_t id);
 void delayMicros(uint32_t micros);
 void get_RTC_DateTime(RTC_DateTypeDef * sdatestructureget, RTC_TimeTypeDef * stimestructureget);
 void set_RTC_DateTime(RTC_DateTypeDef * sdatestructure, RTC_TimeTypeDef * stimestructure);
--- a/Discovery/Inc/check_warning.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/check_warning.h	Sat Nov 15 19:29:44 2025 +0100
@@ -30,6 +30,12 @@
 #include <stdint.h>
 #include "data_central.h"
 
+
+#define REQUEST_BUZZER_OFF			(0u)
+#define REQUEST_BUZZER_ONCE			(1u)
+#define REQUEST_BUZZER_CONTINUOUS	(2u)
+
+
 /* Exported function prototypes ----------------------------------------------*/
 void check_warning(void);
 void check_warning2(SDiveState *pDiveState);
@@ -46,5 +52,7 @@
 uint8_t getSetpointLowId(void);
 uint8_t getSetpointDecoId(void);
 void requestBuzzerActivation(uint8_t active);
+uint8_t getBuzzerActivationRequest();
 uint8_t getBuzzerActivationState();
+void deactivateBuzzer();
 #endif // CHECK_WARNING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Inc/cv_heartbeat.h	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,143 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Inc/cv_heartbeat.h
+/// \brief  Function definitions for connecting to a Polar HC10 heartbeat sensor
+/// \date   3 July 2025
+
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2015 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef INC_CV_HEARTBEAT_H_
+#define INC_CV_HEARTBEAT_H_
+
+#include <stdint.h>
+
+
+#define BLUEMOD_ADDR_SIZE		(20u)		/* length of address respond */
+#define BLUEMOD_RSSI_SIZE		(5u)
+#define BLUEMOD_NAME_SIZE		(40u)
+
+void openEdit_Heartbeat(void);
+
+typedef enum
+{
+	NO_INDICATOR = 0,
+	DEVICE_INDICATOR,
+	CONNECTION_INDICATOR,
+	SERVICE_INDICATOR,
+	CHARACTERISTIC_INDICATOR,
+	DESCRIPTOR_INDICATOR,
+	PULSE_INDICATOR,
+	OK_INDICATOR,			/* module control */
+	ERROR_INDICATOR			/* module control */
+} indicatior_t;
+
+typedef enum
+{
+	BT_READ_NOTHING = 0,
+	BT_READ_DEVICE_ADDR,
+	BT_READ_DEVICE_RSSI,
+	BT_READ_DEVICE_NAME,
+	BT_READ_CON_DETAILS,
+	BT_READ_SERV_HANDLE,
+	BT_READ_SERV_START,
+	BT_READ_SERV_END,
+	BT_READ_SERV_UUID,
+	BT_READ_CHAR_CONHANDLE,
+	BT_READ_CHAR_ATTRIBUTE,
+	BT_READ_CHAR_PROPERTY,
+	BT_READ_CHAR_VALUEHANDLE,
+	BT_READ_CHAR_UUID,
+	BT_READ_DESC_CONHANDLE,
+	BT_READ_DESC_CHARHANDLE,
+	BT_READ_DESC_DESCHANDLE,
+	BT_READ_DESC_UUID,
+	BT_READ_PULSE_CONHANDLE,
+	BT_READ_PULSE_VALUEHANDLE,
+	BT_READ_PULSE_DATA,
+} readDataType_t;
+
+typedef enum
+ {
+	SENSOR_HB_OFFLINE = 0,		/* Default Status no data available  */
+	SENSOR_HB_ENABLE_BLE,
+	SENSOR_HB_CHECK_CONFIG,
+	SENSOR_HB_DISCOVER,
+	SENSOR_HB_CONNECT,
+	SENSOR_HB_DISCONNECT,
+	SENSOR_HB_SERVICES,
+	SENSOR_HB_CHARACTERISTIC,
+	SENSOR_HB_DESCRIPTOR,
+	SENSOR_HB_SUBSCRIBE,
+	SENSOR_HB_RESTART,
+	SENSOR_HB_DETECTION_INDICATOR,		/* searching for indicators to identify data items */
+	SENSOR_HB_DETECTION_RSSI,
+	SENSOR_HB_DETECTION_NAME,
+	SENSOR_HB_DETECTION_MAN,
+	SENSOR_HB_DETECTION_UUID,
+	SENSOR_HB_FOUND,		/* A device providing the requested service was found */
+	SENSOR_HB_CONNECTED,	/* Connection to heartbeat sensor established */
+ 	SENSOR_HB_OFFLINEMODE,	/* Oflline measurement started */
+ } sensorHeartbeat_State_t;
+
+typedef struct
+{
+	uint8_t address[BLUEMOD_ADDR_SIZE];
+	uint8_t rssi[BLUEMOD_RSSI_SIZE];
+	uint8_t name[BLUEMOD_NAME_SIZE];
+} btDdeviceData_t;
+
+
+typedef struct
+{
+	uint8_t handle;
+	uint8_t start[6];
+	uint8_t end[6];
+	uint8_t uuid[50];
+} btDeviceService_t;
+
+typedef struct
+{
+	uint8_t conHandle;
+	uint8_t attrHandle[10];
+	uint8_t properties[10];
+	uint8_t valueHandle[10];
+	uint8_t uuid[50];
+} btDeviceCharacteristic_t;
+
+typedef struct
+{
+	uint8_t conHandle;
+	uint8_t charHandle[10];
+	uint8_t descHandle[10];
+	uint8_t uuid[50];
+} btDeviceDescriptor_t;
+
+typedef struct {
+    uint16_t heart_rate;
+    uint16_t energy_expended;
+    uint16_t rr_intervals[10];
+    uint8_t rr_count;
+} HRMeasurement_t;
+
+sensorHeartbeat_State_t cv_heartbeat_getState();
+void refresh_Heartbeat(void);
+void cv_heartbeat_Control(void);
+uint8_t cv_heartbeat_HandleData();
+
+#endif /* INC_CV_HEARTBEAT_H_ */
--- a/Discovery/Inc/demo.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/demo.h	Sat Nov 15 19:29:44 2025 +0100
@@ -35,4 +35,6 @@
 void demoConfigureSettings(void);
 void demoSendCommand(uint8_t action);
 
+void demo_HandleData(void);
+
 #endif // DEMO_H
--- a/Discovery/Inc/externLogbookFlash.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/externLogbookFlash.h	Sat Nov 15 19:29:44 2025 +0100
@@ -41,7 +41,17 @@
  */
 #define DDSTART				0x00000000
 #define DDSTOP				0x00000FFF
-#define unused1START	0x00001000
+
+#define PROFILE0_START	0x00001000		/* store profiles within one 4k sector because they are always read / written as one block */
+#define PROFILE0_STOP	0x000013FF		/* no ring functionality is implemented because changes are not expected very often */
+#define PROFILE1_START	0x00001400
+#define PROFILE1_STOP	0x000017FF
+#define PROFILE2_START	0x00001800
+#define PROFILE2_STOP	0x00001BFF
+#define PROFILE3_START	0x00001C00
+#define PROFILE3_STOP	0x00001FFF
+
+#define unused1START	0x00002000
 #define unused1STOP		0x00007FFF
 
 /* 32 KB */
@@ -84,6 +94,22 @@
 #define SECTOR_INUSE		(4)
 #define SECTOR_EMPTY		(5)
 
+
+typedef enum{
+	EF_HEADER,
+	EF_SAMPLE,
+	EF_DEVICEDATA,
+	EF_VPMDATA,
+	EF_SETTINGS,
+	EF_FIRMWARE,
+	EF_FIRMWARE2,
+	EF_PROFILE0,
+	EF_PROFILE1,
+	EF_PROFILE2,
+	EF_PROFILE3,
+}which_ring_enum;
+
+
 /* Exported types ------------------------------------------------------------*/
 typedef struct{
 uint8_t byteLow;
@@ -108,8 +134,8 @@
 } convert16_Type;
 
 /* Exported functions --------------------------------------------------------*/
-void ext_flash_write_settings(uint8_t resetRing);
-uint8_t ext_flash_read_settings(void);
+void ext_flash_write_settings(uint8_t whichSettings, uint8_t resetRing);
+uint8_t ext_flash_read_settings(uint8_t whichSettings);
 
 void ext_flash_write_devicedata(uint8_t resetRing);
 uint16_t ext_flash_read_devicedata(uint8_t *buffer, uint16_t max_length);
--- a/Discovery/Inc/firmwareEraseProgram.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/firmwareEraseProgram.h	Sat Nov 15 19:29:44 2025 +0100
@@ -41,11 +41,42 @@
 #define HARDWAREDATA_ADDRESS	(0x08000000 + 0x0000A040)
 /* Exported functions --------------------------------------------------------*/
 
+ typedef struct
+ {
+ 	// 8 bytes
+ 	uint16_t primarySerial;
+ 	uint8_t primaryLicence;
+ 	uint8_t revision8bit;
+ 	uint8_t production_year;
+ 	uint8_t production_month;
+ 	uint8_t production_day;
+ 	uint8_t production_bluetooth_name_set;
 
+ 	// 44 bytes
+ 	char production_info[44];
+
+ 	// 8 bytes
+ 	uint16_t secondarySerial;
+ 	uint8_t secondaryLicence;
+ 	uint8_t secondaryReason8bit;
+ 	uint8_t secondary_year;
+ 	uint8_t secondary_month;
+ 	uint8_t secondary_day;
+ 	uint8_t secondary_bluetooth_name_set;
+
+ 	// 4 bytes
+ 	char secondary_info[4];
+ } SHardwareData;
+
+
+uint32_t CalcFletcher32(uint32_t startAddr, uint32_t endAddr);
 
 uint8_t firmware_eraseFlashMemory(void);
 uint8_t firmware_programFlashMemory(uint8_t *pBuffer1, uint32_t length1);//, uint8_t *pBuffer2, uint32_t length2)
 
+uint8_t bootloader_eraseFlashMemory(void);
+uint8_t bootloader_programFlashMemory(uint8_t *pBuffer1, uint32_t length1, SHardwareData* pHwInfo);
+
 uint8_t firmware2_variable_upperpart_eraseFlashMemory(uint32_t length, uint32_t offset);
 uint8_t firmware2_variable_upperpart_programFlashMemory(uint32_t length, uint32_t offset, uint8_t *pBuffer1, uint32_t pBuffer1Size, uint8_t *pBuffer2);
 
--- a/Discovery/Inc/gfx_colors.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/gfx_colors.h	Sat Nov 15 19:29:44 2025 +0100
@@ -87,8 +87,8 @@
 	CLUT_MenuPageHardware,
 	CLUT_MenuPageSystem,
 	CLUT_MenuPageCustomView,
+	CLUT_MenuPageCvOption,
 	CLUT_MenuPageDivePlanner,
-	CLUT_MenuPage10,
 	CLUT_ButtonSymbols,
 	CLUT_InfoSurface,
 	CLUT_InfoDive,
--- a/Discovery/Inc/gfx_engine.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/gfx_engine.h	Sat Nov 15 19:29:44 2025 +0100
@@ -140,6 +140,7 @@
 void GFX_clear_window_immediately(GFX_DrawCfgWindow* hgfx);
 
 //void GFX_draw_circle_with_MEMORY(uint8_t use_memory, GFX_DrawCfgScreen *hgfx, point_t center, uint8_t radius, int8_t color);
+void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color);
 void GFX_draw_circle(GFX_DrawCfgScreen *hgfx, point_t center, uint8_t radius, int8_t color);
 void GFX_draw_colorline(GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color);
 void GFX_draw_thick_line(uint8_t thickness, GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color);
--- a/Discovery/Inc/logbook.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/logbook.h	Sat Nov 15 19:29:44 2025 +0100
@@ -212,7 +212,7 @@
 uint8_t logbook_getHeader(uint8_t StepBackwards,SLogbookHeader* pLogbookHeader);
 uint16_t logbook_readSampleData(uint8_t StepBackwards, uint16_t length,uint16_t* depth, uint8_t*  gasid, int16_t* temperature, uint16_t* ppo2,
 							    uint16_t* setpoint, uint16_t* sensor1, uint16_t* sensor2, uint16_t* sensor3, uint16_t* cns, uint8_t* bailout,
-								uint16_t* decostopDepth, uint16_t* tank, SGnssCoord* pPosition, uint8_t* event);
+								uint16_t* decostopDepth, uint16_t* tank, uint16_t* compassHeading, SGnssCoord* pPosition, uint16_t* scrubberState, uint8_t* event);
 void logbook_test(void);
 void logbook_InitAndWrite(SDiveState* pStateReal);
 void logbook_recover_brokenlog(uint8_t headerId);
@@ -221,4 +221,6 @@
 uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader);
 void logbook_readDummySamples(uint8_t* pTarget, uint16_t length);
 
+void logScrubberState(const SScrubberData *scrubberData);
+
 #endif /* LOGBOOK_H */
--- a/Discovery/Inc/ostc.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/ostc.h	Sat Nov 15 19:29:44 2025 +0100
@@ -60,6 +60,10 @@
 #define DISPLAY_VERSION_LCD						(0u)
 #define DISPLAY_VERSION_NEW						(1u)
 
+#define CHUNK_SIZE				(160u)		/* the DMA will handle chunk size transfers */
+#define CHUNKS_PER_BUFFER		(3u)
+
+
 /* Exported variables --------------------------------------------------------*/
 
 extern SPI_HandleTypeDef hspiDisplay;
@@ -82,6 +86,7 @@
 void MX_SPI_Init(void);
 void MX_GPIO_Init(void);
 void MX_UART_Init(void);
+void MX_UART_BT_Init_DMA();
 uint8_t MX_UART_ButtonAdjust(uint8_t *array);
 
 void MX_SmallCPU_Reset_To_Boot(void);
@@ -104,5 +109,15 @@
 void SetDisplayVersion(uint8_t version);
 uint8_t isNewDisplay(void);
 
+uint8_t UART_getChar();
+
+#ifdef ENABLE_PULSE_SENSOR_BT
+void UART_StartDMARx();
+#endif
+#ifdef ENABLE_USART_RADIO
+void MX_UART_RADIO_Init_DMA();
+void UART_StartDMARxRadio();
+#endif
+
 
 #endif // OSTC_H
--- a/Discovery/Inc/ostc_hw2.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/ostc_hw2.h	Sat Nov 15 19:29:44 2025 +0100
@@ -167,6 +167,22 @@
 #define USART_IR_HUD_IRQn                           USART2_IRQn
 // to it directly#define USART_IR_HUD_IRQHandler    USART2_IRQHandler
 
+#define USART_RADIO                                 USART3
+#define USART_RADIO_CLK_ENABLE()                   __USART3_CLK_ENABLE();
+#define USART_RADIO_FORCE_RESET()                  __USART3_FORCE_RESET()
+#define USART_RADIO_RELEASE_RESET()                __USART3_RELEASE_RESET()
+//#define USART_IR_HUD_TX_AF                          GPIO_AF7_USART3
+//#define USART_IR_HUD_TX_PIN                         GPIO_PIN_5
+//#define USART_IR_HUD_TX_GPIO_PORT                   GPIOD
+//#define USART_IR_HUD_TX_GPIO_CLK_ENABLE()           __GPIOD_CLK_ENABLE()
+
+#define USART_RADIO_RX_AF                          GPIO_AF7_USART3
+#define USART_RADIO_RX_PIN                         GPIO_PIN_11
+#define USART_RADIO_RX_GPIO_PORT                   GPIOB
+#define USART_RADIO_RX_GPIO_CLK_ENABLE()           __GPIOB_CLK_ENABLE()
+#define USART_RADIO_IRQn                           USART3_IRQn
+
+
 #define TIMx                                        TIM4
 #define TIMx_CLK_ENABLE                             __TIM4_CLK_ENABLE
 #define TIMx_IRQn                                   TIM4_IRQn
--- a/Discovery/Inc/simulation.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/simulation.h	Sat Nov 15 19:29:44 2025 +0100
@@ -63,7 +63,11 @@
 SDecoinfo* simulation_decoplaner_Bachelorarbeit_VPM(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, SgasChangeList *pGasChangeList);
 void simulation_gas_consumption(uint16_t *outputConsumptionList, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, const SgasChangeList *pGasChangeList);
 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const SgasChangeList *pGasChangeList);
-
+void simulation_evaluate_profil(uint16_t *outputConsumptionList,
+								SSimDataSummary *outputSummary,
+								uint16_t depth_meter, uint16_t dive_time_minutes,uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput,
+								SDecoinfo *decoInfoInput,
+								const SgasChangeList *pGasChangeList);
 
 void Sim_Descend (void);
 void Sim_Ascend (void);
--- a/Discovery/Inc/t3.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/t3.h	Sat Nov 15 19:29:44 2025 +0100
@@ -44,6 +44,6 @@
 uint8_t t3_customview_disabled(uint8_t view);
 void t3_handleAutofocus(void);
 
-int printScrubberText(char *text, size_t size, const SScrubberData *scrubberData, SSettings *settings);
+unsigned printScrubberText(char *text, size_t size, const SScrubberData scrubberData[], const SSettings *settings, bool useTwoLines);
 
 #endif /* T3_H */
--- a/Discovery/Inc/tComm.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tComm.h	Sat Nov 15 19:29:44 2025 +0100
@@ -43,10 +43,13 @@
 		BM_CONFIG_SILENCE,
 		BM_CONFIG_DONE,
 		BM_CONFIG_RETRY,
+		BM_CONFIG5_ESCAPE1 = 50,
+		BM_CONFIG5_ESCAPE2,
+		BM_CONFIG5_BAUD,
+		BM_CONFIG5_DATAMODE,
 		BM_INIT_POWEROFF = 100,
 		BM_INIT_POWERON,
-		BM_INIT_TRIGGER_ON,
-		BM_INIT_TRIGGER_OFF,
+		BM_INIT_COMMAND_ON,
 		BM_INIT_ECHO,
 		BM_INIT_FACTORY,
 		BM_INIT_ECHO2,
--- a/Discovery/Inc/tHome.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tHome.h	Sat Nov 15 19:29:44 2025 +0100
@@ -81,7 +81,10 @@
 		CVIEW_CcrSummary,
         CVIEW_Timer,
 		CVIEW_Position,
-		CVIEW_END			/* The ID is used in shift operation => 31 is the max number of supported views */
+#ifdef ENABLE_LOGGER_WINDOW
+		CVIEW_Logger = 25,			/* keep development views at the end of the list to avoid id problems in official releases */
+#endif
+		CVIEW_END	= 32			/* The ID is used in shift operation => 31 is the max number of supported views */
 };
 
 enum CUSTOMVIEWS_BF
--- a/Discovery/Inc/tInfo.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tInfo.h	Sat Nov 15 19:29:44 2025 +0100
@@ -60,10 +60,15 @@
 void tInfo_write_buttonTextline(GFX_DrawCfgScreen *screenPtr, uint8_t left2ByteCode, char middle2ByteCode, char right2ByteCode);
 void tInfo_write_buttonTextline_simple(uint8_t left2ByteCode, char middle2ByteCode, char right2ByteCode);
 
+void tInfo_drawPixel(int16_t x, int16_t y, uint8_t color);
+void tInfo_draw_colorline(point_t start, point_t stop, uint8_t color);
+void t_Info_draw_circle(point_t center, uint8_t radius, int8_t color);
+
 void tInfo_setEvent(uint32_t inputEventID, uint32_t inputFunctionCall);
 
 void tInfo_set_on_off(uint32_t editID, uint8_t int1);
 void exitInfo(void);
 void exitInfoToBack(void);
+void exitInfoSilent(void);
 
 #endif /* TINFO_H */
--- a/Discovery/Inc/tInfoCompass.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tInfoCompass.h	Sat Nov 15 19:29:44 2025 +0100
@@ -28,6 +28,15 @@
 #ifndef TINFO_COMPASS_H
 #define TINFO_COMPASS_H
 
+#include "gfx.h"
+
+typedef struct
+{
+	point_t coord;
+	point_t eclipse;
+	uint8_t check[360];
+} axisIndicator_t;
+
 /* Exported functions --------------------------------------------------------*/
 void openInfo_Compass(void);
 void refreshInfo_Compass(GFX_DrawCfgScreen s);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Inc/tInfoLogger.h	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Inc/tInfoSensor.h
+/// \brief  Infopage content for visualisation of UART protocol flow
+/// \author heinrichs weikamp gmbh
+/// \date   17-07-2025
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef TINFO_LOGGER_H
+#define TINFO_LOGGER_H
+
+#define LINE_HEADER_BYTES (3u)
+#define MAX_CHAR_PER_LINE (60u)
+#define MAX_LOGGER_LINES  (13u)
+
+#define LOG_TX_LINE	(0u)
+#define LOG_RX_LINE (1u)
+
+#include "gfx_engine.h"
+
+/* Exported functions --------------------------------------------------------*/
+void openInfo_Logger();
+void refreshInfo_Logger(GFX_DrawCfgScreen s);
+void sendActionToInfoLogger(uint8_t sendAction);
+void InfoLogger_writeLine(uint8_t* pLine,uint8_t lineLength,uint8_t direction);
+uint8_t InfoLogger_isUpdated();
+
+#endif /* TINFO_LOGGER_H */
--- a/Discovery/Inc/tMenu.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tMenu.h	Sat Nov 15 19:29:44 2025 +0100
@@ -68,6 +68,7 @@
 void nextline(char * text, uint8_t *textPointer);
 
 void tM_init(void);
+void tM_build_pages(void);
 void openMenu(uint8_t freshWithFlipPages);
 void openMenu_first_page_with_OC_gas_update(void);
 void updateMenu(void);
@@ -94,4 +95,5 @@
 void clearDisabledMenuLines(void);
 
 char *makeGrey(bool isGrey);
+char printCheckbox(bool isChecked);
 #endif /* TMENU_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Inc/tMenuCvOption.h	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Inc/tMenuCvOption.h
+/// \brief  Header file of Menu Lines for System settings
+/// \author heinrichs weikamp gmbh
+/// \date   24-April-2025
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef TMENU_CVOPTION_H
+#define TMENU_CVOPTION_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "gfx_engine.h"
+
+/** @addtogroup Template
+	* @{
+	*/
+
+/* Exported variables --------------------------------------------------------*/
+
+
+/* Exported functions --------------------------------------------------------*/
+
+uint32_t tMCvOption_refresh(uint8_t line, char *text, uint16_t *tab, char *subtext);
+void tMCvOption_checkLineStatus(void);
+
+#endif /* TMENU_CVOPTION_H */
--- a/Discovery/Inc/tMenuEdit.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tMenuEdit.h	Sat Nov 15 19:29:44 2025 +0100
@@ -68,7 +68,10 @@
 void tMenuEdit_select(uint32_t editID);
 
 void evaluateNewString	(uint32_t editID, uint32_t *pNewValue1, uint32_t *pNewValue2, uint32_t *pNewValue3, uint32_t *pNewValue4);
+void evaluateNewStringText(uint32_t editID, uint8_t *pNewString);
+
 void tMenuEdit_newInput	(uint32_t editID, uint32_t int1, uint32_t int2, uint32_t int3, uint32_t int4);
+void tMenuEdit_newInputText(uint32_t editID, uint8_t* ptext);
 void tMenuEdit_newButtonText(uint32_t editID, char *text);
 void tMenuEdit_set_on_off(uint32_t editID, uint32_t int1);
 
@@ -91,6 +94,7 @@
 void write_field_toggle(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t int1,  uint8_t int2);
 void write_field_on_off(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t int1);
 void write_field_fpoint(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, float input);
+void write_field_text(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t* pInput);
 
 void stop_cursor_fields(void);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Inc/tMenuEditCvOption.h	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Inc/tMenuEditCvOption.h
+/// \brief  Header file for editing Hardware Settings
+/// \author heinrichs weikamp gmbh
+/// \date   24-Apr-2025
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef TMENU_EDIT_CVOPTION_H
+#define TMENU_EDIT_CVOPTION_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "gfx_engine.h"
+#include "global_constants.h"
+#include "settings.h"
+#include "data_central.h"
+
+void openEdit_CvOption(uint8_t line);
+void refresh_CompassEdit(void);
+uint32_t tMCvOption_refresh(uint8_t line, char *text, uint16_t *tab, char *subtext);
+void tMCvOption_checkLineStatus(void);
+
+#endif /* TMENU_EDIT_CVOPTION_H */
--- a/Discovery/Inc/tMenuSystem.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tMenuSystem.h	Sat Nov 15 19:29:44 2025 +0100
@@ -36,6 +36,16 @@
 	* @{
 	*/
 
+#define CUSTOM_BLOCK_INFO_ADDR	(0x0811FFF0)
+
+typedef struct
+{
+    uint32_t Reserved;		/* for future use */
+    uint32_t Type;			/* type => block purpose */
+    uint32_t fletcher;		/* fletcher check sum */
+    uint32_t length;		/* length of block starting from 0x08100000 */
+} customBlockInfo_t;
+
 void set_CustomsviewsSubpage(uint8_t page);
 
 /* Exported variables --------------------------------------------------------*/
@@ -44,6 +54,5 @@
 /* Exported functions --------------------------------------------------------*/
 
 uint32_t tMSystem_refresh(uint8_t line, char *text, uint16_t *tab, char *subtext);
-void tMSystem_checkLineStatus(void);
 
 #endif /* TMENU_SYSTEM_H */
--- a/Discovery/Inc/tStructure.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/tStructure.h	Sat Nov 15 19:29:44 2025 +0100
@@ -66,6 +66,7 @@
 #define InfoPageCompass 6
 #define InfoPageSensor  8
 #define InfoPagePreDive 9
+#define InfoPageLogger  10
 
 #define StI 			_MB(0,1,0,0,0)
 #define StILOGLIST		_MB(0,2,0,0,0)
@@ -76,6 +77,7 @@
 #define StIDEBUG		_MB(0,7,0,0,0)
 #define StISENINFO		_MB(0,8,0,0,0)
 #define StIPREDIVE		_MB(0,9,0,0,0)
+#define StILOGGER		_MB(0,10,0,0,0)
 
 #define StI_GoToLogbook			_MB(0,1,1,0,0)
 #define StI_GoToPlanner			_MB(0,1,2,0,0)
@@ -214,17 +216,14 @@
 #define StMXTRA_CCRmode					_MB(2,4,1,1,0)
 #define StMXTRA_O2_Fallback				_MB(2,4,2,1,0)
 #define StMXTRA_ScrubTimer				_MB(2,4,3,1,0)
-#define StMXTRA_ScrubTimer_Max			_MB(2,4,3,2,0)
-#define StMXTRA_ScrubTimer_Reset		_MB(2,4,3,3,0)
-#define StMXTRA_ScrubTimer_OP_Mode		_MB(2,4,3,5,0)
+#define StMXTRA_ScrubTimer_Active		_MB(2,4,3,2,0)
+#define StMXTRA_ScrubTimer_Max			_MB(2,4,3,3,0)
+#define StMXTRA_ScrubTimer_Reset		_MB(2,4,3,4,0)
+#define StMXTRA_ScrubTimer_OP_Mode		_MB(2,4,3,6,0)
 #define StMXTRA_PSCR_O2_Drop			_MB(2,4,4,1,0)
 #define StMXTRA_PSCR_LUNG_RATIO			_MB(2,4,4,2,0)
 #define StMXTRA_Predive_Check			_MB(2,4,5,1,0)
 
-
-
-
-
 /* PAGE 5 */
 #define StMDECO		_MB(2,5,0,0,0)
 
@@ -273,136 +272,185 @@
 
 #define StMHARD1_Bluetooth			_MB(2,7,1,1,0)
 
-#define StMHARD2_Compass				_MB(2,7,2,0,0)
-#define StMHARD2_Compass_SetCourse		_MB(2,7,2,2,0)
-#define StMHARD2_Compass_ResetCourse	_MB(2,7,2,3,0)
-#define StMHARD2_Compass_Calibrate		_MB(2,7,2,4,0)
-#define StMHARD2_Compass_Inertia		_MB(2,7,2,5,0)
-#define StMHARD2_Compass_Declination	_MB(2,7,2,6,0)
-
 //#define StMHARD2_Exit						_MB(2,7,2,2,0)
 
-#define StMHARD3_Sensors			_MB(2,7,3,0,0)
-#define StMHARD3_O2_Sensor1			_MB(2,7,3,1,0)
-#define StMHARD3_O2_Sensor2			_MB(2,7,3,2,0)
-#define StMHARD3_O2_Sensor3			_MB(2,7,3,3,0)
-#define StMHARD3_O2_Calibrate		_MB(2,7,3,4,0)
-#define StMHARD3_Sensor_Info		_MB(2,7,3,5,0)
-#define StMHARD3_Sensor_Detect		_MB(2,7,3,6,0)
+#define StMHARD3_Sensors			_MB(2,7,2,0,0)
+#define StMHARD3_O2_Sensor1			_MB(2,7,2,1,0)
+#define StMHARD3_O2_Sensor2			_MB(2,7,2,2,0)
+#define StMHARD3_O2_Sensor3			_MB(2,7,2,3,0)
+#define StMHARD3_O2_Calibrate		_MB(2,7,2,4,0)
+#define StMHARD3_Sensor_Info		_MB(2,7,2,5,0)
+#define StMHARD3_Sensor_Detect		_MB(2,7,2,6,0)
 
 
-#define StMHARD4_BrightnessEco	_MB(2,7,4,1,0)
-#define StMHARD4_BrightnessStd	_MB(2,7,4,2,0)
-#define StMHARD4_BrightnessHigh	_MB(2,7,4,3,0)
-#define StMHARD4_BrightnessMax	_MB(2,7,4,4,0)
+#define StMHARD4_BrightnessEco	_MB(2,7,3,1,0)
+#define StMHARD4_BrightnessStd	_MB(2,7,3,2,0)
+#define StMHARD4_BrightnessHigh	_MB(2,7,3,3,0)
+#define StMHARD4_BrightnessMax	_MB(2,7,3,4,0)
 
-#define StMHARD5_Button1		_MB(2,7,5,1,0)
-#define StMHARD5_ButtonBalance1	_MB(2,7,5,2,0)
-#define StMHARD5_ButtonBalance2	_MB(2,7,5,3,0)
-#define StMHARD5_ButtonBalance3	_MB(2,7,5,4,0)
-#define StMHARD5_ButtonLock		_MB(2,7,5,5,0)
+#define StMHARD5_Button1		_MB(2,7,4,1,0)
+#define StMHARD5_ButtonBalance1	_MB(2,7,4,2,0)
+#define StMHARD5_ButtonBalance2	_MB(2,7,4,3,0)
+#define StMHARD5_ButtonBalance3	_MB(2,7,4,4,0)
+#define StMHARD5_ButtonLock		_MB(2,7,4,5,0)
+
+#define StMHARD6_WarningBuz		_MB(2,7,5,1,0)
 
 //#define StMHARD6_UpdateCPU2_No	_MB(2,7,6,1,0)
 //#define StMHARD6_UpdateCPU2_Yes	_MB(2,7,6,2,0)
 //#define StMHARD6_UpdateCPU2_Now	_MB(2,7,6,3,0)
 
 /* PAGE 8 */
-#define StMSYS		_MB(2,8,0,0,0)
+#define StMOption						_MB(2,8,0,0,0)
+#define StMOption_Compass				_MB(2,8,1,0,0)
+#define StMOption_Compass_SetCourse		_MB(2,8,1,1,0)
+#define StMOption_Compass_ResetCourse	_MB(2,8,1,2,0)
+#define StMOption_Compass_Calibrate		_MB(2,8,1,3,0)
+#define StMOption_Compass_Inertia		_MB(2,8,1,4,0)
+#define StMOption_Compass_Declination	_MB(2,8,1,5,0)
 
-/* PAGE 8 EDIT FIELD CONTENT */
-#define StMSYS1_DateTime _MB(2,8,1,0,0)
-#define StMSYS1_Date	_MB(2,8,1,1,0)
-#define StMSYS1_Time	_MB(2,8,1,2,0)
-#define StMSYS1_FORMAT	_MB(2,8,1,3,0)
-#define StMSYS1_DDMMYY	_MB(2,8,1,3,1)
-#define StMSYS1_MMDDYY	_MB(2,8,1,3,2)
-#define StMSYS1_YYMMDD	_MB(2,8,1,3,3)
-#define StMSYS1_12HR    _MB(2,8,1,4,0)
-#define StMSYS1_GNSSDT  _MB(2,8,1,5,0)
-#define StMSYS1_ZONE	_MB(2,8,1,6,0)
+#define StMOption_Timer					_MB(2,8,2,0,0)
+#define StMOption_Timer_Value			_MB(2,8,2,1,0)
+
+#define StMOption_Heartbeat 			_MB(2,8,3,0,0)
+
+/* PAGE 9 */
+#define StMSYS		_MB(2,9,0,0,0)
 
-#define StMSYS_Timer	_MB(2,8,2,1,0)
+/* PAGE 9 EDIT FIELD CONTENT */
+#define StMSYS1_DateTime _MB(2,9,1,0,0)
+#define StMSYS1_Date	_MB(2,9,1,1,0)
+#define StMSYS1_Time	_MB(2,9,1,2,0)
+#define StMSYS1_FORMAT	_MB(2,9,1,3,0)
+#define StMSYS1_DDMMYY	_MB(2,9,1,3,1)
+#define StMSYS1_MMDDYY	_MB(2,9,1,3,2)
+#define StMSYS1_YYMMDD	_MB(2,9,1,3,3)
+#define StMSYS1_12HR    _MB(2,9,1,4,0)
+#define StMSYS1_GNSSDT  _MB(2,9,1,5,0)
+#define StMSYS1_ZONE	_MB(2,9,1,6,0)
 
-#define StMSYS2_English	_MB(2,8,3,1,0)
-#define StMSYS2_German	_MB(2,8,3,2,0)
-#define StMSYS2_French	_MB(2,8,3,3,0)
-#define StMSYS2_Italian	_MB(2,8,3,4,0)
-#define StMSYS2_Espanol	_MB(2,8,3,5,0)
+#ifdef ENABLE_SETTING_PROFILES
+#define StMSYS_Profile		_MB(2,9,2,0,0)
+#define StMSYS_ProfileA 	_MB(2,9,2,1,0)
+#define StMSYS_ProfileB 	_MB(2,9,2,2,0)
+#define StMSYS_ProfileC 	_MB(2,9,2,3,0)
+#define StMSYS_ProfileD 	_MB(2,9,2,4,0)
 
-#define StMSYS3_Units		_MB(2,8,4,1,0)
-#define StMSYS3_Colors	_MB(2,8,4,2,0)
-#define StMSYS3_Debug		_MB(2,8,4,3,0)
+#define StMSYS2_English	_MB(2,9,3,1,0)
+#define StMSYS2_German	_MB(2,9,3,2,0)
+#define StMSYS2_French	_MB(2,9,3,3,0)
+#define StMSYS2_Italian	_MB(2,9,3,4,0)
+#define StMSYS2_Espanol	_MB(2,9,3,5,0)
 
-#define StMSYS4_Info		_MB(2,8,5,1,0)
+#define StMSYS3_Units	_MB(2,9,4,1,0)
+#define StMSYS3_Colors	_MB(2,9,4,2,0)
+#ifdef HAVE_DEBUG_VIEW
+#define StMSYS3_Debug	_MB(2,9,4,3,0)
+#endif
+
+#define StMSYS4_Info	_MB(2,9,5,1,0)
 
-#define StMSYS5_Exit			_MB(2,8,6,1,0)
-#define StMSYS5_LogbookOffset	_MB(2,8,6,7,0)
-#define StMSYS5_ResetAll		_MB(2,8,6,2,0)
-#define StMSYS5_ResetDeco		_MB(2,8,6,3,0)
-#define StMSYS5_Reboot			_MB(2,8,6,4,0)
-#define StMSYS5_Maintenance		_MB(2,8,6,5,0)
-#define StMSYS5_ResetLogbook	_MB(2,8,6,6,0)
-#define StMSYS5_SetBattCharge	_MB(2,8,6,7,0)
-#define StMSYS5_RebootRTE		_MB(2,8,6,8,0)
-#define StMSYS5_RebootMainCPU	_MB(2,8,6,9,0)
-#define StMSYS5_ScreenTest		_MB(2,8,6,10,0)
-#define StMSYS5_SetFactoryBC	_MB(2,8,6,11,0)
-#define StMSYS5_ResetBluetooth	_MB(2,8,6,12,0)
-#define StMSYS5_SetSampleIndx   _MB(2,8,6,13,0)
-#define StMSYS5_AdjustSurfPres  _MB(2,8,6,14,0)
+#define StMSYS5_Exit			_MB(2,9,6,1,0)
+#define StMSYS5_LogbookOffset	_MB(2,9,6,7,0)
+#define StMSYS5_ResetAll		_MB(2,9,6,2,0)
+#define StMSYS5_ResetDeco		_MB(2,9,6,3,0)
+#define StMSYS5_Reboot			_MB(2,9,6,4,0)
+#define StMSYS5_Maintenance		_MB(2,9,6,5,0)
+#define StMSYS5_ResetLogbook	_MB(2,9,6,6,0)
+#define StMSYS5_SetBattCharge	_MB(2,9,6,7,0)
+#define StMSYS5_RebootRTE		_MB(2,9,6,8,0)
+#define StMSYS5_RebootMainCPU	_MB(2,9,6,9,0)
+#define StMSYS5_ScreenTest		_MB(2,9,6,10,0)
+#define StMSYS5_SetFactoryBC	_MB(2,9,6,11,0)
+#define StMSYS5_ResetBluetooth	_MB(2,9,6,12,0)
+#define StMSYS5_SetSampleIndx   _MB(2,9,6,13,0)
+#define StMSYS5_AdjustSurfPres  _MB(2,9,6,14,0)
+#define StMSYS5_FlashBoot		_MB(2,9,6,15,0)
+
+#else
+
+#define StMSYS2_English	_MB(2,9,2,1,0)
+#define StMSYS2_German	_MB(2,9,2,2,0)
+#define StMSYS2_French	_MB(2,9,2,3,0)
+#define StMSYS2_Italian	_MB(2,9,2,4,0)
+#define StMSYS2_Espanol	_MB(2,9,2,5,0)
+
+#define StMSYS3_Units	_MB(2,9,3,1,0)
+#define StMSYS3_Colors	_MB(2,9,3,2,0)
+#ifdef HAVE_DEBUG_VIEW
+#define StMSYS3_Debug	_MB(2,9,3,3,0)
+#endif
 
-#define StMSYS_Custom0			_MB(2,8,1,0,0)
-#define StMSYS_Custom1			_MB(2,8,2,0,0)
-#define StMSYS_Custom2			_MB(2,8,3,0,0)
-#define StMSYS_Custom3			_MB(2,8,4,0,0)
-#define StMSYS_Custom4			_MB(2,8,5,0,0)
-#define StMSYS_Custom5			_MB(2,8,6,0,0)
+#define StMSYS4_Info	_MB(2,9,4,1,0)
 
- /* PAGE 9 */
+#define StMSYS5_Exit			_MB(2,9,5,1,0)
+#define StMSYS5_LogbookOffset	_MB(2,9,5,7,0)
+#define StMSYS5_ResetAll		_MB(2,9,5,2,0)
+#define StMSYS5_ResetDeco		_MB(2,9,5,3,0)
+#define StMSYS5_Reboot			_MB(2,9,5,4,0)
+#define StMSYS5_Maintenance		_MB(2,9,5,5,0)
+#define StMSYS5_ResetLogbook	_MB(2,9,5,6,0)
+#define StMSYS5_SetBattCharge	_MB(2,9,5,7,0)
+#define StMSYS5_RebootRTE		_MB(2,9,5,8,0)
+#define StMSYS5_RebootMainCPU	_MB(2,9,5,9,0)
+#define StMSYS5_ScreenTest		_MB(2,9,5,10,0)
+#define StMSYS5_SetFactoryBC	_MB(2,9,5,11,0)
+#define StMSYS5_ResetBluetooth	_MB(2,9,5,12,0)
+#define StMSYS5_SetSampleIndx   _MB(2,9,5,13,0)
+#define StMSYS5_AdjustSurfPres  _MB(2,9,5,14,0)
+#define StMSYS5_FlashBoot		_MB(2,9,5,15,0)
+#endif
 
- # define StMCustom 	_MB(2,9,0,0,0)
+/* Temporary line markers for dive mode custom view configuration */
+/* These use line numbers 21-26 which don't conflict with actual menu items */
+#define StMSYS_Custom0			_MB(2,9,21,0,0)
+#define StMSYS_Custom1			_MB(2,9,22,0,0)
+#define StMSYS_Custom2			_MB(2,9,23,0,0)
+#define StMSYS_Custom3			_MB(2,9,24,0,0)
+#define StMSYS_Custom4			_MB(2,9,25,0,0)
+#define StMSYS_Custom5			_MB(2,9,26,0,0)
 
- /* PAGE 9 EDIT FIELD CONTENT */
+/* PAGE 10 */
+#define StMCustom 	_MB(2,10,0,0,0)
+
+ /* PAGE 10 EDIT FIELD CONTENT */
 //
 
-#define StMCustom1_CViewTimeout		_MB(2,9,1,1,0)
-#define StMCustom1_CViewStandard	_MB(2,9,1,2,0)
-#define StMCustom1_CViewStandardBF	_MB(2,9,1,3,0)
-#define StMCustom1_CViewAutoFocusBF	_MB(2,9,1,4,0)
-#define StMCustom1_CornerTimeout	_MB(2,9,1,5,0)
-#define StMCustom1_CornerStandard	_MB(2,9,1,6,0)
+#define StMCustom1_CViewTimeout		_MB(2,10,1,1,0)
+#define StMCustom1_CViewStandard	_MB(2,10,1,2,0)
+#define StMCustom1_CViewStandardBF	_MB(2,10,1,3,0)
+#define StMCustom1_CViewAutoFocusBF	_MB(2,10,1,4,0)
+#define StMCustom1_CornerTimeout	_MB(2,10,1,5,0)
+#define StMCustom1_CornerStandard	_MB(2,10,1,6,0)
 
-#define StMCustom2_BFSelection		_MB(2,9,2,1,0)
+#define StMCustom2_BFSelection		_MB(2,10,2,1,0)
 
-#define StMCustom3_CViewSelection1	_MB(2,9,3,1,0)
-#define StMCustom3_CViewSelection2	_MB(2,9,3,2,0)
-#define StMCustom3_CViewSelection3	_MB(2,9,3,3,0)
-#define StMCustom3_CViewSelection4	_MB(2,9,3,4,0)
-#define StMCustom3_CViewSelection5	_MB(2,9,3,5,0)
-#define StMCustom3_CViewSelection6	_MB(2,9,3,6,0)
+#define StMCustom3_CViewSelection1	_MB(2,10,3,1,0)
+#define StMCustom3_CViewSelection2	_MB(2,10,3,2,0)
+#define StMCustom3_CViewSelection3	_MB(2,10,3,3,0)
+#define StMCustom3_CViewSelection4	_MB(2,10,3,4,0)
+#define StMCustom3_CViewSelection5	_MB(2,10,3,5,0)
+#define StMCustom3_CViewSelection6	_MB(2,10,3,6,0)
 
-#define StMCustom4_CViewSelection1	_MB(2,9,4,1,0)
+#define StMCustom4_CViewSelection1	_MB(2,10,4,1,0)
 
 #ifdef ENABLE_MOTION_CONTROL
-#define StMCustom5_CViewPortCalib	_MB(2,9,5,1,0)
-#define StMCustom5_CViewPortSpotSize _MB(2,9,5,2,0)
-#define StMCustom5_CViewPortLayout	_MB(2,9,5,3,0)
-#define StMCustom5_CViewPortAmbient	_MB(2,9,5,4,0)
-#define StMCustom5_CViewPortControl	_MB(2,9,5,5,0)
-#endif
-#ifdef ENABLE_GPIO_V2
-#define StMCustom5_CViewWarningBuz	_MB(2,9,5,1,0)
+#define StMCustom5_CViewPortCalib	_MB(2,10,5,1,0)
+#define StMCustom5_CViewPortSpotSize _MB(2,10,5,2,0)
+#define StMCustom5_CViewPortLayout	_MB(2,10,5,3,0)
+#define StMCustom5_CViewPortAmbient	_MB(2,10,5,4,0)
+#define StMCustom5_CViewPortControl	_MB(2,10,5,5,0)
 #endif
 
-/* PAGE 10 */
-#define StMPLAN		_MB(2,10,0,0,0)
+/* PAGE 11 */
+#define StMPLAN		_MB(2,11,0,0,0)
 
-/* PAGE 10 EDIT FIELD CONTENT */
-#define StMPLAN2_Interval			_MB(2,10,2,1,0)
-#define StMPLAN3_DiveTime			_MB(2,10,3,1,0)
-#define StMPLAN4_MaxDepth			_MB(2,10,4,1,0)
-#define StMPLAN5_ExitResult			_MB(2,10,5,1,0)
-#define StMPLAN4_Settings			_MB(2,10,6,1,0)
+/* PAGE 11 EDIT FIELD CONTENT */
+#define StMPLAN2_Interval			_MB(2,11,2,1,0)
+#define StMPLAN3_DiveTime			_MB(2,11,3,1,0)
+#define StMPLAN4_MaxDepth			_MB(2,11,4,1,0)
+#define StMPLAN5_ExitResult			_MB(2,11,5,1,0)
+#define StMPLAN4_Settings			_MB(2,11,6,1,0)
 
 
 
--- a/Discovery/Inc/text_multilanguage.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Inc/text_multilanguage.h	Sat Nov 15 19:29:44 2025 +0100
@@ -395,6 +395,8 @@
 		TXT2BYTE_TIMEZONE,
 
 		TXT2BYTE_BUZZER,
+		TXT2BYTE_Pulse,
+		TXT2BYTE_Logger,
 
 		TXT2BYTE_END,
 };
--- a/Discovery/Src/base.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/base.c	Sat Nov 15 19:29:44 2025 +0100
@@ -237,12 +237,17 @@
 #include "t7.h"
 #include "t3.h"
 #include "tMenuEditSetpoint.h"
+#include "cv_heartbeat.h"
+#include "tInfoLogger.h"
 
 #ifdef DEMOMODE
 #include "demo.h"
 static void TIM_DEMO_init(void);
 #endif
 
+#ifdef ENABLE_USART_RADIO
+#include "demo.h"
+#endif
 
 //#include "lodepng.h"
 //#include <stdlib.h> // for malloc and free
@@ -377,33 +382,26 @@
 
     MX_GPIO_Init();
     //  MX_SmallCPU_NO_Reset_Helper();	 //161116 hw
-    MX_Bluetooth_PowerOff();	/* disable module, needed in case of e.g. a reset event to make sure module is configured from scratch */
     MX_SPI_Init();
     MX_UART_Init();
     SDRAM_Config();
     HAL_Delay( 100 );
 
     stateRealGetPointerWrite()->lastKnownBatteryPercentage = 0; // damit das nicht in settings kopiert wird.
-    set_settings_to_Standard();
+    set_settings_to_Standard(EF_SETTINGS);									/* initialize setting structure with default value => will be overwritten by flash read operation */
     mod_settings_for_first_start_with_empty_ext_flash();
-    ext_flash_read_settings();
+    ext_flash_read_settings(EF_SETTINGS);
     if( newFirmwareVersionCheckViaSettings() ) // test for old firmware version in loaded settings
     {
         wasFirmwareUpdateCheckBattery = 1;
         set_settings_button_to_factory_with_individual_buttonBalance(); // will adapt individual values
     }
-    //settingsGetPointer()->bluetoothActive = 0; 	/* MX_Bluetooth_PowerOff();  unnecessary as part of MX_GPIO_Init() */
-    //settingsGetPointer()->compassBearing = 0;
-    set_new_settings_missing_in_ext_flash(); // includes update of firmware version  161121
+
+    set_new_settings_missing_in_ext_flash(EF_SETTINGS); // includes update of firmware version  161121
 
     GFX_init( &pLayerInvisible );
     TIM_BACKLIGHT_init();
 
-    // new 170508: bluetooth on at start
-    settingsGetPointer()->bluetoothActive = 1;
-    MX_Bluetooth_PowerOn();
-    tComm_StartBlueModConfig();
-
     /*
     if( (hardwareDataGetPointer()->primarySerial == 20+18)
      || (hardwareDataGetPointer()->primarySerial == 20+25)
@@ -413,7 +411,7 @@
         tComm_Set_Bluetooth_Name(1);
     }
     */
-    errorsInSettings = check_and_correct_settings();
+    errorsInSettings = check_and_correct_settings(EF_SETTINGS);
     createDiveSettings();
 
 #ifdef QUICK_SLEEP
@@ -438,6 +436,12 @@
     display_power_on__2_of_2__post_RGB();
     GFX_use_colorscheme( settingsGetPointer()->tX_colorscheme );
 
+
+    // new 170508: bluetooth on at start
+    settingsGetPointer()->bluetoothActive = 1;
+    MX_Bluetooth_PowerOn();
+    tComm_StartBlueModConfig();
+
     tHome_init();
     tI_init();
     tM_init();
@@ -472,7 +476,7 @@
     if( settingsGetPointer()->debugModeOnStart )
     {
         settingsGetPointer()->debugModeOnStart = 0;
-        ext_flash_write_settings(0);
+        ext_flash_write_settings(EF_SETTINGS,0);
         setDebugMode();
         openInfo( StIDEBUG );
     }
@@ -502,11 +506,13 @@
             resetToFirmwareUpdate();
 
         tCCR_control();
+
         if( tComm_control() )// will stop while loop if tComm Mode started until exit from UART
         {
             createDiveSettings();
             updateMenu();
-            ext_flash_write_settings(0);
+            ext_flash_write_settings(EF_SETTINGS,0);
+            time_without_button_pressed_deciseconds = 0;	/* reset timeout to avoid shutdown after long time in Comm state */
         }
 
         /* check if tasks depending on global state are pending */
@@ -527,12 +533,22 @@
         {
         	TriggerButtonAction();
         }
+#ifdef ENABLE_PULSE_SENSOR_BT
+        cv_heartbeat_HandleData();
+#endif
+
+#ifdef ENABLE_USART_RADIO
+        demo_HandleData();
+#endif
         if(DoHousekeeping)
         {
            	DoHousekeeping = housekeepingFrame();
         }
         if(DoDisplayRefresh)							/* set every 100ms by timer interrupt */
         {
+#ifdef ENABLE_PULSE_SENSOR_BT
+        	cv_heartbeat_Control();
+#endif
 	        DoDisplayRefresh = 0;
 
 	        updateSetpointStateUsed();
@@ -728,6 +744,15 @@
 {
 	SStateList status;
 	get_globalStateList(&status);
+
+#ifdef ENABLE_LOGGER_WINDOW
+	if((status.base != 0) && (get_globalState() != StILOGGER) && (InfoLogger_isUpdated()))
+	{
+		openInfo_Logger();
+		get_globalStateList(&status);
+	}
+#endif
+
 	switch(status.base)
 	{
 	case BaseHome:
@@ -920,6 +945,8 @@
 								break;
 							case InfoPagePreDive: 	sendActionToInfoPreDive(action);
 								break;
+							case InfoPageLogger: 	exitInfo();
+								break;
 							default:				sendActionToInfo(action);
 								break;
 						}
@@ -1024,7 +1051,7 @@
 	GFX_logoAutoOff();
 	display_power_off();
     ext_flash_write_devicedata(true);	/* write data at default position */
-    ext_flash_write_settings(true);		/* write data at default position */
+    ext_flash_write_settings(EF_SETTINGS,true);		/* write data at default position */
     set_globalState(StStop);
 }
 
@@ -1056,6 +1083,16 @@
     output->mode  = (uint8_t)((id     ) & 0xFF);
 }
 
+uint8_t get_lineOfID(uint32_t id)
+{
+	uint8_t ret = (uint8_t)((id >> 16) & 0xFF);
+	if(ret > 6)
+	{
+		ret = 0;
+	}
+	return ret;
+}
+
 SButtonLock get_ButtonLock(void)
 {
 	return ButtonLockState;
--- a/Discovery/Src/check_warning.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/check_warning.c	Sat Nov 15 19:29:44 2025 +0100
@@ -79,7 +79,7 @@
 #endif
 static uint8_t buzzerOn = 0;			/* current state of the buzzer */
 
-static void setBuzzer(int8_t warningActive);
+static void handleBuzzer(int8_t warningActive);
 /* Exported functions --------------------------------------------------------*/
 
 void requestBuzzerActivation(uint8_t active)
@@ -87,22 +87,39 @@
 	buzzerRequestActive = active;
 }
 
+uint8_t getBuzzerActivationRequest()
+{
+	return buzzerRequestActive;
+}
+
 uint8_t getBuzzerActivationState()
 {
 	return buzzerOn;
 }
 
-static void setBuzzer(int8_t warningActive)
+static void handleBuzzer(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*/
+	static uint8_t lastBuzzerRequest = 0;
+	static uint8_t guiTrigger = 0;
 
 	uint32_t tick =  HAL_GetTick();
 
-	if(warningActive)
+	if(stateUsed->mode == MODE_SURFACE)
 	{
-		if(!lastWarningState)				/* init structures */
+		warningActive = 0;					/* no warning buzzer in surface mode => overwrite value */
+	}
+
+	/* There are two sources for buzzer activation: the warning detection and activation by gui => both need to be merged */
+	if((buzzerRequestActive != REQUEST_BUZZER_OFF) &&  (lastBuzzerRequest == REQUEST_BUZZER_OFF))
+	{
+		guiTrigger = 1;
+	}
+	if((warningActive) || (buzzerRequestActive != REQUEST_BUZZER_OFF))
+	{
+		if((lastWarningState == 0) && (lastBuzzerRequest == REQUEST_BUZZER_OFF))			/* init structures */
 		{
 			guiTimeoutCnt = tick;
 			stateTick = tick;
@@ -111,22 +128,38 @@
 		{
 			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))
+				if((buzzerRequestActive == REQUEST_BUZZER_OFF)
+						|| ((buzzerRequestActive == REQUEST_BUZZER_ONCE) && (time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_PING_TIME_MS))
+						||  (time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_ON_TIME_MS))
 				{
 					buzzerOn = 0;
 					stateTick = tick;
 					guiTimeoutCnt = tick;
+					buzzerRequestActive = REQUEST_BUZZER_OFF;
 				}
 			}
 		}
 		else
 		{
-			if(time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_STABLE_TIME_MS)	/* buzzer has to be off for a certain time */
+			if((time_elapsed_ms(stateTick, tick) > EXT_INTERFACE_BUZZER_STABLE_TIME_MS) || ( guiTrigger))	/* 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))
+				if((warningActive) || (buzzerRequestActive != REQUEST_BUZZER_OFF))
 				{
-					buzzerOn = 1;
-					stateTick = tick;
+					if(((stateUsed->mode != MODE_SURFACE) && (time_elapsed_ms(guiTimeoutCnt, tick)) > (EXT_INTERFACE_BUZZER_ON_TIME_MS + GUI_BUZZER_TIMEOUT_MS))
+						|| ( guiTrigger))
+					{
+						buzzerOn = 1;
+						stateTick = tick;
+						guiTrigger = 0;
+						if(buzzerRequestActive == REQUEST_BUZZER_ONCE)
+						{
+							buzzerRequestActive = REQUEST_BUZZER_OFF;
+						}
+					}
+					if((time_elapsed_ms(guiTimeoutCnt, tick)) > (EXT_INTERFACE_BUZZER_ON_TIME_MS + EXT_INTERFACE_BUZZER_STABLE_TIME_MS))  /* timeout request */
+					{
+						buzzerRequestActive = REQUEST_BUZZER_OFF;
+					}
 				}
 			}
 		}
@@ -135,9 +168,16 @@
 	{
 		buzzerOn = 0;
 	}
+	lastBuzzerRequest = buzzerRequestActive;
 	lastWarningState = warningActive;
 }
 
+void deactivateBuzzer()
+{
+	buzzerRequestActive = REQUEST_BUZZER_OFF;
+	buzzerOn = 0;
+}
+
 void check_warning(void)
 {
   check_warning2(stateUsedWrite);
@@ -160,7 +200,7 @@
 
 	if(settingsGetPointer()->warningBuzzer)
 	{
-		setBuzzer(pDiveState->warnings.numWarnings);
+		handleBuzzer(pDiveState->warnings.numWarnings);
 	}
 
 /* Warnings checked after this line will not cause activation of the buzzer */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/cv_heartbeat.c	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,668 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Src/cv_heartbeat.c
+/// \brief  providing functionality to connect OSTC to a Polar HC10 heartbeat sensor
+/// \author heinrichs weikamp gmbh
+/// \date   03-July-2025
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+#include "configuration.h"
+
+#ifdef ENABLE_PULSE_SENSOR_BT
+#include "cv_heartbeat.h"
+#include "tMenuEdit.h"
+
+#include "gfx_fonts.h"
+#include "tHome.h"
+#include "ostc.h"
+#include "tComm.h"
+#include "tInfoLogger.h"
+#include "stdlib.h"
+
+static sensorHeartbeat_State_t heartbeatState = SENSOR_HB_OFFLINE;
+
+static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+static uint32_t startDetection_ms;
+
+#define MAX_BT_DEVICE 10		/* max number of device which may be handled */
+static btDdeviceData_t btDeviceList[MAX_BT_DEVICE];
+static btDeviceService_t curDeviceService[10];
+static btDeviceCharacteristic_t curDevCharacteristic[10];
+static btDeviceDescriptor_t curDevDescriptor;
+
+
+static uint8_t curCharacteristicIndex = 0;
+static uint8_t curServiceIndex = 0;
+static uint8_t curBtIndex = 0;
+static uint8_t connHandle = ' ';
+static uint8_t evaluateDevIndex = 0xFF;
+static uint8_t evaluateSrvIndex = 0xFF;
+static uint8_t evaluateCharIndex = 0xFF;
+
+static void parsePulseMeasurement(uint8_t* pData, uint8_t length)
+{
+	uint8_t rawData[10];
+
+	char* enptr;
+	uint8_t flags = 0;
+	uint16_t rr = 0;
+	uint8_t index = 0;
+	uint8_t* pRaw = (uint8_t*)&rawData;
+	char tmpStr[3];
+
+	tmpStr[2] = 0;
+
+	HRMeasurement_t pulseData;
+
+	for(index = 0; index < length; index +=2)
+	{
+		memcpy(tmpStr,&pData[index],2);
+		rawData[index / 2] = strtol(tmpStr, &enptr,16);
+	}
+	flags = pRaw[0];
+	index = 1;
+    /* 0: Heart Rate Format bit (0 = UINT8, 1 = UINT16) */
+	if (flags & 0x01)
+	{
+	   	pulseData.heart_rate = pRaw[index] | (pRaw[index + 1] << 8);
+	    index += 2;
+	} else
+	{
+	  	pulseData.heart_rate = pRaw[index];
+	    index += 1;
+	}
+
+	/* 3: Energy Expended Status	*/
+	if (flags & 0x08)
+	{
+	   	pulseData.energy_expended = pRaw[index] | (pRaw[index + 1] << 8);
+	    index += 2;
+	} else
+	{
+	  	pulseData.energy_expended = 0;
+	}
+    /* 4: RR-Interval bit			*/
+	pulseData.rr_count = 0;
+	if (flags & 0x10)
+	{
+	    while (index + 1 < 4 && pulseData.rr_count < 10)
+	    {
+	        rr = pRaw[index] | (pRaw[index + 1] << 8);
+	        pulseData.rr_intervals[pulseData.rr_count++] = rr;
+	        index += 2;
+	    }
+	}
+//			snprintf(text,40,"Pulse: %d",pulseData.heart_rate);
+//			InfoLogger_writeLine((uint8_t*)text,strlen(text),0);
+}
+
+static indicatior_t checkIndicators(uint8_t* pdata)
+{
+	indicatior_t ret = NO_INDICATOR;
+
+	if(strcmp((char*)pdata,"+UBTD:") == 0)
+	{
+		ret = DEVICE_INDICATOR;
+	}
+	else if(strcmp((char*)pdata,"+UUBTACLC:") == 0)
+	{
+		ret = CONNECTION_INDICATOR;
+	}
+	else if(strcmp((char*)pdata,"+UBTGDP:") == 0)
+	{
+		ret = SERVICE_INDICATOR;
+	}
+	else if(strcmp((char*)pdata,"+UBTGDCS:") == 0)
+	{
+		ret = CHARACTERISTIC_INDICATOR;
+	}
+	else if(strcmp((char*)pdata,"+UBTGDCD:") == 0)
+	{
+		ret = DESCRIPTOR_INDICATOR;
+	}
+	else if(strcmp((char*)pdata,"+UUBTGN:") == 0)
+	{
+		ret = PULSE_INDICATOR;
+	}
+	return ret;
+}
+
+static void handleOK()
+{
+	uint8_t index = 0;
+
+	switch(heartbeatState)
+	{
+		case SENSOR_HB_ENABLE_BLE:	heartbeatState = SENSOR_HB_CHECK_CONFIG;
+							break;
+		case SENSOR_HB_CHECK_CONFIG: heartbeatState = SENSOR_HB_DISCOVER;
+							break;
+		case SENSOR_HB_RESTART: 	heartbeatState = SENSOR_HB_OFFLINE;
+							break;
+		case SENSOR_HB_DISCOVER: 	if(curBtIndex > 0)
+									{
+										heartbeatState = SENSOR_HB_CONNECT;
+										evaluateDevIndex = 0;
+									}
+									else
+									{
+										heartbeatState = SENSOR_HB_OFFLINE;
+									}
+
+							break;
+		case SENSOR_HB_SERVICES: 	evaluateSrvIndex = 0xFF;
+									if(curServiceIndex != 0)
+									{
+										for(index = 0; index <= curServiceIndex; index++)
+										{
+											if(strcmp((char*)curDeviceService[index].uuid,"180D") == 0)
+											{
+												heartbeatState = SENSOR_HB_CHARACTERISTIC;
+												evaluateSrvIndex = index;
+												curCharacteristicIndex = 0;
+												break;
+											}
+										}
+									}
+									if(evaluateSrvIndex == 0xFF)		/* device does not provide heartbeat data => disconnect */
+									{
+										heartbeatState = SENSOR_HB_DISCONNECT;
+									}
+							break;
+		case SENSOR_HB_CHARACTERISTIC:	evaluateCharIndex = 0xFF;
+										if(curCharacteristicIndex != 0)
+										{
+											for(index = 0; index < curCharacteristicIndex; index++)
+											{
+												if(strcmp((char*)curDevCharacteristic[index].uuid,"2A37") == 0)
+												{
+													heartbeatState = SENSOR_HB_DESCRIPTOR;
+													evaluateCharIndex = index;
+													break;
+												}
+											}
+										}
+										if(evaluateCharIndex == 0xFF)		/* device does not provide heartbeat data => disconnect */
+										{
+											heartbeatState = SENSOR_HB_DISCONNECT;
+										}
+							break;
+		case SENSOR_HB_DESCRIPTOR:		if(strcmp((char*)curDevDescriptor.uuid,"2902") == 0)
+										{
+											heartbeatState = SENSOR_HB_SUBSCRIBE;
+										}
+										else
+										{
+											heartbeatState = SENSOR_HB_DISCONNECT;
+										}
+							break;
+
+		case SENSOR_HB_SUBSCRIBE:		heartbeatState = SENSOR_HB_CONNECTED;
+							break;
+		case SENSOR_HB_DISCONNECT:		evaluateDevIndex++;
+										connHandle= ' ';
+										if(evaluateDevIndex < curBtIndex)	/* more devices to be evaluated? */
+										{
+											heartbeatState = SENSOR_HB_CONNECT;
+										}
+										else
+										{
+											heartbeatState = SENSOR_HB_OFFLINE;
+										}
+							break;
+		case SENSOR_HB_CONNECT:			/* handled in data rx section */
+		default:
+							break;
+	}
+}
+
+static void handleERROR()
+{
+	switch(heartbeatState)
+	{
+		case SENSOR_HB_DISCONNECT:			evaluateDevIndex++;
+											connHandle= ' ';
+											if(evaluateDevIndex < curBtIndex)	/* more devices to be evaluated? */
+											{
+												heartbeatState = SENSOR_HB_CONNECT;
+											}
+											else
+											{
+												heartbeatState = SENSOR_HB_OFFLINE;
+											}
+						break;
+		default:
+						break;
+	}
+}
+
+uint8_t cv_heartbeat_HandleData()
+{
+	static uint8_t firstDevice = 1;
+	static uint8_t curLine[MAX_CHAR_PER_LINE];			/* holds complete line and is used for logging */
+	static uint8_t curLineIndex = 0;
+	static uint8_t parameter[40];		/* content of the parameter in read state */
+	static uint8_t writeIndex = 0;
+	static uint8_t complete = 0;
+
+	static readDataType_t readType = BT_READ_NOTHING;
+
+	uint8_t data = 0;
+	data = UART_getChar();
+
+	while((data != 0) && (complete == 0))
+	{
+		if(curLineIndex == MAX_CHAR_PER_LINE - 1)		/* avoid overflow */
+		{
+			InfoLogger_writeLine(curLine,curLineIndex,0);
+			memset(curLine,0,sizeof(curLine));
+			curLineIndex = 0;
+		}
+		if((data == '\r') || (data == '\n'))
+		{
+			if(curLineIndex > 0)
+			{
+				InfoLogger_writeLine(curLine,curLineIndex,0);
+				if(strcmp((char*)curLine,"OK") == 0)
+				{
+					handleOK();
+				}
+				else
+				{
+					if(strcmp((char*)curLine,"ERROR") == 0)
+					{
+						handleERROR();
+					}
+				}
+			}
+			switch(readType)
+			{
+				case BT_READ_DEVICE_NAME: 	if(writeIndex < BLUEMOD_NAME_SIZE)
+											{
+												memcpy (btDeviceList[curBtIndex].name, parameter, writeIndex);
+											}
+								break;
+				case BT_READ_SERV_UUID: 	if((writeIndex < 50) && (curServiceIndex < 10))
+											{
+												memcpy(curDeviceService[curServiceIndex].uuid, parameter, writeIndex);
+											}
+											curServiceIndex++;
+								break;
+				case BT_READ_CHAR_UUID: 	if(writeIndex < 50)
+											{
+												memcpy(curDevCharacteristic[curCharacteristicIndex].uuid, parameter, writeIndex);
+												curCharacteristicIndex++;
+											}
+								break;
+				case BT_READ_DESC_UUID: 	if(writeIndex < 50)
+											{
+												memcpy(curDevDescriptor.uuid, parameter, writeIndex);
+											}
+								break;
+				case BT_READ_PULSE_DATA: 	if(writeIndex < 50)
+											{
+												parsePulseMeasurement(parameter, writeIndex);
+											}
+								break;
+				default:
+					break;
+			}
+			curLineIndex = 0;
+			writeIndex = 0;
+			memset(curLine,0,sizeof(curLine));
+			readType = BT_READ_NOTHING;
+		}
+		else
+		{
+			if(curLineIndex < MAX_CHAR_PER_LINE) curLine[curLineIndex++] = data;
+
+			if(data == ':')
+			{
+				switch(checkIndicators(curLine))
+				{
+					case DEVICE_INDICATOR: 		readType = BT_READ_DEVICE_ADDR;
+						break;
+					case CONNECTION_INDICATOR:  readType = BT_READ_CON_DETAILS;
+						break;
+					case SERVICE_INDICATOR: 	readType = BT_READ_SERV_HANDLE;
+						break;
+					case CHARACTERISTIC_INDICATOR: readType = BT_READ_CHAR_CONHANDLE;
+						break;
+					case DESCRIPTOR_INDICATOR: 	readType = BT_READ_DESC_CONHANDLE;
+						break;
+					case PULSE_INDICATOR:		readType = BT_READ_PULSE_CONHANDLE;
+						break;
+					default:
+						break;
+				}
+				writeIndex = 0;
+				memset(parameter,0,sizeof(parameter));
+			}
+			else
+			{
+				if(data == ',')					/* parameter end */
+				{
+					switch(readType)
+					{
+						case BT_READ_DEVICE_ADDR:  if(writeIndex < BLUEMOD_ADDR_SIZE-1)
+													{
+														if(firstDevice)
+														{
+															firstDevice = 0;
+														}
+														else
+														{
+															curBtIndex++;
+														}
+														parameter[writeIndex-1] = 0;	/*remove 'p' from address */
+														strcpy((char*)btDeviceList[curBtIndex].address, (char*)parameter);
+													}
+													readType = BT_READ_DEVICE_RSSI;
+								break;
+						case BT_READ_DEVICE_RSSI:	if(writeIndex < BLUEMOD_RSSI_SIZE-1)
+													{
+														strcpy((char*)btDeviceList[curBtIndex].rssi, (char*)parameter);
+													}
+													readType = BT_READ_DEVICE_NAME;
+								break;
+						case BT_READ_DEVICE_NAME: 	if(writeIndex < BLUEMOD_NAME_SIZE-1)
+													{
+														memcpy(btDeviceList[curBtIndex].name, parameter, writeIndex);
+													}
+													readType = BT_READ_NOTHING;
+										break;
+						case BT_READ_CON_DETAILS:	connHandle = parameter[0];
+													heartbeatState = SENSOR_HB_SERVICES;
+													readType = BT_READ_NOTHING;
+													curServiceIndex = 0;
+										break;
+						case BT_READ_SERV_HANDLE:	curDeviceService[curServiceIndex].handle = parameter[0];
+													readType = BT_READ_SERV_START;
+										break;
+						case BT_READ_SERV_START: 	if(writeIndex < 6)
+													{
+														memcpy(curDeviceService[curServiceIndex].start, parameter, writeIndex);
+													}
+													readType = BT_READ_SERV_END;
+										break;
+						case BT_READ_SERV_END: 		if(writeIndex < 6)
+													{
+														memcpy(curDeviceService[curServiceIndex].end, parameter, writeIndex);
+													}
+													readType = BT_READ_SERV_UUID;
+										break;
+						case BT_READ_CHAR_CONHANDLE: curDevCharacteristic[curCharacteristicIndex].conHandle = parameter[0];
+													 readType = BT_READ_CHAR_ATTRIBUTE;
+										break;
+						case BT_READ_CHAR_ATTRIBUTE: if(writeIndex < 10)
+													{
+														memcpy(curDevCharacteristic[curCharacteristicIndex].attrHandle, parameter, writeIndex);
+													}
+													readType = BT_READ_CHAR_PROPERTY;
+										break;
+						case BT_READ_CHAR_PROPERTY: if(writeIndex < 10)
+													{
+														memcpy(curDevCharacteristic[curCharacteristicIndex].properties, parameter, writeIndex);
+													}
+													readType = BT_READ_CHAR_VALUEHANDLE;
+										break;
+						case BT_READ_CHAR_VALUEHANDLE: if(writeIndex < 10)
+													{
+														memcpy(curDevCharacteristic[curCharacteristicIndex].valueHandle, parameter, writeIndex);
+													}
+													readType = BT_READ_CHAR_UUID;
+										break;
+						case BT_READ_DESC_CONHANDLE: curDevDescriptor.conHandle = parameter[0];
+													 readType = BT_READ_DESC_CHARHANDLE;
+										break;
+						case BT_READ_DESC_CHARHANDLE: if(writeIndex < 10)
+													{
+														memcpy(curDevDescriptor.charHandle, parameter, writeIndex);
+													}
+													readType = BT_READ_DESC_DESCHANDLE;
+										break;
+						case BT_READ_DESC_DESCHANDLE: if(writeIndex < 10)
+													{
+														memcpy(curDevDescriptor.descHandle, parameter, writeIndex);
+													}
+													readType = BT_READ_DESC_UUID;
+										break;
+						case BT_READ_PULSE_CONHANDLE: curDevDescriptor.conHandle = parameter[0];
+													  readType = BT_READ_PULSE_VALUEHANDLE;
+										break;
+						case BT_READ_PULSE_VALUEHANDLE: if(writeIndex < 10)
+														{
+											//				if(strcmp((char*)curDevCharacteristic[evaluateCharIndex].valueHandle,(char*) parameter) == 0)
+															{
+																readType = BT_READ_PULSE_DATA;
+															}
+#if 0
+															else
+															{
+																readType = BT_READ_NOTHING;
+															}
+#endif
+														}
+										break;
+						default:					readType = BT_READ_NOTHING;
+							break;
+					}
+					writeIndex = 0;
+					memset(parameter,0 , sizeof(parameter));
+				}
+				else
+				{
+					if(readType != BT_READ_NOTHING)
+					{
+						parameter[writeIndex++] = data;
+					}
+				}
+			}
+		}
+		data = UART_getChar();
+	}
+	return complete;
+}
+
+sensorHeartbeat_State_t cv_heartbeat_getState()
+{
+	return heartbeatState;
+}
+
+void openEdit_Heartbeat(void)
+{
+    char text[32];
+    snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Pulse);
+    write_topline(text);
+
+    set_globalState(StMOption_Heartbeat);
+    resetMenuEdit(CLUT_MenuPageCvOption);
+
+    snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_SensorDetect);
+    write_field_button(StMOption_Heartbeat, 30, 299, ME_Y_LINE1, &FontT48, text);
+
+    write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
+
+    setEvent(StMOption_Heartbeat, (uint32_t)OnAction_Heartbeat);
+}
+
+static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+	switch(heartbeatState)
+	{
+		case SENSOR_HB_OFFLINE:
+				HAL_UART_AbortReceive_IT(&UartHandle);
+				MX_UART_BT_Init_DMA();
+				UART_StartDMARx();
+				heartbeatState = SENSOR_HB_ENABLE_BLE;
+				startDetection_ms = HAL_GetTick();
+				curBtIndex = 0;
+				memset(btDeviceList, 0, sizeof(btDeviceList));
+			break;
+
+		default:
+			break;
+	}
+    return UNSPECIFIC_RETURN;
+}
+
+void cv_heartbeat_Control(void)
+{
+	static uint8_t action = 0;
+	static uint8_t retry = 0;
+	static uint8_t lastState = 0;
+	char cmd[50];
+
+	cmd[0] = 0;
+
+	if(action == 3)
+	{
+		action = 0;
+		switch(heartbeatState)
+		{
+			case SENSOR_HB_ENABLE_BLE:	HAL_Delay(1000);
+										snprintf(cmd, sizeof(cmd), "+++" ); //"AT+UBTD=2,1,5000\r\n"
+										InfoLogger_writeLine((uint8_t*)cmd,3,1);
+										HAL_UART_Transmit(&UartHandle, (uint8_t*)cmd, 3, 5000);
+										HAL_Delay(1000);
+										cmd[0] = 0;
+				break;
+			case SENSOR_HB_CHECK_CONFIG:  snprintf(cmd, sizeof(cmd), "AT+UBTCFG=2\r\n" );	// AT+UBTLE?
+
+#if 0
+				if(settingsGetPointer()->dive_mode == DIVEMODE_OC)
+				{
+					snprintf(cmd, sizeof(cmd), "AT+UBTLE=2\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n"
+				}
+				else
+				{
+					snprintf(cmd, sizeof(cmd), "AT+UBTLE=3\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n"
+				}
+#endif
+				break;
+			case SENSOR_HB_DISCOVER:	if(lastState != SENSOR_HB_DISCOVER)
+										{
+											snprintf(cmd, sizeof(cmd), "AT+UBTD=2,1\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n"
+											curBtIndex = 0;
+										}
+
+										//snprintf(cmd, sizeof(cmd), "AT&W\r\n" ); //  AT+UBTD=2,1\r\n "AT+UBTD=2,1,5000\r\n"
+				break;
+#if 0
+			case SENSOR_HB_RESTART:	snprintf(cmd, sizeof(cmd), "AT+UBTD=2,1\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n"
+
+									//	snprintf(cmd, sizeof(cmd), "AT+CPWROFF\r\n" ); //  AT+UBTD=2,1\r\n "AT+UBTD=2,1,5000\r\n"
+				break;
+#endif
+			case SENSOR_HB_CONNECT:		if(evaluateDevIndex < curBtIndex)
+										{
+											snprintf(cmd, sizeof(cmd), "AT+UBTACLC=%s\r\n",btDeviceList[evaluateDevIndex].address);
+										}
+				break;
+			case SENSOR_HB_DISCONNECT:		snprintf(cmd, sizeof(cmd), "AT+UBTACLD=%c\r\n",connHandle);
+				break;
+			case SENSOR_HB_SERVICES:	if((connHandle >= '0') && (connHandle <= '9') && (lastState != SENSOR_HB_SERVICES))
+										{
+											snprintf(cmd, sizeof(cmd), "AT+UBTGDP=%c\r\n",connHandle);
+											memset(curDeviceService, 0, sizeof(curDeviceService));
+										}
+				break;
+			case SENSOR_HB_CHARACTERISTIC:	snprintf(cmd, sizeof(cmd), "AT+UBTGDCS=%c,%s,%s\r\n",connHandle,curDeviceService[evaluateSrvIndex].start
+																								,curDeviceService[evaluateSrvIndex].end);
+											memset(curDevCharacteristic, 0, sizeof(curDevCharacteristic));
+				break;
+			case SENSOR_HB_DESCRIPTOR: 		snprintf(cmd, sizeof(cmd), "AT+UBTGDCD=%c,%s,%s\r\n",connHandle,curDevCharacteristic[evaluateCharIndex].valueHandle
+																											,curDeviceService[evaluateSrvIndex].end);
+				break;
+			case SENSOR_HB_SUBSCRIBE: 		snprintf(cmd, sizeof(cmd), "AT+UBTGWC=%c,%s,1\r\n",connHandle,curDevDescriptor.descHandle);
+				break;
+			default:
+				break;
+		}
+		if(cmd[0] != 0)
+		{
+			{
+				InfoLogger_writeLine((uint8_t*)cmd,strlen(cmd),1);
+				HAL_UART_Transmit(&UartHandle, (uint8_t*)cmd, strlen(cmd), 5000);
+				retry++;
+				if(retry == 3)
+				{
+					heartbeatState = SENSOR_HB_OFFLINE;
+				}
+			}
+		}
+		if(lastState != heartbeatState)
+		{
+			lastState = heartbeatState;
+			retry = 0;
+		}
+	}
+	else
+	{
+		action++;
+	}
+}
+void refresh_Heartbeat(void)
+{
+	char text[32];
+	uint8_t index = 0;
+
+	snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Pulse);
+	write_topline(text);
+
+	switch(heartbeatState)
+	{
+		case SENSOR_HB_OFFLINE:
+		default:							snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_SensorDetect);
+											write_label_var(30, 299, ME_Y_LINE1, &FontT48, text);
+
+	    									if(curBtIndex > 0)
+	    									{
+	    										while((index < curBtIndex) && (index < 3))
+	    										{
+													snprintf(text, 40, "%s", btDeviceList[index].address);
+													write_label_var(  30, 300,  ME_Y_LINE3 + (index * ME_Y_LINE_STEP), &FontT48, text);
+													index++;
+	    										}
+	    									}
+			break;
+		case SENSOR_HB_ENABLE_BLE:			snprintf(text, 32, "Activate BLE");
+											write_label_var(  30, 300, ME_Y_LINE1, &FontT48, text);
+			break;
+		case SENSOR_HB_DISCOVER:
+	    									snprintf(text, 32, "Searching");
+	    									write_label_var(  30, 300, ME_Y_LINE1, &FontT48, text);
+
+	    									if(curBtIndex > 0)
+	    									{
+	    										while((index < curBtIndex) && (index < 4))
+	    										{
+													snprintf(text, 40, "%s", btDeviceList[index].address);
+													write_label_var(  30, 300,  ME_Y_LINE2 + (index * ME_Y_LINE_STEP), &FontT48, text);
+													index++;
+	    										}
+	    									}
+			break;
+	}
+
+    write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
+}
+#endif
--- a/Discovery/Src/data_central.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/data_central.c	Sat Nov 15 19:29:44 2025 +0100
@@ -717,10 +717,12 @@
 
 uint32_t	CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words)
 {
- cm_t        crc_model;
- uint32_t      word_to_do;
- uint8_t       byte_to_do;
- int         i;
+	 cm_t        crc_model;
+	 uint32_t      word_to_do;
+	 uint8_t       byte_to_do;
+	 int         i;
+
+	 uint32_t wordCnt = 0;
  
      // Values for the STM32F generator.
  
@@ -733,10 +735,10 @@
  
      cm_ini(&crc_model);
  
-     while (words--)
+     do
      {
          // The STM32F10x hardware does 32-bit words at a time!!!
-				if(words > (768000/4))
+				if(wordCnt >= (768000/4))
 					word_to_do = *buffer2++;
 				else
 					word_to_do = *buffer1++;
@@ -765,7 +767,8 @@
  
              cm_nxt(&crc_model, byte_to_do);
          }
-     }
+         wordCnt++;
+     } while (wordCnt != words);
  
      // Return the final result.
  
@@ -843,30 +846,33 @@
 {
 	float newTarget = newHeading;
 
-	if(settingsGetPointer()->compassInertia == 0)
+	if((newHeading > 0.0) && (newHeading < 360))
 	{
-		compass_compensated = newHeading;
-	}
-	else
-	{
-		if((compass_compensated > 270.0) && (newHeading < 90.0))		/* transition passing 0 clockwise */
+		if(settingsGetPointer()->compassInertia == 0)
 		{
-			newTarget = newHeading + 360.0;
+			compass_compensated = newHeading;
 		}
+		else
+		{
+			if((compass_compensated > 270.0) && (newHeading < 90.0))		/* transition passing 0 clockwise */
+			{
+				newTarget = newHeading + 360.0;
+			}
 
-		if((compass_compensated < 90.0) && (newHeading > 270.0))		/* transition passing 0 counter clockwise */
-		{
-			newTarget = newHeading - 360.0;
-		}
+			if((compass_compensated < 90.0) && (newHeading > 270.0))		/* transition passing 0 counter clockwise */
+			{
+				newTarget = newHeading - 360.0;
+			}
 
-		compass_compensated = compass_compensated + ((newTarget - compass_compensated) / (COMPASS_FRACTION * (settingsGetPointer()->compassInertia)));
-		if(compass_compensated < 0.0)
-		{
-			compass_compensated += 360.0;
-		}
-		if(compass_compensated >= 360.0)
-		{
-			compass_compensated -= 360.0;
+			compass_compensated = compass_compensated + ((newTarget - compass_compensated) / (COMPASS_FRACTION * (settingsGetPointer()->compassInertia)));
+			if(compass_compensated < 0.0)
+			{
+				compass_compensated += 360.0;
+			}
+			if(compass_compensated >= 360.0)
+			{
+				compass_compensated -= 360.0;
+			}
 		}
 	}
 }
@@ -972,6 +978,62 @@
     return color;
 }
 
+void formatStringOfTime(char* pString, uint8_t strLen, RTC_TimeTypeDef Stime, uint8_t showAlive, uint8_t showSeconds)
+{
+    char timeSuffix[] = {0,0,0};
+    uint8_t hours;
+
+	if(strLen > 10)
+	{
+
+        hours = Stime.Hours;
+        if (settingsGetPointer()->amPMTime)
+        {
+        	timeSuffix[1] = 'M';
+    		if (Stime.Hours > 11)
+    		{
+    			timeSuffix[0] = 'P';
+    		}
+    		else
+    		{
+    			timeSuffix[0] = 'A';
+    		}
+
+    		if (Stime.Hours % 12 == 0)
+    		{
+    			hours = 12;
+    		}
+    		else
+    		{
+    			hours = (Stime.Hours % 12);
+    		}
+        }
+
+       	if(showSeconds)
+       	{
+       		if((Stime.Seconds % 2) || (!showAlive))
+       		{
+       			snprintf(pString, strLen,"%02d:%02d:%02d\016\016%s\017",hours, Stime.Minutes, Stime.Seconds,timeSuffix);
+       		}
+       		else
+       		{
+       			snprintf(pString, strLen,"%02d\031:\030%02d\031:\030%02d\016\016%s\017",hours, Stime.Minutes, Stime.Seconds,timeSuffix);
+       		}
+       	}
+       	else
+       	{
+       		if((Stime.Seconds % 2) || (!showAlive))
+       		{
+       			snprintf(pString, strLen,"%02d:%02d\016\016%s\017",hours, Stime.Minutes,timeSuffix);
+       		}
+        	else
+        	{
+        		snprintf(pString, strLen,"%02d\031:\030%02d\016\016%s\017",hours, Stime.Minutes,timeSuffix);
+        	}
+        }
+	}
+}
+
 /* returns the date in the order defined by the settings DDMMYY => X */
 void convertStringOfDate_DDMMYY(char* pString, uint8_t strLen, uint8_t day, uint8_t month, uint8_t year)
 {
--- a/Discovery/Src/data_exchange_main.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/data_exchange_main.c	Sat Nov 15 19:29:44 2025 +0100
@@ -412,7 +412,7 @@
 				break;
 			case SENSOR_CO2:	SensorActive[SENSOR_CO2] = 1;
 				break;
-#if defined ENABLE_GPIO_V2 || defined ENABLE_GNSS_SUPPORT
+#if defined ENABLE_GNSS_INTERNAL || defined ENABLE_GNSS_EXTERN
 			case SENSOR_GNSS:	SensorActive[SENSOR_GNSS] = 1;
 				break;
 #endif
@@ -442,12 +442,10 @@
 	}
 #endif
 
-#ifdef ENABLE_GPIO_V2
-	if(getBuzzerActivationState())
+	if((isNewDisplay()) && getBuzzerActivationState())
 	{
 		externalInterface_Cmd |= EXT_INTERFACE_BUZZER_ON;
 	}
-#endif
 
 	dataOut.data.externalInterface_Cmd = externalInterface_Cmd;
 	externalInterface_Cmd = 0;
@@ -468,7 +466,11 @@
 		dataOut.revisionHardware = 0xFF;
 		dataOut.revisionCRCx0x7A = 0xFF;
 	}
-	
+	if(isNewDisplay())
+	{
+		dataOut.displayVersion = 1;
+	}
+
 	if(DataEX_check_header_and_footer_ok() && !told_reset_logik_alles_ok)
 	{
 		MX_tell_reset_logik_alles_ok();
@@ -847,8 +849,7 @@
 	SDiveState *pStateReal = stateRealGetPointerWrite();
 	uint8_t idx;
 	float meter = 0;
-	SSettings *pSettings;
-	
+
 #ifdef ENABLE_EXTERNAL_PRESSURE
     float CO2Corr = 0.0;
 #endif
@@ -912,6 +913,7 @@
 		}
 	}
 
+	SSettings *pSettings = settingsGetPointer();
 	if((requestNecessary.uw != 0) && (dataIn.confirmRequest.uw != 0))
 	{
 		if(((dataIn.confirmRequest.uw) & CRBUTTON) != 0)
@@ -949,14 +951,12 @@
 
 		if(requestNecessary.ub.button == 1)	/* send button values to RTE */
 		{
-			setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness);
+			setButtonResponsiveness(pSettings->ButtonResponsiveness);
 		}
 	}
 
 	/*	uint8_t IAmStolenPleaseKillMe;
 	 */
-	pSettings = settingsGetPointer();
-
 	if(pSettings->IAmStolenPleaseKillMe > 3)
 	{
 		pSettings->salinity = 0;
@@ -1044,7 +1044,7 @@
             disableTimer();
 
 				// new 170508
-			settingsGetPointer()->bluetoothActive = 0;
+			pSettings->bluetoothActive = 0;
 			MX_Bluetooth_PowerOff();
 			//Init dive Mode
 			decoLock = DECO_CALC_init_as_is_start_of_dive;
@@ -1374,3 +1374,12 @@
 	return;
 }
 
+bool isScrubberTimerEnabled(const SSettings *settings)
+{
+	return settings->scrubberActiveId != 0x00 && isLoopMode(settings->dive_mode);
+}
+
+bool isScrubberTimerRunning(const SDiveState *diveState, const SSettings *settings)
+{
+	return isScrubberTimerEnabled(settings) && diveState->mode == MODE_DIVE && isLoopMode(diveState->diveSettings.diveMode);
+}
--- a/Discovery/Src/demo.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/demo.c	Sat Nov 15 19:29:44 2025 +0100
@@ -28,6 +28,8 @@
 #include "data_exchange_main.h" // for time_elapsed_ms()
 #include "settings.h"
 #include "ostc.h"
+#include "tInfoLogger.h"
+#include <string.h>
 
 #ifndef DEMOMODE
 
@@ -425,5 +427,62 @@
 
 #endif // DEMO
 
+#ifdef ENABLE_USART_RADIO				/* debug function to check receiption of radio data */
+void demo_HandleData(void)
+{
+	static uint8_t comStarted = 0;
+	static uint8_t text[50];
+	static uint8_t index = 0;
+	static uint32_t startTick = 0;
+	static uint8_t firstData = 1;
+	uint8_t data = 0;
+
+	switch(comStarted)
+	{
+		case 0: 	startTick = HAL_GetTick();
+					comStarted++;
+				break;
+		case 1:		if(time_elapsed_ms(startTick, HAL_GetTick()) > 5000)
+					{
+						MX_UART_RADIO_Init_DMA();
+						UART_StartDMARxRadio();
+						comStarted++;
+						sprintf((char*)text,"RadioStarted");
+						InfoLogger_writeLine(text,strlen((char*)text),1);
+					}
+			break;
+		case 2:				data = UART_getChar();
+							if(data != 0)
+							{
+								if(firstData)
+								{
+									firstData = 0;
+									sprintf((char*)text,"FirstData");
+									InfoLogger_writeLine(text,strlen((char*)text),1);
+								}
+								if((index == 50) || (data =='r')  || (data =='n'))
+								{
+									if(index > 0)
+									{
+										InfoLogger_writeLine(text,index,0);
+										index = 0;
+									}
+								}
+								else
+								{
+									text[index++] = data;
+								}
+							}
+			break;
+		default:
+			break;
+	}
+
+
+	{
+	}
+}
+#endif
+
 
 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- a/Discovery/Src/display.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/display.c	Sat Nov 15 19:29:44 2025 +0100
@@ -407,7 +407,7 @@
 	aTxBuffer[1] = OLED_VFP_SET_13h;
 	send((uint8_t*)aTxBuffer, 2);
 	aTxBuffer[0] = 0x72;
-	aTxBuffer[1] = 0x08;
+	aTxBuffer[1] = 0x0C;
 	send((uint8_t*)aTxBuffer, 2);
 
 	aTxBuffer[0] = 0x70;
--- a/Discovery/Src/externLogbookFlash.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/externLogbookFlash.c	Sat Nov 15 19:29:44 2025 +0100
@@ -84,17 +84,6 @@
 
 #define HEADER2OFFSET 0x400
 
-typedef enum{
-	EF_HEADER,
-	EF_SAMPLE,
-	EF_DEVICEDATA,
-	EF_VPMDATA,
-	EF_SETTINGS,
-	EF_FIRMWARE,
-	EF_FIRMWARE2,
-}which_ring_enum;
-
-
 typedef struct{
 uint8_t IsBusy:1;
 uint8_t IsWriteEnabled:1;
@@ -130,6 +119,7 @@
 static uint32_t	actualPointerDevicedata = DDSTART;
 static uint32_t	actualPointerVPM = 0;
 static uint32_t	actualPointerSettings = SETTINGSSTART;
+static uint32_t	actualPointerProfile = PROFILE0_START;
 static uint32_t	actualPointerFirmware = 0;
 static uint32_t	actualPointerFirmware2 = 0;
 
@@ -344,7 +334,11 @@
 		}
 		else if(pSample2)
 		{
-			actualAddress += length1;
+			/* actualAddress += length1; do dummy read to get EEPROM to the correct address */
+			for(uint32_t i = 0; i<length1; i++)
+			{
+				ext_flash_read_block(&pSample2[0], EF_FIRMWARE2);
+			}
 			for(uint32_t i = 0; i<length2; i++)
 			{
 				ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);
@@ -527,28 +521,44 @@
 	return;
 }
 #else
-void ext_flash_write_settings(uint8_t resetRing)
+void ext_flash_write_settings(uint8_t whichSettings, uint8_t resetRing)
 {
-	uint8_t *pData;
+	SSettings *pSettings;
 	const uint16_t length = sizeof(SSettings);
 	uint8_t length_lo, length_hi;
 	uint8_t dataLength[2] = { 0 };
 
+	pSettings = settingsGetPointer();
+
 	ext_flash_disable_protection();
 
-	if(stateRealGetPointer()->lastKnownBatteryPercentage)
+	switch (whichSettings)
 	{
-		settingsGetPointer()->lastKnownBatteryPercentage = stateRealGetPointer()->lastKnownBatteryPercentage;
-	}
-	settingsGetPointer()->backup_localtime_rtc_tr = stateRealGetPointer()->lifeData.timeBinaryFormat;
-	settingsGetPointer()->backup_localtime_rtc_dr = stateRealGetPointer()->lifeData.dateBinaryFormat;
-
-	pData = (uint8_t *)settingsGetPointer();
-
-	/* Reset the Ring to the start address if requested (e.g. because we write the default block during shutdown) */
-	if((resetRing) || ((actualPointerSettings + length) >= SETTINGSSTOP))
-	{
-		actualPointerSettings = SETTINGSSTART;
+		default:
+		case EF_SETTINGS:		if(stateRealGetPointer()->lastKnownBatteryPercentage)
+								{
+									pSettings->lastKnownBatteryPercentage = stateRealGetPointer()->lastKnownBatteryPercentage;
+								}
+								pSettings->backup_localtime_rtc_tr = stateRealGetPointer()->lifeData.timeBinaryFormat;
+								pSettings->backup_localtime_rtc_dr = stateRealGetPointer()->lifeData.dateBinaryFormat;
+								/* Reset the Ring to the start address if requested (e.g. because we write the default block during shutdown) */
+								if((resetRing) || ((actualPointerSettings + length) >= SETTINGSSTOP))
+								{
+									actualPointerSettings = SETTINGSSTART;
+								}
+			break;
+		case EF_PROFILE0:		actualPointerProfile = PROFILE0_START;
+								pSettings = profileGetPointer(0);
+			break;
+		case EF_PROFILE1:		actualPointerProfile = PROFILE1_START;
+								pSettings = profileGetPointer(1);
+			break;
+		case EF_PROFILE2:		actualPointerProfile = PROFILE2_START;
+								pSettings = profileGetPointer(2);
+			break;
+		case EF_PROFILE3:		actualPointerProfile = PROFILE3_START;
+								pSettings = profileGetPointer(3);
+			break;
 	}
 
 	length_lo = (uint8_t)(length & 0xFF);
@@ -556,8 +566,8 @@
 	dataLength[0] = length_lo;
 	dataLength[1] = length_hi;
 
-	ef_write_block(dataLength,2, EF_SETTINGS, 0);
-	ef_write_block(pData,length, EF_SETTINGS, 0);
+	ef_write_block(dataLength,2, whichSettings, 0);
+	ef_write_block((uint8_t*)pSettings,length, whichSettings, 0);
 //	ext_flash_enable_protection();
 }
 #endif
@@ -570,7 +580,7 @@
  * new settings should be fine as they are added
  * and loaded before calling this function
  */
-uint8_t ext_flash_read_settings(void)
+uint8_t ext_flash_read_settings(uint8_t whichSettings)
 {
 	uint8_t returnValue = HAL_BUSY;
 	uint8_t exit = 0;
@@ -579,69 +589,90 @@
 	uint8_t length_lo, length_hi;
 	uint16_t lengthOnEEPROM;
 	uint32_t header;
-	SSettings *pSettings = settingsGetPointer();
-
-	actualAddress = SETTINGSSTART;
+	SSettings* pSettings = settingsGetPointer();
 
-	ext_flash_read_block_start();
-	ext_flash_read_block(&length_lo, EF_SETTINGS);
-	ext_flash_read_block(&length_hi, EF_SETTINGS);
-	
-	while ((length_lo != 0xFF) && (length_hi != 0xFF) && (exit == 0))		/* get the latest stored setting block */
+	switch(whichSettings)
+	{
+		case EF_SETTINGS:	pSettings = settingsGetPointer();
+							actualAddress = SETTINGSSTART;
+			break;
+		case EF_PROFILE0:	pSettings = profileGetPointer(0);
+							actualAddress = PROFILE0_START;
+			break;
+		case EF_PROFILE1:	pSettings = profileGetPointer(1);
+							actualAddress = PROFILE1_START;
+					break;
+		case EF_PROFILE2:	pSettings = profileGetPointer(2);
+							actualAddress = PROFILE2_START;
+					break;
+		case EF_PROFILE3:	pSettings = profileGetPointer(3);
+							actualAddress = PROFILE3_START;
+					break;
+		default: returnValue = HAL_ERROR;
+	}
+
+	if(returnValue != HAL_ERROR)
 	{
-		lengthOnEEPROM = length_hi * 256;
-		lengthOnEEPROM += length_lo;
-		if(lengthOnEEPROM <= lengthStandardNow) 			/* EEPROM Header size equal or smaller => settings constant or upgraded */
+		ext_flash_read_block_start();
+		ext_flash_read_block(&length_lo, whichSettings);
+		ext_flash_read_block(&length_hi, whichSettings);
+
+		while ((length_lo != 0xFF) && (length_hi != 0xFF) && (exit == 0))		/* get the latest stored setting block */
 		{
-			ext_flash_read_block_multi(&header, 4, EF_SETTINGS);
-			if((header <= pSettings->header) && (header >= pSettings->updateSettingsAllowedFromHeader))	/* check to allow update of header */
+			lengthOnEEPROM = length_hi * 256;
+			lengthOnEEPROM += length_lo;
+			if(lengthOnEEPROM <= lengthStandardNow) 			/* EEPROM Header size equal or smaller => settings constant or upgraded */
 			{
-				returnValue = HAL_OK;
-				pSettings->header = header;
-				pData = (uint8_t *)pSettings + 4; /* header */
-				for(uint16_t i = 0; i < (lengthOnEEPROM-4); i++)
-					ext_flash_read_block(&pData[i], EF_SETTINGS);
-				if(header != pSettings->header)				/* setting layout changed => no additional setting sets expected */
+				ext_flash_read_block_multi(&header, 4, whichSettings);
+				if((header <= pSettings->header) && (header >= pSettings->updateSettingsAllowedFromHeader))	/* check to allow update of header */
 				{
+					returnValue = HAL_OK;
+					pSettings->header = header;
+					pData = (uint8_t *)pSettings + 4; /* header */
+					for(uint16_t i = 0; i < (lengthOnEEPROM-4); i++)
+						ext_flash_read_block(&pData[i], whichSettings);
+					if(header != pSettings->header)				/* setting layout changed => no additional setting sets expected */
+					{
+						exit = 1;
+					}
+				}
+				else
+				{
+					returnValue = HAL_ERROR;
 					exit = 1;
 				}
 			}
-			else
+			else											/* size of settings decreased => possible downgrade of firmware */
 			{
-				returnValue = HAL_ERROR;
+				ext_flash_read_block_multi(&header, 4, whichSettings);
+
+				if(header > 0xFFFF0014)						/* verify that new (old) header should be compatible (only less bytes, no change in layout) */
+				{
+					returnValue = HAL_OK;
+					pSettings->header = header;
+					pData = (uint8_t *)pSettings + 4; /* header */
+					for(uint16_t i = 0; i < (lengthStandardNow-4); i++) 		/* only read the data fitting into the structure */
+						ext_flash_read_block(&pData[i], whichSettings);
+				}
+				else
+				{
+					returnValue = HAL_ERROR;
+				}
 				exit = 1;
 			}
+			ext_flash_read_block(&length_lo, whichSettings);
+			ext_flash_read_block(&length_hi, whichSettings);
 		}
-		else											/* size of settings decreased => possible downgrade of firmware */
-		{
-			ext_flash_read_block_multi(&header, 4, EF_SETTINGS);
+		ext_flash_decf_address_ring(whichSettings);				/* set pointer back to empty address */
+		ext_flash_decf_address_ring(whichSettings);
+		ext_flash_read_block_stop();
 
-			if(header > 0xFFFF0014)						/* verify that new (old) header should be compatible (only less bytes, no change in layout) */
-			{
-				returnValue = HAL_OK;
-				pSettings->header = header;
-				pData = (uint8_t *)pSettings + 4; /* header */
-				for(uint16_t i = 0; i < (lengthStandardNow-4); i++) 		/* only read the data fitting into the structure */
-					ext_flash_read_block(&pData[i], EF_SETTINGS);
-			}
-			else
-			{
-				returnValue = HAL_ERROR;
-			}
-			exit = 1;
+		if(actualAddress > actualPointerSettings)				/* the write pointer has not yet been set up probably */
+		{
+			actualPointerSettings = actualAddress;
 		}
-		ext_flash_read_block(&length_lo, EF_SETTINGS);
-		ext_flash_read_block(&length_hi, EF_SETTINGS);
+		ext_flash_read_block_stop();
 	}
-	ext_flash_decf_address_ring(EF_SETTINGS);				/* set pointer back to empty address */
-	ext_flash_decf_address_ring(EF_SETTINGS);
-	ext_flash_read_block_stop();
-
-	if(actualAddress > actualPointerSettings)				/* the write pointer has not yet been set up probably */
-	{
-		actualPointerSettings = actualAddress;
-	}
-	ext_flash_read_block_stop();
 	return returnValue;
 }
 
@@ -1851,6 +1882,13 @@
 			ringStart = FWSTART2;
 			ringStop = FWSTOP2;
 			break;
+		case EF_PROFILE0:
+		case EF_PROFILE1:
+		case EF_PROFILE2:
+		case EF_PROFILE3:	actualAddress = actualPointerProfile;
+							ringStart = PROFILE0_START;
+							ringStop = PROFILE3_STOP;
+			break;
 		default:
 			ringStart = FLASHSTART;
 			ringStop = FLASHSTOP;
@@ -1932,6 +1970,11 @@
 		case EF_FIRMWARE2:
 			actualPointerFirmware2 = actualAddress;
 			break;
+		case EF_PROFILE0:
+		case EF_PROFILE1:
+		case EF_PROFILE2:
+		case EF_PROFILE3:	actualPointerProfile = actualAddress;
+			break;
 		default:
 			break;
 	}
@@ -1996,6 +2039,13 @@
 			ringStart = SETTINGSSTART;
 			ringStop = SETTINGSSTOP;
 			break;
+		case EF_PROFILE0:
+		case EF_PROFILE1:
+		case EF_PROFILE2:
+		case EF_PROFILE3:	ringStart = PROFILE0_START;
+							ringStop = PROFILE3_STOP;
+			break;
+
 		default:
 			ringStart = FLASHSTART;
 			ringStop = FLASHSTOP;
@@ -2145,6 +2195,12 @@
 			ringStart = FWSTART2;
 			ringStop = FWSTOP2;
 			break;
+		case EF_PROFILE0:
+		case EF_PROFILE1:
+		case EF_PROFILE2:
+		case EF_PROFILE3:	ringStart = PROFILE0_START;
+							ringStop = PROFILE3_STOP;
+			break;
 		default:
 			ringStart = FLASHSTART;
 			ringStop = FLASHSTOP;
@@ -2190,6 +2246,13 @@
 			ringStart = FWSTART2;
 			ringStop = FWSTOP2;
 			break;
+		case EF_PROFILE0:
+		case EF_PROFILE1:
+		case EF_PROFILE2:
+		case EF_PROFILE3:	ringStart = PROFILE0_START;
+							ringStop = PROFILE3_STOP;
+			break;
+
 		default:
 			ringStart = FLASHSTART;
 			ringStop = FLASHSTOP;
--- a/Discovery/Src/gfx_colors.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/gfx_colors.c	Sat Nov 15 19:29:44 2025 +0100
@@ -89,8 +89,8 @@
 	0x00AC00ff,//0x00E5AE18, // CLUT_MenuPageHardware
 	0x00ff00ff,//0x00E5AEFF, // CLUT_MenuPageSystem 
 	0x00FF55FF,//0x00FFFF00, // CLUT_MenuPageCustomView
+	0x00FFAAFF, // CLUT_MenuPageCVOption
 	0x00C4EACC, // CLUT_MenuPageDivePlanner
-	0x00000000, // CLUT_MenuPage10 - UNUSED
 	0x00FFFFFF, // CLUT_ButtonSymbols
 	0x000092D0, // CLUT_InfoSurface
 	0x000092D0, // CLUT_InfoDive - UNUSED
--- a/Discovery/Src/gfx_engine.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/gfx_engine.c	Sat Nov 15 19:29:44 2025 +0100
@@ -1075,7 +1075,7 @@
 
 
 /* this is NOT fast nor optimized */
-static void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color)
+void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color)
 {
 	uint16_t* pDestination;
 
@@ -3483,7 +3483,7 @@
 
 #define		Vsync_d1	2
 #define		VFP_d1		4	// make sure this value * VSYNC is also set in display.c for OLED_VFP_SET
-#define		VBP_d1		4	// make sure this value * VSYNC is also set in display.c for OLED_VBP_SET
+#define		VBP_d1		6	// make sure this value * VSYNC is also set in display.c for OLED_VBP_SET
 
   /* Horizontal synchronization width = Hsync - 1 */
   LtdcHandle.Init.HorizontalSync = Hsync_d1 - 1;
@@ -3828,7 +3828,7 @@
 		hgfx.WindowX1 = 779;
 		if(Font == &FontT24)
 		{
-			hgfx.WindowX0 = hgfx.WindowX1 - (Font->spacesize*3);
+			hgfx.WindowX0 = hgfx.WindowX1 - (Font->spacesize*7);
 		}
 		else
 		{
--- a/Discovery/Src/logbook.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/logbook.c	Sat Nov 15 19:29:44 2025 +0100
@@ -67,6 +67,9 @@
 #define DEFAULT_SAMPLES	(100)	/* Number of sample data bytes in case of an broken header information */
 #define DUMMY_SAMPLES	(1000)	/* Maximum number of samples profided by a dummy dive profile */
 
+#define SCRUBBER_ERROR_FLAG 0x4000
+#define SCRUBBER_WARNING_FLAG 0x2000
+
 typedef struct /* don't forget to adjust void clear_divisor(void) */
 {
 	uint8_t temperature;
@@ -467,6 +470,10 @@
             eventByte1.ub.bit7 = 1;
             eventByte2.ub.bit2 = 1;
     }
+    if (state->events.scrubberState) {
+        eventByte1.ub.bit7 = 1;
+        eventByte2.ub.bit3 = 1;
+    }
 
     //Add EventByte 1
     if(eventByte1.uw > 0)
@@ -510,8 +517,9 @@
     }
     if (state->events.compassHeadingUpdate) {
         // New heading and type of heading
-        sample[length++] = state->events.info_compassHeadingUpdate & 0xFF;
-        sample[length++] = (state->events.info_compassHeadingUpdate & 0xFF00) >> 8;
+        pdata = (uint8_t*)&state->events.info_compassHeadingUpdate;
+        sample[length++] = *pdata++;
+        sample[length++] = *pdata++;
     }
     if (state->events.gnssPositionUpdate) {
     	pdata = (uint8_t*)&state->events.info_gnssPosition.fLon;
@@ -525,6 +533,11 @@
         sample[length++] = *pdata++;
         sample[length++] = *pdata++;
     }
+    if (state->events.scrubberState) {
+        pdata = (uint8_t*)&state->events.info_scrubberState;
+        sample[length++] = *pdata++;
+        sample[length++] = *pdata++;
+    }
 
     if(divisor.temperature == 0)
     {
@@ -706,7 +719,7 @@
   */
 static uint16_t readSample(int32_t* depth, int16_t * gasid, int16_t* setpoint_cbar, int32_t* temperature, int32_t* sensor1, int32_t* sensor2,
 						   int32_t* sensor3, int32_t* cns, SManualGas* manualGas, int16_t* bailout, int16_t* decostopDepth, uint16_t* tank,
-						   SGnssCoord* pPosition, uint8_t* event)
+						   uint16_t* compassHeading, SGnssCoord* pPosition, uint16_t* scrubberState, uint8_t* event)
 {
 	int length = 0;
 	_Bool bEvent = 0;
@@ -740,6 +753,12 @@
   if(tank)
 	  *tank = 0;
 
+  if (compassHeading)
+    *compassHeading = UINT16_MAX;
+
+  if (scrubberState)
+    *scrubberState = UINT16_MAX;
+
   if(manualGas)
   {
     manualGas->percentageO2 =-1;
@@ -836,6 +855,14 @@
 				if(gasid)
 						*gasid = 0;
 			}
+
+            // Compass heading
+            if (eventByte2.ub.bit1) {
+                ext_flash_read_next_sample_part((uint8_t*)compassHeading, 2);
+                bytesRead += 2;
+                length -= 2;
+            }
+
 			/* gnss position start dive */
 			if(eventByte2.ub.bit2)
 			{
@@ -864,6 +891,13 @@
 					memcpy(&pPosition->fLat, &tempU32, 4);
 				}
 			}
+
+            // Scrubber state
+            if (eventByte2.ub.bit3) {
+                ext_flash_read_next_sample_part((uint8_t*)scrubberState, 2);
+                bytesRead += 2;
+                length -= 2;
+            }
 	}
 
 	if(divisor.temperature == 0)
@@ -1006,7 +1040,7 @@
   */
 uint16_t logbook_readSampleData(uint8_t StepBackwards, uint16_t length,uint16_t* depth, uint8_t*  gasid, int16_t* temperature, uint16_t* ppo2,
 							    uint16_t* setpoint, uint16_t* sensor1, uint16_t* sensor2, uint16_t* sensor3, uint16_t* cns, uint8_t* bailout,
-								uint16_t* decostopDepth, uint16_t* tank, SGnssCoord* pPosition, uint8_t* event)
+								uint16_t* decostopDepth, uint16_t* tank, uint16_t* compassHeading, SGnssCoord* pPosition, uint16_t* scrubberState, uint8_t* event)
 {
      //Test read
     //SLogbookHeader header;
@@ -1043,6 +1077,10 @@
 	uint16_t tankVal = 0;
 	uint32_t small_profileLength = 0;
 	uint8_t eventdata;
+    uint16_t compassHeadingVal;
+    uint16_t compassHeadingLast = UINT16_MAX;
+    uint16_t scrubberStateVal;
+    uint16_t scrubberStateLast = UINT16_MAX;
 	SGnssCoord posCoord;
 	posCoord.fLat = 0.0;
 	posCoord.fLon = 0.0;
@@ -1126,7 +1164,7 @@
 				ext_flash_set_entry_point();
 				divisorBackup = divisor;
 				retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
-									&bailoutVal, &decostepDepthVal, &tankVal, &posCoord, &eventdata);
+									&bailoutVal, &decostepDepthVal, &tankVal, &compassHeadingVal, &posCoord, &scrubberStateVal, &eventdata);
 
 				if(retVal == 0)
 				{
@@ -1134,7 +1172,7 @@
 						ext_flash_reopen_read_sample_at_entry_point();
 						divisor = divisorBackup;
 						retVal = readSample(&depthVal,&gasidVal,&setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal,
-											&manualGasVal, &bailoutVal, &decostepDepthVal, &tankVal, &posCoord, &eventdata);
+											&manualGasVal, &bailoutVal, &decostepDepthVal, &tankVal, &compassHeadingVal, &posCoord, &scrubberStateVal, &eventdata);
 
 						if(retVal == 0)
 								break;
@@ -1201,6 +1239,16 @@
 				else
 						decostepDepthLast = decostepDepthVal;
 
+				if (compassHeadingVal == UINT16_MAX)
+						compassHeadingVal = compassHeadingLast;
+				else
+						compassHeadingLast = compassHeadingVal;
+
+				if (scrubberStateVal == UINT16_MAX)
+						scrubberStateVal = scrubberStateLast;
+				else
+						scrubberStateLast = scrubberStateVal;
+
 				counter++;
 				// Heed compression
 				// Write here to arrays
@@ -1264,6 +1312,13 @@
 						sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF;
 					if(sensor3)
 						sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF;
+
+                    if (compassHeading)
+                        compassHeading[iNum] = compassHeadingVal;
+
+                    if (scrubberState)
+                        scrubberState[iNum] = scrubberStateVal;
+
 					iNum++;
 					counter = 0;
 
@@ -1274,6 +1329,7 @@
 					}
 				}
 		}
+
 		if(pPosition)
 		{
 			memcpy(pPosition, &posCoord, sizeof(posCoord));
@@ -1321,8 +1377,23 @@
 		{
 			//InitdiveProfile
 			pSettings->totalDiveCounter++;
-			logbook_initNewdiveProfile(pStateReal,settingsGetPointer());
+			logbook_initNewdiveProfile(pStateReal, pSettings);
 			min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius;
+            if (isScrubberTimerRunning(pStateReal, pSettings)) {
+                int16_t maxScrubberTime = INT16_MIN;
+                SScrubberData *longestScrubberData = NULL;
+                for (unsigned timerId = 0; timerId < 2; timerId++) {
+                    if (pSettings->scrubberActiveId & (1 << timerId)) {
+                        SScrubberData *scrubberData = &pStateReal->scrubberDataDive[timerId];
+                        if (scrubberData->TimerCur > maxScrubberTime) {
+                            maxScrubberTime = scrubberData->TimerCur;
+                            longestScrubberData = scrubberData;
+                        }
+                    }
+                }
+
+                logScrubberState(longestScrubberData);
+            }
 
 			//Write logbook sample
 			logbook_writeSample(pStateReal);
@@ -1355,13 +1426,13 @@
 				{
 					pSettings->logbookOffset++;
 				}
-				ext_flash_write_settings(0);
+				ext_flash_write_settings(EF_SETTINGS,0);
 				ext_flash_disable_protection_for_logbook();
 
 				ext_flash_CloseSector();	/* this is just a repair function which invalidates a not used sector in case a log maintenance was called before dive */
 				bDiveMode = 3;
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 			pStateReal->events.gnssPositionUpdate = 1;
 
 			if(pStateReal->lifeData.gnssData.alive & GNSS_ALIVE_BACKUP_POS)
@@ -1873,7 +1944,9 @@
     int16_t decostepDepthVal = 0;
 	uint16_t tankVal = 0;
 	uint8_t eventdata;
+    uint16_t compassHeadingVal;
 	SGnssCoord posCoord;
+    uint16_t scrubberStateVal;
 
 		//uint16_t* ppo2, uint16_t* cns#
      uint32_t bytesRead = 0;
@@ -1894,21 +1967,21 @@
         ext_flash_set_entry_point();
         divisorBackup = divisor;
 		retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
-							&bailoutVal, &decostepDepthVal,&tankVal, &posCoord, &eventdata);
+							&bailoutVal, &decostepDepthVal, &tankVal, &compassHeadingVal, &posCoord, &scrubberStateVal, &eventdata);
         if(retVal == 0)
         {
           //Error try to read again!!!
           ext_flash_reopen_read_sample_at_entry_point();
           divisor = divisorBackup;
 		  retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
-								&bailoutVal, &decostepDepthVal, &tankVal, &posCoord, &eventdata);
+								&bailoutVal, &decostepDepthVal, &tankVal, &compassHeadingVal, &posCoord, &scrubberStateVal, &eventdata);
           if(retVal == 0)
           {
               //Error try to read again!!!
               ext_flash_reopen_read_sample_at_entry_point();
               divisor = divisorBackup;
 			  retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
-				 				&bailoutVal, &decostepDepthVal,&tankVal, &posCoord, &eventdata);
+				 				&bailoutVal, &decostepDepthVal, &tankVal, &compassHeadingVal, &posCoord, &scrubberStateVal, &eventdata);
               if(retVal == 0)
               {
                 ext_flash_reopen_read_sample_at_entry_point();
@@ -2146,5 +2219,19 @@
 	dummyReadIdx += length;
 }
 
+void logScrubberState(const SScrubberData *scrubberData)
+{
+    uint16_t scrubberState = scrubberData->TimerCur & 0x0FFF; // truncate to 12 bit
+    if (isScrubberError(scrubberData)) {
+        scrubberState |= SCRUBBER_ERROR_FLAG;
+    }
+
+    if (isScrubberWarning(scrubberData)) {
+        scrubberState |= SCRUBBER_WARNING_FLAG;
+    }
+
+    stateUsedWrite->events.scrubberState = 1;
+    stateUsedWrite->events.info_scrubberState = scrubberState;
+}
 
 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- a/Discovery/Src/logbook_miniLive.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/logbook_miniLive.c	Sat Nov 15 19:29:44 2025 +0100
@@ -367,7 +367,7 @@
     	ReplayDataOffset = StepBackwards;
 		logbook_getHeader(StepBackwards ,&logbookHeader);
 
-		dataLength = logbook_readSampleData(StepBackwards, DEPTH_DATA_LENGTH, ReplayDepthData,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ReplayMarkerData);
+		dataLength = logbook_readSampleData(StepBackwards, DEPTH_DATA_LENGTH, ReplayDepthData,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ReplayMarkerData);
 
 	/* check if a marker is provided. If not disable marker functionality for the replay block */
 		for(index = 0; index < dataLength; index++)
--- a/Discovery/Src/ostc.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/ostc.c	Sat Nov 15 19:29:44 2025 +0100
@@ -27,8 +27,10 @@
 //////////////////////////////////////////////////////////////////////////////
 
 /* Includes ------------------------------------------------------------------*/
+#include "configuration.h"
 #include "ostc.h"
 #include "stm32f4xx_hal.h"
+#include "cv_heartbeat.h"
 
 #ifndef BOOTLOADER_STANDALONE
 #include "tCCR.h"
@@ -45,6 +47,10 @@
 #endif
 UART_HandleTypeDef UartIR_HUD_Handle;
 
+#ifdef ENABLE_USART_RADIO
+UART_HandleTypeDef UartRadio_Handle;
+#endif
+
 __IO ITStatus UartReady = RESET;
 __IO ITStatus UartReadyHUD = RESET;
 
@@ -54,6 +60,19 @@
 
 /* Private variables with external access via get_xxx() function -------------*/
 static uint8_t	hardwareDisplay = 0;		//< either OSTC4 LCD (=0) or new Screen (=1)
+
+#ifdef ENABLE_PULSE_SENSOR_BT
+static DMA_HandleTypeDef  hdma_uart_BT_rx;
+#endif
+
+#ifdef ENABLE_USART_RADIO
+static DMA_HandleTypeDef  hdma_uart_radio_rx;
+#endif
+
+static uint16_t rxBufRead = 0;
+static uint16_t rxBufWrite = 0;
+static uint8_t rxBufferUart[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow variations in buffer read time */
+
 /* Private function prototypes -----------------------------------------------*/
 
 /* Exported functions --------------------------------------------------------*/
@@ -138,7 +157,10 @@
     SMALLCPU_CSB_GPIO_ENABLE();
     OSCILLOSCOPE_GPIO_ENABLE();
     OSCILLOSCOPE2_GPIO_ENABLE();
-    BLE_UBLOX_DSR_GPIO_ENABLE();
+    if(isNewDisplay())
+    {
+    	BLE_UBLOX_DSR_GPIO_ENABLE();
+    }
 
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_PULLUP;
@@ -232,12 +254,15 @@
     HAL_GPIO_Init(BLE_NENABLE_GPIO_PORT, &GPIO_InitStruct);
     HAL_GPIO_WritePin(BLE_NENABLE_GPIO_PORT,BLE_NENABLE_PIN,GPIO_PIN_RESET);
 
-    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
-    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-    GPIO_InitStruct.Pin = BLE_UBLOX_DSR_PIN;
-    HAL_GPIO_Init(BLE_UBLOX_DSR_GPIO_PORT, &GPIO_InitStruct);
-    HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+    if(isNewDisplay())
+    {
+		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+		GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+		GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+		GPIO_InitStruct.Pin = BLE_UBLOX_DSR_PIN;
+		HAL_GPIO_Init(BLE_UBLOX_DSR_GPIO_PORT, &GPIO_InitStruct);
+		HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+    }
 }
 
 
@@ -248,7 +273,11 @@
     GPIO_InitStruct.Pin = BLE_NENABLE_PIN;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(BLE_NENABLE_GPIO_PORT, &GPIO_InitStruct);
-    HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+
+    if(isNewDisplay())
+    {
+    	HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+    }
 }
 
 
@@ -353,7 +382,7 @@
     UartHandle.Init.StopBits   = UART_STOPBITS_1;
     UartHandle.Init.Parity     = UART_PARITY_NONE;
     UartHandle.Init.Mode       = UART_MODE_TX_RX;
-    HAL_UART_Init(&UartHandle);
+    /* HAL_UART_Init(&UartHandle); moved final init step into BT config function to avoid problems while module power is off */
 
 #ifdef USART_PIEZO
     UartPiezoTxHandle.Instance        = USART_PIEZO;
@@ -378,8 +407,122 @@
 
     HAL_UART_Init(&UartIR_HUD_Handle);
 #endif
+
+#ifdef ENABLE_USART_RADIO
+    UartRadio_Handle.Instance        = USART_RADIO;
+    UartRadio_Handle.Init.BaudRate   = 9600;
+    UartRadio_Handle.Init.WordLength = UART_WORDLENGTH_8B;
+    UartRadio_Handle.Init.StopBits   = UART_STOPBITS_1;
+    UartRadio_Handle.Init.Parity     = UART_PARITY_NONE;
+    UartRadio_Handle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
+    UartRadio_Handle.Init.Mode       = UART_MODE_RX;
+
+    HAL_UART_Init(&UartRadio_Handle);
+#endif
+
 }
 
+#ifdef ENABLE_PULSE_SENSOR_BT
+void MX_UART_BT_Init_DMA()
+{
+
+	__DMA2_CLK_ENABLE();
+	 __HAL_RCC_DMA2_CLK_ENABLE();
+
+	hdma_uart_BT_rx.Instance = DMA2_Stream2;
+	hdma_uart_BT_rx.Init.Channel = DMA_CHANNEL_4;
+	hdma_uart_BT_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+	hdma_uart_BT_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+	hdma_uart_BT_rx.Init.MemInc = DMA_MINC_ENABLE;
+	hdma_uart_BT_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
+	hdma_uart_BT_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+	hdma_uart_BT_rx.Init.Mode = DMA_NORMAL;
+	hdma_uart_BT_rx.Init.Priority = DMA_PRIORITY_LOW;
+	hdma_uart_BT_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+	HAL_DMA_Init(&hdma_uart_BT_rx);
+
+	__HAL_LINKDMA(&UartHandle, hdmarx, hdma_uart_BT_rx);
+
+	HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
+	HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
+}
+#endif
+
+#ifdef ENABLE_USART_RADIO
+void MX_UART_RADIO_Init_DMA()
+{
+
+	__DMA2_CLK_ENABLE();
+	 __HAL_RCC_DMA2_CLK_ENABLE();
+
+	hdma_uart_radio_rx.Instance = DMA2_Stream1;
+	hdma_uart_radio_rx.Init.Channel = DMA_CHANNEL_4;
+	hdma_uart_radio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+	hdma_uart_radio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+	hdma_uart_radio_rx.Init.MemInc = DMA_MINC_ENABLE;
+	hdma_uart_radio_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
+	hdma_uart_radio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+	hdma_uart_radio_rx.Init.Mode = DMA_NORMAL;
+	hdma_uart_radio_rx.Init.Priority = DMA_PRIORITY_LOW;
+	hdma_uart_radio_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+	HAL_DMA_Init(&hdma_uart_radio_rx);
+
+	__HAL_LINKDMA(&UartRadio_Handle, hdmarx, hdma_uart_radio_rx);
+
+	HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
+	HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
+}
+#endif
+
+
+uint8_t UART_getChar()
+{
+	uint8_t retChar = 0;
+
+	if((rxBufRead != rxBufWrite) && (rxBufferUart[rxBufRead] != 0))
+	{
+		retChar = rxBufferUart[rxBufRead];
+		rxBufferUart[rxBufRead++] = 0;
+		if(rxBufRead == CHUNK_SIZE * CHUNKS_PER_BUFFER)
+		{
+			rxBufRead = 0;
+		}
+	}
+	return retChar;
+}
+#ifdef ENABLE_PULSE_SENSOR_BT
+void UART_StartDMARx()
+{
+	HAL_UART_Receive_DMA (&UartHandle, &rxBufferUart[rxBufWrite], CHUNK_SIZE);
+	rxBufWrite += CHUNK_SIZE;
+	if(rxBufWrite >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+	{
+		rxBufWrite = 0;
+	}
+}
+void DMA2_Stream2_IRQHandler(void)
+{
+  HAL_DMA_IRQHandler(&hdma_uart_BT_rx);
+}
+#endif
+
+#ifdef ENABLE_USART_RADIO
+void UART_StartDMARxRadio()
+{
+	HAL_UART_Receive_DMA (&UartRadio_Handle, &rxBufferUart[rxBufWrite], CHUNK_SIZE);
+	rxBufWrite += CHUNK_SIZE;
+	if(rxBufWrite >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+	{
+		rxBufWrite = 0;
+	}
+}
+
+void DMA2_Stream2_IRQHandler(void)
+{
+  HAL_DMA_IRQHandler(&hdma_uart_radio_rx);
+}
+#endif
+
 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
 {
     if(huart == &UartHandle)
@@ -390,7 +533,20 @@
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
     if(huart == &UartHandle)
-        UartReady = SET;
+    {
+#ifdef ENABLE_PULSE_SENSOR_BT
+    	if(cv_heartbeat_getState() != SENSOR_HB_OFFLINE)
+    	{
+    		UART_StartDMARx();
+    	}
+    	else
+    	{
+    		UartReady = SET;
+    	}
+#else
+    	UartReady = SET;
+#endif
+    }
     else
     if(huart == &UartIR_HUD_Handle)
     {
--- a/Discovery/Src/settings.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/settings.c	Sat Nov 15 19:29:44 2025 +0100
@@ -33,6 +33,10 @@
 #include "externLogbookFlash.h" // for SAMPLESTART and SAMPLESTOP
 #include "text_multilanguage.h" // for LANGUAGE_END
 #include "tHome.h" // for CVIEW_END
+#include "tMenu.h"
+#include "tMenuEdit.h"
+#include "tInfo.h"
+#include "tInfoLog.h"
 #include "motion.h"
 #include "t7.h"
 #include "data_central.h"
@@ -42,8 +46,10 @@
 
 SSettings Settings;
 
+SSettings Profile[NUMBER_OF_PROFILES];	/* may be optimized if RAM is getting short. profile copies are only used by profile dialog */
+												/* static structure is used to keep things simple avoiding larger code changes */
 const uint8_t RTErequiredHigh = 3;
-const uint8_t RTErequiredLow = 4;
+const uint8_t RTErequiredLow = 7;
 
 const uint8_t FONTrequiredHigh = 1;
 const uint8_t FONTrequiredLow =	0;
@@ -61,16 +67,16 @@
 const SFirmwareData firmware_FirmwareData __attribute__( (section(".firmware_firmware_data")) ) =
 {
     .versionFirst   = 1,
-    .versionSecond 	= 6,
-    .versionThird   = 9,
+    .versionSecond 	= 7,
+    .versionThird   = 4,
     .versionBeta    = 0,
 
     /* 4 bytes with trailing 0 */
     .signature = "mh",
 
     .release_year = 25,
-    .release_month = 1,
-    .release_day = 18,
+    .release_month = 6,
+    .release_day = 9,
     .release_sub = 0,
 
     /* max 48 with trailing 0 */
@@ -89,7 +95,7 @@
  * There might even be entries with fixed values that have no range
  */
 const SSettings SettingsStandard = {
-    .header = 0xFFFF002C,
+    .header = 0xFFFF002D,
     .warning_blink_dsec = 8 * 2,
     .lastDiveLogId = 0,
     .logFlashNextSampleStartAddress = SAMPLESTART,
@@ -326,7 +332,7 @@
 	.autoSetpoint = 0,
 	.scrubTimerMax_Obsolete = 0,
 	.scrubTimerCur_Obsolete = 0,
-	.scrubTimerMode = SCRUB_TIMER_OFF,
+	.scrubTimerMode = SCRUB_TIMER_MINUTES,
 	.ext_sensor_map[0] = SENSOR_OPTIC,
 	.ext_sensor_map[1] = SENSOR_OPTIC,
 	.ext_sensor_map[2] = SENSOR_OPTIC,
@@ -343,15 +349,48 @@
 	.slowExitTime = 0,
 	.timeZone.hours = 0,
 	.timeZone.minutes = 0,
-	.warningBuzzer = 0
+	.warningBuzzer = 0,
+	.profileName[0] = "STANDARD",
+    .profileName[1] = "OC_TX___",
+    .profileName[2] = "MCCR____",
+    .profileName[3] = "ECCR____",
+	.activeProfile = 0,
 };
 
 /* Private function prototypes -----------------------------------------------*/
 uint8_t checkValue(uint8_t value,uint8_t from, uint8_t to);
 
+/* The profiles are store in a 4k flash block => make sure that size does not violate the size of the flash block (settings * 4) */
+_Static_assert(sizeof(Settings) < 1000, "To much settings to support multiple profiles");
+
+
 /* Functions -----------------------------------------------------------------*/
 
 
+uint16_t settingsGetSize()
+{
+	return sizeof (Settings);
+}
+
+
+void setFlipDisplay(uint8_t flipDisplay)
+{
+    bool settingChanged = flipDisplay != Settings.FlipDisplay;
+    Settings.FlipDisplay = flipDisplay;
+    if (settingChanged) {
+        // reinit all views
+        tHome_init();
+        tI_init();
+        tM_init();
+        tMenuEdit_init();
+        tInfoLog_init();
+        tM_build_pages();
+        GFX_build_logo_frame();
+        GFX_build_hw_background_frame();
+    }
+}
+
+
 //  ===============================================================================
 //	set_new_settings_missing_in_ext_flash
 /// @brief	Add all the new setting variables of this version
@@ -361,34 +400,49 @@
 ///
 //  ===============================================================================
 SSettings* pSettings;
-void set_new_settings_missing_in_ext_flash(void)
+void set_new_settings_missing_in_ext_flash(uint8_t whichSettings)
 {
 	uint32_t tmp = 0;
+	pSettings = settingsGetPointer();
 
+	switch(whichSettings)
+	{
+	    		default:
+	    		case EF_SETTINGS:
+	    			break;
+	    		case EF_PROFILE0:	pSettings = profileGetPointer(0);
+	    			break;
+	    		case EF_PROFILE1:	pSettings = profileGetPointer(1);
+	    			break;
+	    		case EF_PROFILE2:	pSettings = profileGetPointer(2);
+	    			break;
+	    		case EF_PROFILE3:	pSettings = profileGetPointer(3);
+	    			break;
+	}
     // never delete this part setting the serial
     if(hardwareDataGetPointer()->secondarySerial != 0xFFFF)
     {
-        settingsGetPointer()->serialHigh = (hardwareDataGetPointer()->secondarySerial / 256);
-        settingsGetPointer()->serialLow  = (hardwareDataGetPointer()->secondarySerial & 0xFF);
+    	pSettings->serialHigh = (hardwareDataGetPointer()->secondarySerial / 256);
+    	pSettings->serialLow  = (hardwareDataGetPointer()->secondarySerial & 0xFF);
     }
     else
     if(hardwareDataGetPointer()->primarySerial != 0xFFFF)
     {
-        settingsGetPointer()->serialHigh = (hardwareDataGetPointer()->primarySerial / 256);
-        settingsGetPointer()->serialLow  = (hardwareDataGetPointer()->primarySerial & 0xFF);
+    	pSettings->serialHigh = (hardwareDataGetPointer()->primarySerial / 256);
+    	pSettings->serialLow  = (hardwareDataGetPointer()->primarySerial & 0xFF);
     }
     else
     {
-        settingsGetPointer()->serialHigh = 0;
-        settingsGetPointer()->serialLow  = 0;
+    	pSettings->serialHigh = 0;
+    	pSettings->serialLow  = 0;
     }
 
-    settingsGetPointer()->firmwareVersion[0] = firmware_FirmwareData.versionFirst;
-    settingsGetPointer()->firmwareVersion[1] = firmware_FirmwareData.versionSecond;
-    settingsGetPointer()->firmwareVersion[2] = firmware_FirmwareData.versionThird;
-    settingsGetPointer()->firmwareVersion[3] = firmware_FirmwareData.versionBeta;
+    pSettings->firmwareVersion[0] = firmware_FirmwareData.versionFirst;
+    pSettings->firmwareVersion[1] = firmware_FirmwareData.versionSecond;
+    pSettings->firmwareVersion[2] = firmware_FirmwareData.versionThird;
+    pSettings->firmwareVersion[3] = firmware_FirmwareData.versionBeta;
 
-    pSettings = settingsGetPointer();
+
     const SSettings* pStandard = settingsGetPointerStandard();
 
     /* Pointing to the old header data => set new data depending on what had been added since last version */
@@ -442,7 +496,7 @@
         pSettings->gasConsumption_deco_l_min        = pStandard->gasConsumption_deco_l_min;
         // no break
     case 0xFFFF000C:
-        memcpy(pSettings->customtext, " hwOS 4\n\r" " welcome\n\r", 60);
+        strncpy(pSettings->customtext, " hwOS 4\n\r" " welcome\n\r", sizeof(pSettings->customtext));
         // no break
     case 0xFFFF000D: // nothing to do from 0xFFFF000D to 0xFFFF000E, just about header :-)
     case 0xFFFF000E:
@@ -476,10 +530,11 @@
         pSettings->FactoryButtonBalance[2]          = pStandard->FactoryButtonBalance[2];
         // no break
     case 0xFFFF0017:
-    	pSettings->FlipDisplay = 0;
-    	// no break
+        setFlipDisplay(0);
+        // no break
     case 0xFFFF0018:
     	pSettings->cv_configuration = 0xFFFFFFFF;
+        pSettings->cv_configuration &= ~(1 << CVIEW_sensors | 1 << CVIEW_sensors_mV | 1 << CVIEW_Timer);
     	// no break
     case 0xFFFF0019:
     	pSettings->MotionDetection = MOTION_DETECT_OFF;
@@ -487,13 +542,13 @@
     case 0xFFFF001A:
     	/* deactivate new views => to be activated by customer */
         pSettings->cv_config_BigScreen = 0xFFFFFFFF;
-        pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_Navigation + LEGACY_T3_START_ID_PRE_TIMER);
-        pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_DepthData + LEGACY_T3_START_ID_PRE_TIMER);
+        pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_Navigation + LEGACY_T3_START_ID_PRE_TIMER);
+        pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_DepthData + LEGACY_T3_START_ID_PRE_TIMER);
         // no break
     case 0xFFFF001B:
     	pSettings->compassInertia = 0; 			/* no inertia */
     	pSettings->tX_customViewPrimaryBF = CVIEW_T3_Decostop;
-    	pSettings->cv_config_BigScreen &= pSettings->cv_configuration ^= 1 << (CVIEW_T3_DecoTTS + LEGACY_T3_START_ID_PRE_TIMER);
+        pSettings->cv_config_BigScreen &= 1 << (CVIEW_T3_DecoTTS + LEGACY_T3_START_ID_PRE_TIMER);
         // no break
     case 0xFFFF001C:
     	pSettings->viewPortMode = 0;
@@ -512,7 +567,7 @@
     	pSettings->autoSetpoint = 0;
     	pSettings->scrubTimerMax_Obsolete = 0;
     	pSettings->scrubTimerCur_Obsolete = 0;
-    	pSettings->scrubTimerMode = SCRUB_TIMER_OFF;
+        pSettings->scrubTimerMode = SCRUB_TIMER_MINUTES;
     	// no break
     case 0xFFFF001F:
     	pSettings->pscr_lung_ratio = 10;
@@ -525,7 +580,7 @@
     	pSettings->ext_uart_protocol = 0;
     	// no break;
     case 0xFFFF0022:
-    	pSettings->scubberActiveId = 0;
+        pSettings->scrubberActiveId = 0;
     	pSettings->scrubberData[0].TimerCur = pSettings->scrubTimerCur_Obsolete;
     	pSettings->scrubberData[0].TimerMax = pSettings->scrubTimerMax_Obsolete;
     	pSettings->scrubberData[0].lastDive.WeekDay = 0;
@@ -590,15 +645,23 @@
     case 0xFFFF0028:
     	// no break;
     case 0xFFFF0029:
-    	Settings.cvAutofocus = 0;
+    	pSettings->cvAutofocus = 0;
     	// no break;
     case 0xFFFF002A:
-    	Settings.slowExitTime = 0;
+    	pSettings->slowExitTime = 0;
     	// no break;
     case 0xFFFF002B:
-    	Settings.timeZone.hours = 0;
-    	Settings.timeZone.minutes = 0;
-    	Settings.warningBuzzer = 0;
+    	pSettings->timeZone.hours = 0;
+    	pSettings->timeZone.minutes = 0;
+    	pSettings->warningBuzzer = 0;
+    	// no break;
+    case 0xFFFF002C:
+    	sprintf((char*)pSettings->profileName[0],"STANDARD");
+    	sprintf((char*)pSettings->profileName[1],"OC_TX___");
+    	sprintf((char*)pSettings->profileName[2],"MCCR____");
+    	sprintf((char*)pSettings->profileName[3],"ECCR____");
+    	pSettings->activeProfile = 0;
+
     	// no break;
     default:
         pSettings->header = pStandard->header;
@@ -714,7 +777,7 @@
 	}
 }
 
-uint8_t check_and_correct_settings(void)
+uint8_t check_and_correct_settings(uint8_t whichSettings)
 {
     uint32_t corrections = 0;
     uint8_t firstGasFoundOC = 0;
@@ -725,114 +788,133 @@
     settingsWarning = 0; /* reset warning indicator */
     SettingsStatus.FirstCorrection = 0xFF;
 
+	pSettings = settingsGetPointer();
+
+	switch(whichSettings)
+	{
+	    		default:
+	    		case EF_SETTINGS:
+	    			break;
+	    		case EF_PROFILE0:	pSettings = profileGetPointer(0);
+	    			break;
+	    		case EF_PROFILE1:	pSettings = profileGetPointer(1);
+	    			break;
+	    		case EF_PROFILE2:	pSettings = profileGetPointer(2);
+	    			break;
+	    		case EF_PROFILE3:	pSettings = profileGetPointer(3);
+	    			break;
+	}
+
+
+
 /*	uint32_t header;
  */
 
 /*	uint8_t warning_blink_dsec; 1/10 seconds
  */
-        if((Settings.warning_blink_dsec < 1) || (Settings.warning_blink_dsec > 100))
+        if((pSettings->warning_blink_dsec < 1) || (pSettings->warning_blink_dsec > 100))
         {
-            Settings.warning_blink_dsec = SettingsStandard.warning_blink_dsec;
+            pSettings->warning_blink_dsec = SettingsStandard.warning_blink_dsec;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        parameterId++;
+        parameterId++; /* 1 */
 /*	uint8_t lastDiveLogId;
  */
 
 /*	uint32_t logFlashNextSampleStartAddress;
  */
-        if((Settings.logFlashNextSampleStartAddress < SAMPLESTART) || (Settings.logFlashNextSampleStartAddress > SAMPLESTOP))
+        if((pSettings->logFlashNextSampleStartAddress < SAMPLESTART) || (pSettings->logFlashNextSampleStartAddress > SAMPLESTOP))
         {
-            Settings.logFlashNextSampleStartAddress = SAMPLESTART;
+            pSettings->logFlashNextSampleStartAddress = SAMPLESTART;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        parameterId++;
+        parameterId++; /* 2 */
 
 /*	uint8_t dive_mode; has to before the gases
  */
-    if(	(Settings.dive_mode != DIVEMODE_OC) 		&&
-            (Settings.dive_mode != DIVEMODE_CCR)  	&&
-            (Settings.dive_mode != DIVEMODE_Gauge)	&&
-            (Settings.dive_mode != DIVEMODE_Apnea)	&&
-			(Settings.dive_mode != DIVEMODE_PSCR))
+    if(	(pSettings->dive_mode != DIVEMODE_OC) 		&&
+            (pSettings->dive_mode != DIVEMODE_CCR)  	&&
+            (pSettings->dive_mode != DIVEMODE_Gauge)	&&
+            (pSettings->dive_mode != DIVEMODE_Apnea)	&&
+			(pSettings->dive_mode != DIVEMODE_PSCR))
     {
-        Settings.dive_mode = DIVEMODE_OC;
+        pSettings->dive_mode = DIVEMODE_OC;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++;/* 3 */
 
 /*	SGasLine gas[1 + (2*NUM_GASES)];
  */
     for(int i=1; i<=2*NUM_GASES;i++)
     {
-        if(Settings.gas[i].oxygen_percentage < 4)
+        if(pSettings->gas[i].oxygen_percentage < 4)
         {
-            Settings.gas[i].oxygen_percentage = 4;
+            pSettings->gas[i].oxygen_percentage = 4;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.gas[i].oxygen_percentage > 100)
+        if(pSettings->gas[i].oxygen_percentage > 100)
         {
-            Settings.gas[i].oxygen_percentage = 100;
+            pSettings->gas[i].oxygen_percentage = 100;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if((Settings.gas[i].oxygen_percentage + Settings.gas[i].helium_percentage) > 100)
+        if((pSettings->gas[i].oxygen_percentage + pSettings->gas[i].helium_percentage) > 100)
         {
-            Settings.gas[i].helium_percentage = 100 - Settings.gas[i].oxygen_percentage;
+            pSettings->gas[i].helium_percentage = 100 - pSettings->gas[i].oxygen_percentage;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.gas[i].note.ub.deco)
+        if(pSettings->gas[i].note.ub.deco)
         {
-            if(Settings.gas[i].note.ub.active != 1)
+            if(pSettings->gas[i].note.ub.active != 1)
             {
-                Settings.gas[i].note.ub.active = 1;
+                pSettings->gas[i].note.ub.active = 1;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
-            if(Settings.gas[i].note.ub.travel == 1)
+            if(pSettings->gas[i].note.ub.travel == 1)
             {
-                Settings.gas[i].note.ub.travel = 0;
+                pSettings->gas[i].note.ub.travel = 0;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
         }
-        if(Settings.gas[i].note.ub.travel)
+        if(pSettings->gas[i].note.ub.travel)
         {
-            if(Settings.gas[i].note.ub.active != 1)
+            if(pSettings->gas[i].note.ub.active != 1)
             {
-                Settings.gas[i].note.ub.active = 1;
+                pSettings->gas[i].note.ub.active = 1;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
-            if(Settings.gas[i].note.ub.deco == 1)
+            if(pSettings->gas[i].note.ub.deco == 1)
             {
-                Settings.gas[i].note.ub.deco = 0;
+                pSettings->gas[i].note.ub.deco = 0;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
         }
-        if(Settings.gas[i].note.ub.first)
+        if(pSettings->gas[i].note.ub.first)
         {
-            if(Settings.gas[i].note.ub.active != 1)
+            if(pSettings->gas[i].note.ub.active != 1)
             {
-                Settings.gas[i].note.ub.active = 1;
+                pSettings->gas[i].note.ub.active = 1;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
-            if(Settings.gas[i].note.ub.travel == 1)
+            if(pSettings->gas[i].note.ub.travel == 1)
             {
-                Settings.gas[i].note.ub.travel = 0;
+                pSettings->gas[i].note.ub.travel = 0;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
-            if(Settings.gas[i].note.ub.deco == 1)
+            if(pSettings->gas[i].note.ub.deco == 1)
             {
-                Settings.gas[i].note.ub.deco = 0;
+                pSettings->gas[i].note.ub.deco = 0;
                 corrections++;
                 setFirstCorrection(parameterId);
             }
@@ -842,480 +924,480 @@
             if((i>NUM_GASES) && (!firstGasFoundCCR))
                 firstGasFoundCCR = 1;
             else
-                Settings.gas[i].note.ub.first = 0;
+                pSettings->gas[i].note.ub.first = 0;
         }
-        if(Settings.gas[i].bottle_size_liter > 40)
+        if(pSettings->gas[i].bottle_size_liter > 40)
         {
-            Settings.gas[i].bottle_size_liter = 40;
+            pSettings->gas[i].bottle_size_liter = 40;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.gas[i].depth_meter > 250)
+        if(pSettings->gas[i].depth_meter > 250)
         {
-            Settings.gas[i].depth_meter = 250;
+            pSettings->gas[i].depth_meter = 250;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.gas[i].depth_meter_travel > 250)
+        if(pSettings->gas[i].depth_meter_travel > 250)
         {
-            Settings.gas[i].depth_meter_travel = 250;
+            pSettings->gas[i].depth_meter_travel = 250;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        /*if(Settings.gas[i].note.ub.senderCode)
+        /*if(pSettings->gas[i].note.ub.senderCode)
         {
         }
-        if(Settings.gas[i].bottle_wireless_id)
+        if(pSettings->gas[i].bottle_wireless_id)
         {
         }
         */
     } // for(int i=1; i<=2*NUM_GASES;i++)
-    parameterId++;
+    parameterId++; /* 4 */
     if(!firstGasFoundOC)
     {
-        Settings.gas[1].note.ub.active = 1;
-        Settings.gas[1].note.ub.first = 1;
-        Settings.gas[1].note.ub.travel = 0;
-        Settings.gas[1].note.ub.deco = 0;
+        pSettings->gas[1].note.ub.active = 1;
+        pSettings->gas[1].note.ub.first = 1;
+        pSettings->gas[1].note.ub.travel = 0;
+        pSettings->gas[1].note.ub.deco = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 5 */
     if(!firstGasFoundCCR)
     {
-        Settings.gas[1 + NUM_GASES].note.ub.active = 1;
-        Settings.gas[1 + NUM_GASES].note.ub.first = 1;
-        Settings.gas[1 + NUM_GASES].note.ub.travel = 0;
-        Settings.gas[1 + NUM_GASES].note.ub.deco = 0;
+        pSettings->gas[1 + NUM_GASES].note.ub.active = 1;
+        pSettings->gas[1 + NUM_GASES].note.ub.first = 1;
+        pSettings->gas[1 + NUM_GASES].note.ub.travel = 0;
+        pSettings->gas[1 + NUM_GASES].note.ub.deco = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 6 */
 /*	SSetpointLine setpoint[1 + NUM_GASES];
  */
     for(int i=1; i<=NUM_GASES;i++)
     {
-        if(Settings.setpoint[i].setpoint_cbar < MIN_PPO2_SP_CBAR)
+        if(pSettings->setpoint[i].setpoint_cbar < MIN_PPO2_SP_CBAR)
         {
-            Settings.setpoint[i].setpoint_cbar = MIN_PPO2_SP_CBAR;
+            pSettings->setpoint[i].setpoint_cbar = MIN_PPO2_SP_CBAR;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.setpoint[i].setpoint_cbar > 160)
+        if(pSettings->setpoint[i].setpoint_cbar > 160)
         {
-            Settings.setpoint[i].setpoint_cbar = 160;
+            pSettings->setpoint[i].setpoint_cbar = 160;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        if(Settings.setpoint[i].depth_meter > 250)
+        if(pSettings->setpoint[i].depth_meter > 250)
         {
-            Settings.setpoint[i].depth_meter = 250;
+            pSettings->setpoint[i].depth_meter = 250;
             corrections++;
             setFirstCorrection(parameterId);
         }
     }	// for(int i=1; i<=NUM_GASES;i++)
-    parameterId++;
+    parameterId++; /* 7 */
     if (checkAndFixSetpointSettings()) {
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 8 */
 /*	uint8_t CCR_Mode;
  */
-    if(	(Settings.CCR_Mode != CCRMODE_Sensors) &&
-    		(Settings.CCR_Mode != CCRMODE_Simulation) &&
-            (Settings.CCR_Mode != CCRMODE_FixedSetpoint))
+    if(	(pSettings->CCR_Mode != CCRMODE_Sensors) &&
+    		(pSettings->CCR_Mode != CCRMODE_Simulation) &&
+            (pSettings->CCR_Mode != CCRMODE_FixedSetpoint))
     {
-        Settings.CCR_Mode = CCRMODE_FixedSetpoint;
+        pSettings->CCR_Mode = CCRMODE_FixedSetpoint;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 9 */
 /*	split2x4_Type deco_type;
  */
-    if(	(Settings.deco_type.ub.standard != GF_MODE) &&
-            (Settings.deco_type.ub.standard != VPM_MODE))
+    if(	(pSettings->deco_type.ub.standard != GF_MODE) &&
+            (pSettings->deco_type.ub.standard != VPM_MODE))
     {
-        Settings.deco_type.ub.standard = VPM_MODE;
+        pSettings->deco_type.ub.standard = VPM_MODE;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.deco_type.ub.alternative != GF_MODE)
+    parameterId++; /* 10 */
+    if(pSettings->deco_type.ub.alternative != GF_MODE)
     {
-        Settings.deco_type.ub.alternative = GF_MODE;
+        pSettings->deco_type.ub.alternative = GF_MODE;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 11 */
 /*	uint8_t ppO2_max_deco;
  */
-    if(Settings.ppO2_max_deco > 190)
+    if(pSettings->ppO2_max_deco > 190)
     {
-        Settings.ppO2_max_deco = 190;
+        pSettings->ppO2_max_deco = 190;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.ppO2_max_deco < 100)
+    parameterId++; /* 12 */
+    if(pSettings->ppO2_max_deco < 100)
     {
-        Settings.ppO2_max_deco = 100;
+        pSettings->ppO2_max_deco = 100;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 13 */
 
 /*	uint8_t ppO2_max_std;
  */
-    if(Settings.ppO2_max_std > 190)
+    if(pSettings->ppO2_max_std > 190)
     {
-        Settings.ppO2_max_std = 190;
+        pSettings->ppO2_max_std = 190;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.ppO2_max_std < 100)
+    parameterId++; /* 14 */
+    if(pSettings->ppO2_max_std < 100)
     {
-        Settings.ppO2_max_std = 100;
+        pSettings->ppO2_max_std = 100;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 15 */
 /*	uint8_t ppO2_min;
  */
-    if(Settings.ppO2_min != 15)
+    if(pSettings->ppO2_min != 15)
     {
-        Settings.ppO2_min = 15;
+        pSettings->ppO2_min = 15;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 16 */
 /*	uint8_t CNS_max;
  */
-    if(Settings.CNS_max != 90)
+    if(pSettings->CNS_max != 90)
     {
-        Settings.CNS_max = 90;
+        pSettings->CNS_max = 90;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 17 */
 /*  uint8_t ascent_MeterPerMinute_max;
  */
-    if(Settings.ascent_MeterPerMinute_max != 30)
+    if(pSettings->ascent_MeterPerMinute_max != 30)
     {
-        Settings.ascent_MeterPerMinute_max = 30;
+        pSettings->ascent_MeterPerMinute_max = 30;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 18 */
 /*	uint8_t ascent_MeterPerMinute_showGraph;
  */
-    if(Settings.ascent_MeterPerMinute_showGraph != 30)
+    if(pSettings->ascent_MeterPerMinute_showGraph != 30)
     {
-        Settings.ascent_MeterPerMinute_showGraph = 30;
+        pSettings->ascent_MeterPerMinute_showGraph = 30;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 19 */
 /*	uint8_t future_TTS;
  */
-    if(Settings.future_TTS > 15)
+    if(pSettings->future_TTS > 15)
     {
-        Settings.future_TTS = 15;
+        pSettings->future_TTS = 15;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 20 */
 /*	uint8_t GF_high;
  */
-    if(Settings.GF_high > 99)
+    if(pSettings->GF_high > 99)
     {
-        Settings.GF_high = 99;
+        pSettings->GF_high = 99;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.GF_high < 45)
+    parameterId++; /* 21 */
+    if(pSettings->GF_high < 45)
     {
-        Settings.GF_high = 45;
+        pSettings->GF_high = 45;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 22 */
 /*	uint8_t GF_low;
  */
-    if(Settings.GF_low > 99)
+    if(pSettings->GF_low > 99)
     {
-        Settings.GF_low = 99;
+        pSettings->GF_low = 99;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.GF_low < 10)
+    parameterId++; /* 23 */
+    if(pSettings->GF_low < 10)
     {
-        Settings.GF_low = 10;
+        pSettings->GF_low = 10;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.GF_low > Settings.GF_high)
+    parameterId++; /* 24 */
+    if(pSettings->GF_low > pSettings->GF_high)
     {
-        Settings.GF_low = Settings.GF_high;
+        pSettings->GF_low = pSettings->GF_high;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 25 */
 /*	uint8_t aGF_high;
  */
-    if(Settings.aGF_high > 99)
+    if(pSettings->aGF_high > 99)
     {
-        Settings.aGF_high = 99;
+        pSettings->aGF_high = 99;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.aGF_high < 45)
+    parameterId++; /* 26 */
+    if(pSettings->aGF_high < 45)
     {
-        Settings.aGF_high = 45;
+        pSettings->aGF_high = 45;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 27 */
 /*	uint8_t aGF_low;
  */
-    if(Settings.aGF_low > 99)
+    if(pSettings->aGF_low > 99)
     {
-        Settings.aGF_low = 99;
+        pSettings->aGF_low = 99;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.aGF_low < 10)
+    parameterId++; /* 28 */
+    if(pSettings->aGF_low < 10)
     {
-        Settings.aGF_low = 10;
+        pSettings->aGF_low = 10;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.aGF_low > Settings.aGF_high)
+    parameterId++; /* 29 */
+    if(pSettings->aGF_low > pSettings->aGF_high)
     {
-        Settings.aGF_low = Settings.aGF_high;
+        pSettings->aGF_low = pSettings->aGF_high;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 30 */
 /*	split2x4_Type VPM_conservatism;
  */
-    if(Settings.VPM_conservatism.ub.standard > 5)
+    if(pSettings->VPM_conservatism.ub.standard > 5)
     {
-        Settings.VPM_conservatism.ub.standard = 5;
+        pSettings->VPM_conservatism.ub.standard = 5;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.VPM_conservatism.ub.alternative > 5)
+    parameterId++; /* 31 */
+    if(pSettings->VPM_conservatism.ub.alternative > 5)
     {
-        Settings.VPM_conservatism.ub.alternative = 5;
+        pSettings->VPM_conservatism.ub.alternative = 5;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 32 */
 /*	uint8_t safetystopDuration;
  */
-    if(Settings.safetystopDuration > 5)
+    if(pSettings->safetystopDuration > 5)
     {
-        Settings.safetystopDuration = 5;
+        pSettings->safetystopDuration = 5;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 33 */
 /*	uint8_t AtemMinutenVolumenLiter;
  */
-    if(Settings.AtemMinutenVolumenLiter != 25)
+    if(pSettings->AtemMinutenVolumenLiter != 25)
     {
-        Settings.AtemMinutenVolumenLiter = 25;
+        pSettings->AtemMinutenVolumenLiter = 25;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 34 */
 /*	uint8_t ReserveFractionDenominator;
  */
-    if(Settings.ReserveFractionDenominator != 4)
+    if(pSettings->ReserveFractionDenominator != 4)
     {
-        Settings.ReserveFractionDenominator = 4;
+        pSettings->ReserveFractionDenominator = 4;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 35 */
 /*	uint8_t salinity;
  */
-    if(Settings.salinity > 4)
+    if(pSettings->salinity > 4)
     {
-        Settings.salinity = 4;
+        pSettings->salinity = 4;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 36 */
 /*	uint8_t last_stop_depth_meter;
  */
-    if(Settings.last_stop_depth_meter > 9)
+    if(pSettings->last_stop_depth_meter > 9)
     {
-        Settings.last_stop_depth_meter = 9;
+        pSettings->last_stop_depth_meter = 9;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.last_stop_depth_meter < 3)
+    parameterId++; /* 37 */
+    if(pSettings->last_stop_depth_meter < 3)
     {
-        Settings.last_stop_depth_meter = 3;
+        pSettings->last_stop_depth_meter = 3;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 38 */
 /*	uint8_t stop_increment_depth_meter;
  */
-    if(Settings.stop_increment_depth_meter != 3)
+    if(pSettings->stop_increment_depth_meter != 3)
     {
-        Settings.stop_increment_depth_meter = 3;
+        pSettings->stop_increment_depth_meter = 3;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 39 */
 /*	uint8_t brightness;
  */
-    if(Settings.brightness > 4)
+    if(pSettings->brightness > 4)
     {
-        Settings.brightness = 4;
+        pSettings->brightness = 4;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 40 */
 /*	uint8_t date_format;
  */
-    if(	(Settings.date_format != DDMMYY) &&
-            (Settings.date_format != MMDDYY) &&
-            (Settings.date_format != YYMMDD))
+    if(	(pSettings->date_format != DDMMYY) &&
+            (pSettings->date_format != MMDDYY) &&
+            (pSettings->date_format != YYMMDD))
     {
-        Settings.date_format = DDMMYY;
+        pSettings->date_format = DDMMYY;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 41 */
 /*	uint8_t selected_language;
  */
-    if(Settings.selected_language >= LANGUAGE_END)
+    if(pSettings->selected_language >= LANGUAGE_END)
     {
-        Settings.selected_language = LANGUAGE_English;
+        pSettings->selected_language = LANGUAGE_English;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 42 */
 /*	char customtext[60];
  */
-    if(Settings.customtext[59] != 0)
+    if(pSettings->customtext[59] != 0)
     {
-        Settings.customtext[59] = 0;
+        pSettings->customtext[59] = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 43 */
 /*	uint16_t timeoutSurfacemode;
  */
-    if(	(Settings.timeoutSurfacemode != 20) &&  // Quick Sleep Option
-            (Settings.timeoutSurfacemode != 120))
+    if(	(pSettings->timeoutSurfacemode != 20) &&  // Quick Sleep Option
+            (pSettings->timeoutSurfacemode != 120))
     {
-        Settings.timeoutSurfacemode = 120;
+        pSettings->timeoutSurfacemode = 120;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 44 */
 /*	uint8_t timeoutMenuSurface;
  */
-    if(Settings.timeoutMenuSurface != 120)
+    if(pSettings->timeoutMenuSurface != 120)
     {
-        Settings.timeoutMenuSurface = 120;
+        pSettings->timeoutMenuSurface = 120;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 45 */
 /*	uint8_t timeoutMenuDive;
  */
-    if(Settings.timeoutMenuDive != 120)
+    if(pSettings->timeoutMenuDive != 120)
     {
-        Settings.timeoutMenuDive = 120;
+        pSettings->timeoutMenuDive = 120;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 46 */
 /*	uint8_t timeoutMenuEdit;
  */
-    if(Settings.timeoutMenuEdit != 120)
+    if(pSettings->timeoutMenuEdit != 120)
     {
-        Settings.timeoutMenuEdit = 120;
+        pSettings->timeoutMenuEdit = 120;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 47 */
 /*	uint8_t timeoutInfo;
  */
-    if(Settings.timeoutInfo != 120)
+    if(pSettings->timeoutInfo != 120)
     {
-        Settings.timeoutInfo = 120;
+        pSettings->timeoutInfo = 120;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 48 */
 /*	uint8_t timeoutInfoCompass;
  */
-    if(Settings.timeoutInfoCompass != 60)
+    if(pSettings->timeoutInfoCompass != 60)
     {
-        Settings.timeoutInfoCompass = 60;
+        pSettings->timeoutInfoCompass = 60;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 49 */
 /*	uint8_t design;
  */
-    if(Settings.design != 7)
+    if(pSettings->design != 7)
     {
-        Settings.design = 7;
+        pSettings->design = 7;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 50 */
 /*	uint16_t timeoutDiveReachedZeroDepth;
  */
-    if(Settings.timeoutDiveReachedZeroDepth != 300)
+    if(pSettings->timeoutDiveReachedZeroDepth != 300)
     {
-        Settings.timeoutDiveReachedZeroDepth = 300;
+        pSettings->timeoutDiveReachedZeroDepth = 300;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 51 */
 /*	uint16_t divetimeToCreateLogbook;
  */
-    if(Settings.divetimeToCreateLogbook != 60)
+    if(pSettings->divetimeToCreateLogbook != 60)
     {
-        Settings.divetimeToCreateLogbook = 60;
+        pSettings->divetimeToCreateLogbook = 60;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.slowExitTime > 9)
+    parameterId++; /* 52 */
+    if(pSettings->slowExitTime > 9)
     {
-        Settings.divetimeToCreateLogbook = 0;
+        pSettings->divetimeToCreateLogbook = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 53 */
 
-    if(Settings.warningBuzzer > 1)
+    if(pSettings->warningBuzzer > 1)
     {
-    	Settings.warningBuzzer = 0;
+    	pSettings->warningBuzzer = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 54 */
 
 
 /*	uint8_t serialHigh;
@@ -1343,533 +1425,532 @@
  */
 
 #ifdef HAVE_DEBUG_VIEW
-    if(Settings.showDebugInfo > 1)
+    if(pSettings->showDebugInfo > 1)
     {
-        Settings.showDebugInfo = 0;
+        pSettings->showDebugInfo = 0;
         corrections++;
     }
 #else
-    Settings.showDebugInfo = 0;
+    pSettings->showDebugInfo = 0;
 #endif
 
 /*	uint8_t ButtonResponsiveness[4];
  */
     // Base value, index 3
-    if(Settings.ButtonResponsiveness[3] < MIN_BUTTONRESPONSIVENESS_GUI)
+    if(pSettings->ButtonResponsiveness[3] < MIN_BUTTONRESPONSIVENESS_GUI)
     {
-        Settings.ButtonResponsiveness[3] = MIN_BUTTONRESPONSIVENESS_GUI;
+        pSettings->ButtonResponsiveness[3] = MIN_BUTTONRESPONSIVENESS_GUI;
         corrections++;
         setFirstCorrection(parameterId);
     }
     else
-    if(Settings.ButtonResponsiveness[3] > MAX_BUTTONRESPONSIVENESS_GUI)
+    if(pSettings->ButtonResponsiveness[3] > MAX_BUTTONRESPONSIVENESS_GUI)
     {
-        Settings.ButtonResponsiveness[3] = MAX_BUTTONRESPONSIVENESS_GUI;
+        pSettings->ButtonResponsiveness[3] = MAX_BUTTONRESPONSIVENESS_GUI;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 55 */
     // flex values 0, 1, 2
     for(int i=0; i<3;i++)
     {
-        if(Settings.ButtonResponsiveness[i] < MIN_BUTTONRESPONSIVENESS) // 50-10  //Fix for broken buttons. :)
+        if(pSettings->ButtonResponsiveness[i] < MIN_BUTTONRESPONSIVENESS) // 50-10  //Fix for broken buttons. :)
         {
-            Settings.ButtonResponsiveness[i] = MIN_BUTTONRESPONSIVENESS;
+            pSettings->ButtonResponsiveness[i] = MIN_BUTTONRESPONSIVENESS;
             corrections++;
             setFirstCorrection(parameterId);
         }
         else
-        if(Settings.ButtonResponsiveness[i] > MAX_BUTTONRESPONSIVENESS) // 110+20
+        if(pSettings->ButtonResponsiveness[i] > MAX_BUTTONRESPONSIVENESS) // 110+20
         {
-            Settings.ButtonResponsiveness[i] = MAX_BUTTONRESPONSIVENESS;
+            pSettings->ButtonResponsiveness[i] = MAX_BUTTONRESPONSIVENESS;
             corrections++;
             setFirstCorrection(parameterId);
         }
     }
-    parameterId++;
+    parameterId++; /* 56 */
 /*	uint8_t buttonBalance[3];
  */
     for(int i=0; i<3;i++)
     {
-        if(Settings.buttonBalance[i] < 2) // 2 = -10
+        if(pSettings->buttonBalance[i] < 2) // 2 = -10
         {
-            Settings.buttonBalance[i] = 2;
+            pSettings->buttonBalance[i] = 2;
             corrections++;
             setFirstCorrection(parameterId);
         }
         else
-        if(Settings.buttonBalance[i] > 5) // 3 = 0, 4 = +10, 5 = +20
+        if(pSettings->buttonBalance[i] > 5) // 3 = 0, 4 = +10, 5 = +20
         {
-            Settings.buttonBalance[i] = 5;
+            pSettings->buttonBalance[i] = 5;
             corrections++;
             setFirstCorrection(parameterId);
         }
     }
-    parameterId++;
+    parameterId++; /* 57 */
 /*	uint8_t nonMetricalSystem;
  */
-    if(Settings.nonMetricalSystem > 1)
+    if(pSettings->nonMetricalSystem > 1)
     {
-        Settings.nonMetricalSystem = 1;
+        pSettings->nonMetricalSystem = 1;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 58 */
 /*	uint8_t fallbackToFixedSetpoint;
  */
-    if(Settings.fallbackToFixedSetpoint > 1)
+    if(pSettings->fallbackToFixedSetpoint > 1)
     {
-        Settings.fallbackToFixedSetpoint = 1;
+        pSettings->fallbackToFixedSetpoint = 1;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 59 */
 /*	uint8_t bluetoothActive;
  */
-    if(Settings.bluetoothActive > 1)
+    if(pSettings->bluetoothActive > 1)
     {
-        Settings.bluetoothActive = 1;
+        pSettings->bluetoothActive = 1;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 60 */
 /*	uint8_t safetystopDepth;
  */
-    if(Settings.safetystopDepth > 6)
+    if(pSettings->safetystopDepth > 6)
     {
-        Settings.safetystopDepth = 6;
+        pSettings->safetystopDepth = 6;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.safetystopDepth < 3)
+    parameterId++; /* 61 */
+    if(pSettings->safetystopDepth < 3)
     {
-        Settings.safetystopDepth = 3;
+        pSettings->safetystopDepth = 3;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 62 */
 /*	uint32_t updateSettingsAllowedFromHeader;
  */
 
 /*	uint8_t ppo2sensors_deactivated;
  */
-    if(Settings.ppo2sensors_deactivated > (1+2+4))
+    if(pSettings->ppo2sensors_deactivated > (1+2+4))
     {
-        Settings.ppo2sensors_deactivated = 0;
+        pSettings->ppo2sensors_deactivated = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 63 */
 /*	uint8_t tX_colorscheme;
  */
-    if(Settings.tX_colorscheme > 3)
+    if(pSettings->tX_colorscheme > 3)
     {
-        Settings.tX_colorscheme = 0;
+        pSettings->tX_colorscheme = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 64 */
 /*	uint8_t tX_userselectedLeftLowerCornerPrimary;
  */
-    if(Settings.tX_userselectedLeftLowerCornerPrimary >= LLC_END)
+    if(pSettings->tX_userselectedLeftLowerCornerPrimary >= LLC_END)
     {
-        Settings.tX_userselectedLeftLowerCornerPrimary = LLC_Temperature;
+        pSettings->tX_userselectedLeftLowerCornerPrimary = LLC_Temperature;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 65 */
 /*	uint8_t tX_userselectedLeftLowerCornerTimeout;
  */
-    if(Settings.tX_userselectedLeftLowerCornerTimeout > 60)
+    if(pSettings->tX_userselectedLeftLowerCornerTimeout > 60)
     {
-        Settings.tX_userselectedLeftLowerCornerTimeout = 0;
+        pSettings->tX_userselectedLeftLowerCornerTimeout = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 66 */
 /*	uint8_t tX_customViewPrimary;
  */
-    if(Settings.tX_customViewPrimary >= CVIEW_END)
+    if(pSettings->tX_customViewPrimary >= CVIEW_END)
     {
-        Settings.tX_customViewPrimary = 1;
+        pSettings->tX_customViewPrimary = 1;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 67 */
 /*	uint8_t tX_customViewTimeout;
  */
-    if(Settings.tX_customViewTimeout > 60)
+    if(pSettings->tX_customViewTimeout > 60)
     {
-        Settings.tX_customViewTimeout = 0;
+        pSettings->tX_customViewTimeout = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 68 */
 /*	uint8_t timeoutEnterButtonSelectDive;
  */
-    if(Settings.timeoutEnterButtonSelectDive != 10)
+    if(pSettings->timeoutEnterButtonSelectDive != 10)
     {
-        Settings.timeoutEnterButtonSelectDive = 10;
+        pSettings->timeoutEnterButtonSelectDive = 10;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 69 */
 /*	uint8_t logbookOffset;
  */
-    if(Settings.logbookOffset > 9000)
+    if(pSettings->logbookOffset > 9000)
     {
-        Settings.logbookOffset = 0;
+        pSettings->logbookOffset = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 70 */
 /*	uint8_t alwaysShowPPO2;
  */
-    if(Settings.alwaysShowPPO2 > 1)
+    if(pSettings->alwaysShowPPO2 > 1)
     {
-        Settings.alwaysShowPPO2 = 0;
+        pSettings->alwaysShowPPO2 = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 71 */
 /*	uint8_t extraDisplay;
  */
-    if(Settings.extraDisplay >= EXTRADISPLAY_END)
+    if(pSettings->extraDisplay >= EXTRADISPLAY_END)
     {
-        Settings.extraDisplay = EXTRADISPLAY_BIGFONT;
+        pSettings->extraDisplay = EXTRADISPLAY_BIGFONT;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 72 */
 /*	int8_t offsetPressure_mbar;
  */
-    if((Settings.offsetPressure_mbar > PRESSURE_OFFSET_LIMIT_MBAR) ||
-         (Settings.offsetPressure_mbar < -1 * PRESSURE_OFFSET_LIMIT_MBAR))
+    if((pSettings->offsetPressure_mbar > PRESSURE_OFFSET_LIMIT_MBAR) ||
+         (pSettings->offsetPressure_mbar < -1 * PRESSURE_OFFSET_LIMIT_MBAR))
     {
-        Settings.offsetPressure_mbar = 0;
+        pSettings->offsetPressure_mbar = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 73 */
 /*	int8_t offsetTemperature_centigrad;
  */
-    if((Settings.offsetTemperature_centigrad > 20) ||
-         (Settings.offsetTemperature_centigrad < -20))
+    if((pSettings->offsetTemperature_centigrad > 20) ||
+         (pSettings->offsetTemperature_centigrad < -20))
     {
-        Settings.offsetTemperature_centigrad = 0;
+        pSettings->offsetTemperature_centigrad = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 74 */
 /*	uint8_t gasConsumption_travel_l_min;
  */
-    if((Settings.gasConsumption_travel_l_min < 5) ||
-         (Settings.gasConsumption_travel_l_min > 50))
+    if((pSettings->gasConsumption_travel_l_min < 5) ||
+         (pSettings->gasConsumption_travel_l_min > 50))
     {
-        Settings.gasConsumption_travel_l_min = 20;
+        pSettings->gasConsumption_travel_l_min = 20;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 75 */
 /*	uint8_t gasConsumption_bottom_l_min;
  */
-    if((Settings.gasConsumption_bottom_l_min < 5) ||
-         (Settings.gasConsumption_bottom_l_min > 50))
+    if((pSettings->gasConsumption_bottom_l_min < 5) ||
+         (pSettings->gasConsumption_bottom_l_min > 50))
     {
-        Settings.gasConsumption_bottom_l_min = 20;
+        pSettings->gasConsumption_bottom_l_min = 20;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 76 */
 /*	uint8_t gasConsumption_deco_l_min;
  */
-    if((Settings.gasConsumption_deco_l_min < 5) ||
-         (Settings.gasConsumption_deco_l_min > 50))
+    if((pSettings->gasConsumption_deco_l_min < 5) ||
+         (pSettings->gasConsumption_deco_l_min > 50))
     {
-        Settings.gasConsumption_deco_l_min = 20;
+        pSettings->gasConsumption_deco_l_min = 20;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 77 */
 /*	uint8_t showDebugInfo;
  */
 #ifdef BOOT16
-        Settings.showDebugInfo = 0;
+        pSettings->showDebugInfo = 0;
 #else
-        if(Settings.showDebugInfo > 1)
-            Settings.showDebugInfo = 0;
+        if(pSettings->showDebugInfo > 1)
+            pSettings->showDebugInfo = 0;
 
 #endif
 
 /*	uint8_t selected_language;
  */
 #ifdef BOOT16
-        if(Settings.selected_language > 1)
-            Settings.selected_language = 0;
+        if(pSettings->selected_language > 1)
+            pSettings->selected_language = 0;
 #else
-        if(Settings.selected_language > 4)
-            Settings.selected_language = 0;
+        if(pSettings->selected_language > 4)
+            pSettings->selected_language = 0;
 #endif
 
 
 /*	uint8_t display_toogle_desc; 1/10 seconds
  */
-        if((Settings.display_toogle_desc < 20) || (Settings.display_toogle_desc > 600))
+        if((pSettings->display_toogle_desc < 20) || (pSettings->display_toogle_desc > 600))
         {
-            Settings.display_toogle_desc = SettingsStandard.display_toogle_desc;
+            pSettings->display_toogle_desc = SettingsStandard.display_toogle_desc;
             corrections++;
             setFirstCorrection(parameterId);
         }
-        parameterId++;
+        parameterId++; /* 78 */
 /*	uint8_t debugModeOnStart;
  */
-    if(Settings.debugModeOnStart > 1)
+    if(pSettings->debugModeOnStart > 1)
     {
-        Settings.debugModeOnStart = 0;
+        pSettings->debugModeOnStart = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 79 */
 
 /*	uint8_t IAmStolenPleaseKillMe;
  */
 
     if(hardwareDataGetPointer()->primarySerial == 90)
-        Settings.IAmStolenPleaseKillMe++;
+        pSettings->IAmStolenPleaseKillMe++;
     else
-        Settings.IAmStolenPleaseKillMe = 0;
+        pSettings->IAmStolenPleaseKillMe = 0;
 
 
 /*	uint8_t debugModeOnStart;
  */
-    if(Settings.compassBearing > 360)
+    if(pSettings->compassBearing > 360)
     {
-        Settings.compassBearing = 0;
+        pSettings->compassBearing = 0;
         corrections++;
         setFirstCorrection(parameterId);
     }
 
-    parameterId++;
+    parameterId++; /* 80 */
 /*	uint8_t lastKnownBatteryPercentage;
  */
-    if(Settings.lastKnownBatteryPercentage > 100)
+    if(pSettings->lastKnownBatteryPercentage > 100)
     {
-        Settings.lastKnownBatteryPercentage = 100;
+        pSettings->lastKnownBatteryPercentage = 100;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 81 */
 /*	uint8_t VPM_model
  */
-    if((Settings.VPM_model !=  VPM_FROM_FORTRAN) && (Settings.VPM_model !=  VPM_BACHELORWORK))
+    if((pSettings->VPM_model !=  VPM_FROM_FORTRAN) && (pSettings->VPM_model !=  VPM_BACHELORWORK))
     {
-        Settings.VPM_model = VPM_FROM_FORTRAN;
+        pSettings->VPM_model = VPM_FROM_FORTRAN;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
+    parameterId++; /* 82 */
 /*	uint8_t Buehlmann_model
  */
-    if((Settings.GF_model !=  BUEHLMANN_OSTC4) && (Settings.GF_model !=  BUEHLMANN_hwOS))
+    if((pSettings->GF_model !=  BUEHLMANN_OSTC4) && (pSettings->GF_model !=  BUEHLMANN_hwOS))
     {
-        Settings.GF_model = BUEHLMANN_OSTC4;
+        pSettings->GF_model = BUEHLMANN_OSTC4;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.FlipDisplay > 1) /* only boolean values allowed */
-   	{
-    	Settings.FlipDisplay = 0;
+    parameterId++; /* 83 */
+    if(pSettings->FlipDisplay > 1)  /* only boolean values allowed */
+    {
+        setFlipDisplay(1);
 	    corrections++;
 	    setFirstCorrection(parameterId);
    	}
-    parameterId++;
+    parameterId++; /* 84 */
 #ifdef ENABLE_MOTION_CONTROL
-    if(Settings.MotionDetection >= MOTION_DETECT_END)
+    if(pSettings->MotionDetection >= MOTION_DETECT_END)
    	{
-    	Settings.MotionDetection = MOTION_DETECT_OFF;
+    	pSettings->MotionDetection = MOTION_DETECT_OFF;
 	    corrections++;
 	    setFirstCorrection(parameterId);
    	}
 #else
-    Settings.MotionDetection = MOTION_DETECT_OFF;
-    Settings.viewPortMode = 0;
-    Settings.viewRoll = 0.0;
-    Settings.viewPitch = 0.0;
-    Settings.viewYaw = 0.0;
+    pSettings->MotionDetection = MOTION_DETECT_OFF;
+    pSettings->viewPortMode = 0;
+    pSettings->viewRoll = 0.0;
+    pSettings->viewPitch = 0.0;
+    pSettings->viewYaw = 0.0;
 #endif
-    parameterId++;
-    if(Settings.compassInertia > MAX_COMPASS_COMP)
+    parameterId++; /* 85 */
+    if(pSettings->compassInertia > MAX_COMPASS_COMP)
    	{
-    	Settings.compassInertia = 0;
+    	pSettings->compassInertia = 0;
 	    corrections++;
 	    setFirstCorrection(parameterId);
    	}
-    parameterId++;
-    if(Settings.tX_customViewPrimaryBF > CVIEW_T3_END)
+    parameterId++; /* 86 */
+    if(pSettings->tX_customViewPrimaryBF > CVIEW_T3_END)
     {
-    	Settings.tX_customViewPrimaryBF = CVIEW_T3_Decostop;
+    	pSettings->tX_customViewPrimaryBF = CVIEW_T3_Decostop;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.viewPortMode > MAX_VIEWPORT_MODE)
+    parameterId++; /* 87 */
+    if(pSettings->viewPortMode > MAX_VIEWPORT_MODE)
     {
-    	Settings.viewPortMode = 0;
+    	pSettings->viewPortMode = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.ppo2sensors_source >= O2_SENSOR_SOURCE_MAX)
+    parameterId++; /* 88 */
+    if(pSettings->ppo2sensors_source >= O2_SENSOR_SOURCE_MAX)
     {
-    	Settings.ppo2sensors_source = O2_SENSOR_SOURCE_OPTIC;
-    	Settings.ppo2sensors_calibCoeff[0] = 0.0;
-    	Settings.ppo2sensors_calibCoeff[1] = 0.0;
-    	Settings.ppo2sensors_calibCoeff[2] = 0.0;
+    	pSettings->ppo2sensors_source = O2_SENSOR_SOURCE_OPTIC;
+    	pSettings->ppo2sensors_calibCoeff[0] = 0.0;
+    	pSettings->ppo2sensors_calibCoeff[1] = 0.0;
+    	pSettings->ppo2sensors_calibCoeff[2] = 0.0;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.amPMTime > 1) /* only boolean values allowed */
+    parameterId++; /* 89 */
+    if(pSettings->amPMTime > 1) /* only boolean values allowed */
     {
-    	Settings.amPMTime = 0;
+    	pSettings->amPMTime = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.autoSetpoint > 1) /* only boolean values allowed */
+    parameterId++; /* 90 */
+    if(pSettings->autoSetpoint > 1) /* only boolean values allowed */
     {
-    	Settings.autoSetpoint = 0;
+    	pSettings->autoSetpoint = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.scubberActiveId > 1)
+    parameterId++; /* 91 */
+    if (pSettings->scrubberActiveId > 0x03) {
+        /* scrubber active is used as bitfield => two timer => 2 bits in use */
+        pSettings->scrubberActiveId = 0x00;
+        corrections++;
+        setFirstCorrection(parameterId);
+    }
+    parameterId++; /* 92 */
+    if((pSettings->scrubberData[0].TimerMax > MAX_SCRUBBER_TIME) || pSettings->scrubberData[0].TimerCur < MIN_SCRUBBER_TIME || pSettings->scrubberData[0].TimerCur > (int16_t)MAX_SCRUBBER_TIME)
     {
-    	Settings.scubberActiveId = 0;
-    	corrections++;
-    	setFirstCorrection(parameterId);
-    }
-    parameterId++;
-    if((Settings.scrubberData[0].TimerMax > MAX_SCRUBBER_TIME) || Settings.scrubberData[0].TimerCur < MIN_SCRUBBER_TIME || Settings.scrubberData[0].TimerCur > (int16_t)MAX_SCRUBBER_TIME)
-    {
-    	Settings.scrubberData[0].TimerMax = 0;
-    	Settings.scrubberData[0].TimerCur = 0;
+    	pSettings->scrubberData[0].TimerMax = 0;
+    	pSettings->scrubberData[0].TimerCur = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if((Settings.scrubberData[1].TimerMax > MAX_SCRUBBER_TIME) || Settings.scrubberData[1].TimerCur < MIN_SCRUBBER_TIME || Settings.scrubberData[1].TimerCur > (int16_t)MAX_SCRUBBER_TIME)
+    parameterId++; /* 93 */
+    if((pSettings->scrubberData[1].TimerMax > MAX_SCRUBBER_TIME) || pSettings->scrubberData[1].TimerCur < MIN_SCRUBBER_TIME || pSettings->scrubberData[1].TimerCur > (int16_t)MAX_SCRUBBER_TIME)
     {
-    	Settings.scrubberData[1].TimerMax = 0;
-    	Settings.scrubberData[1].TimerCur = 0;
+    	pSettings->scrubberData[1].TimerMax = 0;
+    	pSettings->scrubberData[1].TimerCur = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.scrubTimerMode > SCRUB_TIMER_END)
-    {
-    	Settings.scrubTimerMode = SCRUB_TIMER_OFF;
+    parameterId++; /* 94 */
+    if (pSettings->scrubTimerMode == INVALID_SCRUB_TIMER_OFF || pSettings->scrubTimerMode > SCRUB_TIMER_END) {
+        pSettings->scrubTimerMode = SCRUB_TIMER_MINUTES;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if((Settings.pscr_lung_ratio > PSCR_MAX_LUNG_RATIO) || (Settings.pscr_lung_ratio < PSCR_MIN_LUNG_RATIO))
+    parameterId++; /* 95 */
+    if((pSettings->pscr_lung_ratio > PSCR_MAX_LUNG_RATIO) || (pSettings->pscr_lung_ratio < PSCR_MIN_LUNG_RATIO))
     {
-    	Settings.pscr_lung_ratio = 10;
+    	pSettings->pscr_lung_ratio = 10;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.pscr_o2_drop > PSCR_MAX_O2_DROP)
+    parameterId++; /* 96 */
+    if(pSettings->pscr_o2_drop > PSCR_MAX_O2_DROP)
     {
-    	Settings.pscr_o2_drop = 4;
+    	pSettings->pscr_o2_drop = 4;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.co2_sensor_active > 1)
+    parameterId++; /* 97 */
+    if(pSettings->co2_sensor_active > 1)
     {
-    	Settings.co2_sensor_active = 0;
+    	pSettings->co2_sensor_active = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.ext_uart_protocol > UART_MAX_PROTOCOL)
+    parameterId++; /* 98 */
+    if(pSettings->ext_uart_protocol > UART_MAX_PROTOCOL)
     {
-    	Settings.ext_uart_protocol = 0;
+    	pSettings->ext_uart_protocol = 0;
     	corrections++;
     	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if((Settings.ext_sensor_map[0] >= SENSOR_END)
-    		|| (Settings.ext_sensor_map[1] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[2] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[3] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[4] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[5] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[6] >= SENSOR_END)
-			|| (Settings.ext_sensor_map[7] >= SENSOR_END))
+    parameterId++; /* 99 */
+    if((pSettings->ext_sensor_map[0] >= SENSOR_END)
+    		|| (pSettings->ext_sensor_map[1] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[2] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[3] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[4] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[5] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[6] >= SENSOR_END)
+			|| (pSettings->ext_sensor_map[7] >= SENSOR_END))
     {
-    	Settings.ext_sensor_map[0] = SENSOR_OPTIC;
-    	Settings.ext_sensor_map[1] = SENSOR_OPTIC;
-    	Settings.ext_sensor_map[2] = SENSOR_OPTIC;
-    	Settings.ext_sensor_map[3] = SENSOR_NONE;
-    	Settings.ext_sensor_map[4] = SENSOR_NONE;
-    	Settings.ext_sensor_map[5] = SENSOR_NONE;
-    	Settings.ext_sensor_map[6] = SENSOR_NONE;
-    	Settings.ext_sensor_map[7] = SENSOR_NONE;
+    	pSettings->ext_sensor_map[0] = SENSOR_OPTIC;
+    	pSettings->ext_sensor_map[1] = SENSOR_OPTIC;
+    	pSettings->ext_sensor_map[2] = SENSOR_OPTIC;
+    	pSettings->ext_sensor_map[3] = SENSOR_NONE;
+    	pSettings->ext_sensor_map[4] = SENSOR_NONE;
+    	pSettings->ext_sensor_map[5] = SENSOR_NONE;
+    	pSettings->ext_sensor_map[6] = SENSOR_NONE;
+    	pSettings->ext_sensor_map[7] = SENSOR_NONE;
        	corrections++;
        	setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.buttonLockActive > 1)
+    parameterId++; /* 100 */
+    if(pSettings->buttonLockActive > 1)
     {
-        Settings.buttonLockActive = 1;
+        pSettings->buttonLockActive = 1;
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if (Settings.compassDeclinationDeg > 99) {
-        Settings.compassDeclinationDeg = 99;
+    parameterId++; /* 101 */
+    if (pSettings->compassDeclinationDeg > MAX_COMPASS_DECLINATION_DEG) {
+        pSettings->compassDeclinationDeg = MAX_COMPASS_DECLINATION_DEG;
 
         corrections++;
         setFirstCorrection(parameterId);
-    } else if (Settings.compassDeclinationDeg < -99) {
-        Settings.compassDeclinationDeg = -99;
+    } else if (pSettings->compassDeclinationDeg < -MAX_COMPASS_DECLINATION_DEG) {
+        pSettings->compassDeclinationDeg = -MAX_COMPASS_DECLINATION_DEG;
 
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if (Settings.timerDurationS > 599) {
-        Settings.timerDurationS = 599;
+    parameterId++; /* 102 */
+    if (pSettings->timerDurationS > 599) {
+        pSettings->timerDurationS = 599;
 
         corrections++;
         setFirstCorrection(parameterId);
-    } else if (Settings.timerDurationS < 1) {
-        Settings.timerDurationS = 1;
+    } else if (pSettings->timerDurationS < 1) {
+        pSettings->timerDurationS = 1;
 
         corrections++;
         setFirstCorrection(parameterId);
     }
-    parameterId++;
-    if(Settings.cvAutofocus > 1)
+    parameterId++; /* 103 */
+    if(pSettings->cvAutofocus > 1)
     {
     	 corrections++;
-    	 Settings.cvAutofocus = 0;
+    	 pSettings->cvAutofocus = 0;
     }
-    parameterId++;
-    if((Settings.timeZone.hours > 14)
-    		|| (Settings.timeZone.hours < -12)
-			|| (Settings.timeZone.minutes > 45))
+    parameterId++; /* 104 */
+    if((pSettings->timeZone.hours > 14)
+    		|| (pSettings->timeZone.hours < -12)
+			|| (pSettings->timeZone.minutes > 45))
     {
-    	Settings.timeZone.hours = 0;
-    	Settings.timeZone.minutes = 0;
+    	pSettings->timeZone.hours = 0;
+    	pSettings->timeZone.minutes = 0;
     	 corrections++;
     }
-	parameterId++;
+	parameterId++; /* 105 */
     if(corrections)
     {
     	settingsWarning = 1;
@@ -1893,6 +1974,7 @@
 }
 
 
+#if 0
 #ifndef SPECIALPROGRAMM
 const SHardwareData* hardwareDataGetPointer(void)
 {
@@ -1900,6 +1982,7 @@
 }
 #endif
 #endif
+#endif
 const SSettings* settingsGetPointerStandard(void)
 {
     return &SettingsStandard;
@@ -1934,7 +2017,17 @@
 {
     return &Settings;
 }
+SSettings* profileGetPointer(uint8_t number)
+{
+	SSettings* returnPointer = NULL;
 
+	if(number < NUMBER_OF_PROFILES)
+	{
+		returnPointer = &Profile[number];
+	}
+
+    return returnPointer;
+}
 
 //  ===============================================================================
 //  set_settings_to_Standard
@@ -1948,28 +2041,70 @@
 ///					160622 added lastDiveLogIdBackup
 ///
 //  ===============================================================================
-void set_settings_to_Standard(void)
+void set_settings_to_Standard(uint8_t whichSettings)
 {
     SSettings *pSettings;
     const SSettings *pSettingsStandard;
     uint16_t personalDiveCountBackup;
     uint8_t lastDiveLogIdBackup;
+    uint32_t sampleStartBackup;
     pSettings = settingsGetPointer();
     pSettingsStandard = settingsGetPointerStandard();
+    uint8_t profileBackup = pSettings->activeProfile;
+
+    switch(whichSettings)
+    	{
+    		default:
+    		case EF_SETTINGS:
+    			break;
+    		case EF_PROFILE0:	pSettings = profileGetPointer(0);
+    			break;
+    		case EF_PROFILE1:	pSettings = profileGetPointer(1);
+    			break;
+    		case EF_PROFILE2:	pSettings = profileGetPointer(2);
+    			break;
+    		case EF_PROFILE3:	pSettings = profileGetPointer(3);
+    			break;
+    	}
 
     personalDiveCountBackup = pSettings->personalDiveCount;
     lastDiveLogIdBackup = pSettings->lastDiveLogId;
+    sampleStartBackup = pSettings->logFlashNextSampleStartAddress;
+
     memcpy(pSettings,pSettingsStandard,sizeof(*pSettings));
     pSettings->personalDiveCount = personalDiveCountBackup;
     pSettings->lastDiveLogId = lastDiveLogIdBackup;
+    pSettings->logFlashNextSampleStartAddress = sampleStartBackup;
 
     pSettings->firmwareVersion[0] = firmware_FirmwareData.versionFirst;
     pSettings->firmwareVersion[1] = firmware_FirmwareData.versionSecond;
     pSettings->firmwareVersion[2] = firmware_FirmwareData.versionThird;
     pSettings->firmwareVersion[3] = firmware_FirmwareData.versionBeta;
 
-    set_new_settings_missing_in_ext_flash();
-    check_and_correct_settings();
+    memset(pSettings->customtext,0,60);
+    sprintf(pSettings->customtext," <your name>\n <address>");
+    pSettings->cv_configuration &= ~(1 << CVIEW_sensors | 1 << CVIEW_sensors_mV | 1 << CVIEW_Timer);
+
+    switch(whichSettings)		/* some default data may be dependend on the default value => adapt setting */
+    	{
+    		default:
+    		case EF_SETTINGS:	pSettings->activeProfile = profileBackup;
+    			break;
+    		case EF_PROFILE0:	pSettings = profileGetPointer(0);
+    			break;
+    		case EF_PROFILE1:	pSettings = profileGetPointer(1);
+    			break;
+    		case EF_PROFILE2:	pSettings = profileGetPointer(2);	/* MCCR */
+    							pSettings->dive_mode = DIVEMODE_CCR;
+    			break;
+    		case EF_PROFILE3:	pSettings = profileGetPointer(3);	/* ECCR */
+    							pSettings->dive_mode = DIVEMODE_CCR;
+    							pSettings->CCR_Mode = CCRMODE_Sensors;
+    			break;
+    	}
+
+    set_new_settings_missing_in_ext_flash(whichSettings);
+    check_and_correct_settings(whichSettings);
     // has to be called too: createDiveSettings();
 }
 
@@ -2120,6 +2255,13 @@
     return 0;
 }
 
+bool checkValueSigned(int8_t value, int8_t from, int8_t to)
+{
+    if(value >= from && value <= to)
+        return true;
+    return false;
+}
+
 uint8_t writeData(uint8_t * data)
 {
         uint32_t newSensitivity;
@@ -2256,7 +2398,11 @@
         Settings.date_format = data[1];
         break;
         case 0x34:
+            if (!checkValueSigned(data[1], -MAX_COMPASS_DECLINATION_DEG, MAX_COMPASS_DECLINATION_DEG))
                 return ERROR_;
+            Settings.compassDeclinationDeg = (int8_t)data[1];
+
+            break;
         case 0x35:
                 if(data[1] & 0x80)
                 {
@@ -2288,7 +2434,11 @@
         Settings.fallbackToFixedSetpoint = data[1];
         break;
         case 0x39:
+            if (!checkValue(data[1], 0, 1))
                 return ERROR_;
+            setFlipDisplay(data[1]);
+
+            break;
         case 0x3A:
         if(!checkValue(data[1],70,110))
             return ERROR_;
@@ -2617,10 +2767,10 @@
         break;
 
     case 0x34:
-        data[datacounter++] = PARAM_UNKNOWN ;
-        data[datacounter++] = 0;
-        data[datacounter++] = 0; // compass gain, is unknown,, settingsGetPointerStandard()->;
-        data[datacounter++] = 0;
+        data[datacounter++] = PARAM_SINT;
+        data[datacounter++] = (uint8_t)-MAX_COMPASS_DECLINATION_DEG;
+        data[datacounter++] = (uint8_t)settingsGetPointerStandard()->compassDeclinationDeg;
+        data[datacounter++] = MAX_COMPASS_DECLINATION_DEG;
         break;
 
     case 0x35:
@@ -2660,8 +2810,8 @@
     case 0x39:
         data[datacounter++] = PARAM_BOOL;
         data[datacounter++] = 0;
-        data[datacounter++] = 0; // flipscreen, not yet :-) settingsGetPointerStandard()->;
-        data[datacounter++] = 0;
+        data[datacounter++] = settingsGetPointerStandard()->FlipDisplay;
+        data[datacounter++] = 1;
         break;
 
     case 0x3A:
@@ -2921,7 +3071,7 @@
         data[0] = Settings.date_format;
         break;
      case 0x34:
-        data[0] = 7; // gain should be always 7 as far as I understand the code in RTE
+        data[0] = (uint8_t)Settings.compassDeclinationDeg;
         break;
      case 0x35:
         data[0] = Settings.offsetPressure_mbar;
@@ -2939,7 +3089,7 @@
         data[0] = Settings.fallbackToFixedSetpoint;
         break;
      case 0x39:
-        data[0] = 0; // flip screen
+        data[0] = Settings.FlipDisplay;
         break;
      case 0x3A:
         data[0] = Settings.ButtonResponsiveness[3];
@@ -3344,7 +3494,27 @@
 {
 	settingsWarning = 0;
 }
+
 inline uint8_t isSettingsWarning()
 {
 	return settingsWarning;
 }
+
+bool isScrubberError(const SScrubberData *scrubberData)
+{
+    if (scrubberData->TimerCur <= SCRUBBER_ERROR_TIME) {
+        return true;
+    }
+
+    return false;
+}
+
+bool isScrubberWarning(const SScrubberData *scrubberData)
+{
+    if (scrubberData->TimerCur <= SCRUBBER_WARNING_TIME) {
+        return true;
+    }
+
+    return false;
+}
+
--- a/Discovery/Src/show_logbook.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/show_logbook.c	Sat Nov 15 19:29:44 2025 +0100
@@ -455,7 +455,7 @@
 #endif
 
     uint16_t dataLength = 0;
-    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tankdata, &posCoord, NULL);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tankdata, NULL, &posCoord, NULL, NULL);
 
     //Print Date
     uint8_t year = logbookHeader.dateYear;
@@ -466,7 +466,7 @@
 
     Gfx_write_label_var(hgfx, 30, 250,10, &FontT42,CLUT_GasSensor1,text);
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
     if((posCoord.fLat != 0.0) || (posCoord.fLon != 0.0))
     {
     	snprintf(text, 20, "%2.4f - %2.4f", posCoord.fLat, posCoord.fLon );
@@ -752,7 +752,7 @@
     uint16_t decoDepthdata[1000];
     uint16_t *pDecoDepthData = 0;
 
-    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, decoDepthdata, NULL, NULL, NULL);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, decoDepthdata, NULL, NULL, NULL, NULL, NULL);
 
         for(int i = 0; i<dataLength; i++)
         {
@@ -897,6 +897,7 @@
     releaseFrame(17,tLOGbackground.FBStartAdress);
 }
 
+#define MSG_LENGTH 30
 
 static void show_logbook_logbook_show_log_page3(GFX_DrawCfgScreen *hgfx, uint8_t StepBackwards)
 {
@@ -917,9 +918,9 @@
     uint16_t dataLength = 0;
     uint16_t depthdata[1000];
     uint8_t  gasdata[1000];
-    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 
-    char msg[15];
+    char msg[MSG_LENGTH];
     char gas_name[15];
     int j = 0;
 
@@ -979,18 +980,18 @@
             	if(index < NUM_GASES)		/* Switch to Bailout is not covered by log gas list */
             	{
             		snprintf(gas_name,15,"Bailout");
-            		snprintf(msg,15,"G%d: %s",index +1, gas_name);
+                        snprintf(msg, MSG_LENGTH, "G%d: %s", index +1, gas_name);
             	}
             	else
             	{
             		print_gas_name(gas_name,15,logbookHeader.gasordil[index-NUM_GASES].oxygen_percentage,logbookHeader.gasordil[index-NUM_GASES].helium_percentage);
-            		snprintf(msg,15,"D%d: %s",index +1 - NUM_GASES, gas_name);
+                        snprintf(msg, MSG_LENGTH, "D%d: %s", index + 1 - NUM_GASES, gas_name);
             	}
             }
             else
             {
             	print_gas_name(gas_name,15,logbookHeader.gasordil[index].oxygen_percentage,logbookHeader.gasordil[index].helium_percentage);
-            	snprintf(msg,15,"G%d: %s",index +1, gas_name);
+                snprintf(msg, MSG_LENGTH, "G%d: %s", index + 1, gas_name);
             }
             Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,msg);
         }
@@ -1047,15 +1048,15 @@
 
 
         if(!isLoopMode(logbookHeader.diveMode))
-            dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+            dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         else
         {
         	switch(logbookHeader.CCRmode)
         	{
         		case CCRMODE_FixedSetpoint:
-        		default:				dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        		default:				dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         				break;
-        		case CCRMODE_Sensors:	dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL, NULL, NULL, NULL);
+        		case CCRMODE_Sensors:	dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         								if(!check_data_array_empty(sensor1))
         								{
         									sensorDataAvailable[0] = 1;
@@ -1072,22 +1073,22 @@
         								{
         									if(sensorDataAvailable[0] == 0)
         									{
-        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         										sensorDataAvailable[0] = 1;
         									}
         									else if(sensorDataAvailable[1] == 0)
         									{
-        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         										sensorDataAvailable[1] = 1;
         									}
         									else if(sensorDataAvailable[2] == 0)
         									{
-        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        										logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         										sensorDataAvailable[2] = 1;
         									}
         								}
         		    	break;
-        		case CCRMODE_Simulation: dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        		case CCRMODE_Simulation: dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         				break;
         	}
         }
--- a/Discovery/Src/simulation.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/simulation.c	Sat Nov 15 19:29:44 2025 +0100
@@ -43,6 +43,7 @@
 #include "vpm.h"
 #include "buehlmann.h"
 #include "logbook_miniLive.h"
+#include "logbook.h"
 
 #include "configuration.h"
 
@@ -111,7 +112,8 @@
 
     stateSim.lifeData.apnea_total_max_depth_meter = 0;
 
-    memcpy(stateSim.scrubberDataDive, settingsGetPointer()->scrubberData, sizeof(stateSim.scrubberDataDive));
+    SSettings *settings = settingsGetPointer();
+    memcpy(stateSim.scrubberDataDive, settings->scrubberData, sizeof(stateSim.scrubberDataDive));
     memset(simSensmVOffset,0,sizeof(simSensmVOffset));
    	if(getReplayOffset() != 0xFFFF)
    	{
@@ -244,21 +246,35 @@
     	pDiveState->lifeData.ascent_rate_meter_per_min = 0;
     }
 
-    if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (pDiveState->mode == MODE_DIVE) && isLoopMode(pDiveState->diveSettings.diveMode))
-    {
-    	simScrubberTimeoutCount++;
-    	if(simScrubberTimeoutCount >= 60)		/* resolution is minutes */
-    	{
-    		simScrubberTimeoutCount = 0;
-    		if(pDiveState->scrubberDataDive[pSettings->scubberActiveId].TimerCur > MIN_SCRUBBER_TIME)
-    		{
-    			pDiveState->scrubberDataDive[pSettings->scubberActiveId].TimerCur--;
-    		}
-            translateDate(stateUsed->lifeData.dateBinaryFormat, &pDiveState->scrubberDataDive[pSettings->scubberActiveId].lastDive);
-    	}
+    if (isScrubberTimerRunning(pDiveState, pSettings)) {
+        simScrubberTimeoutCount++;
+
+        if (simScrubberTimeoutCount >= 60) {
+            /* resolution is minutes */
+            simScrubberTimeoutCount = 0;
+
+            int16_t maxScrubberTime = INT16_MIN;
+            SScrubberData *longestScrubberData = NULL;
+            for (unsigned timerId = 0; timerId < 2; timerId++) {
+                if (pSettings->scrubberActiveId & (1 << timerId)) {
+                    SScrubberData *scrubberData = &pDiveState->scrubberDataDive[timerId];
+                    if (scrubberData->TimerCur > MIN_SCRUBBER_TIME) {
+                        scrubberData->TimerCur--;
+                    }
+
+                    if (scrubberData->TimerCur > maxScrubberTime) {
+                        maxScrubberTime = scrubberData->TimerCur;
+                        longestScrubberData = scrubberData;
+                    }
+
+                    translateDate(stateUsed->lifeData.dateBinaryFormat, &scrubberData->lastDive);
+                }
+            }
+
+            logScrubberState(longestScrubberData);
+        }
     }
 
-
     if(lastPressure_bar > 0)
      {
          //1 second * 60 == 1 minute, bar * 10 = meter
--- a/Discovery/Src/stm32f4xx_hal_msp_hw2.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/stm32f4xx_hal_msp_hw2.c	Sat Nov 15 19:29:44 2025 +0100
@@ -630,18 +630,20 @@
 
   /* USER CODE END USART3_MspInit 0 */
     /* Peripheral clock enable */
-    __USART3_CLK_ENABLE();
+	USART_RADIO_RX_GPIO_CLK_ENABLE();
 
     /**USART3 GPIO Configuration
-    PC10     ------> USART3_TX
-    PC11     ------> USART3_RX
+    PB11     ------> USART3_RX
     */
-    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
+    GPIO_InitStruct.Pin = USART_RADIO_RX_PIN;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_PULLUP;
     GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
-    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+    GPIO_InitStruct.Alternate = USART_RADIO_RX_AF;
+    HAL_GPIO_Init(USART_RADIO_RX_GPIO_PORT, &GPIO_InitStruct);
+
+    HAL_NVIC_SetPriority(USART_RADIO_IRQn, 0, 1);
+    HAL_NVIC_EnableIRQ(USART_RADIO_IRQn);
 
   /* USER CODE BEGIN USART3_MspInit 1 */
 
@@ -706,7 +708,7 @@
     PC10     ------> USART3_TX
     PC11     ------> USART3_RX
     */
-    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
+    HAL_GPIO_DeInit(USART_RADIO_RX_GPIO_PORT, USART_RADIO_RX_PIN);
 
   /* USER CODE BEGIN USART3_MspDeInit 1 */
 
--- a/Discovery/Src/t3.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/t3.c	Sat Nov 15 19:29:44 2025 +0100
@@ -33,6 +33,7 @@
 #include "t3.h"
 
 #include "data_exchange_main.h"
+#include "settings.h"
 #include "decom.h"
 #include "gfx_fonts.h"
 #include "math.h"
@@ -536,13 +537,13 @@
     else
     {
     	color = 0xff;
-    	if((pSettings->slowExitTime != 0) && (nextstopDepthMeter == 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter))
+    	if((pSettings->slowExitTime != 0) && (nextstopDepthMeter == 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter) && (stateUsed->lifeData.depth_meter > 0.3))
     	{
     		color = t3_drawSlowExitGraph(tXscreen, tXl1, tXr1);
     	}
     	if(color == 0xff)	/* no slow exit => continue with common ascent graph */
     	{
-			if(stateUsed->lifeData.ascent_rate_meter_per_min > 0) /* ascentrate graph -standard mode */
+			if(stateUsed->lifeData.ascent_rate_meter_per_min > 0) /* ascent rate graph -standard mode */
 			{
 				 if(!pSettings->FlipDisplay)
 				 {
@@ -769,7 +770,7 @@
     else
     {
         t3_refresh_customview(depth_meter);
-        requestBuzzerActivation(0);
+        requestBuzzerActivation(REQUEST_BUZZER_OFF);
     }
     if(stateUsed->warnings.lowBattery)
         t3_basics_battery_low_customview_extra(&t3r1); //t3c1);
@@ -1334,14 +1335,13 @@
                 GFX_write_string(&FontT105,tXc1,text,1);
             }
 
-            if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && isLoopMode(pSettings->dive_mode))
-            {
+            if (isScrubberTimerEnabled(pSettings)) {
                  snprintf(text,TEXTSIZE,"\032\002\f%c",TXT_ScrubTime);
                  GFX_write_string(&FontT42,tXc1,text,0);
 
                 textpointer = 0;
                 text[textpointer++] = '\002';
-                textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings);
+                textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings, false);
                 GFX_write_string(&FontT105,tXc1,text,1);
             }
         }
@@ -1687,7 +1687,7 @@
     {
         GFX_write_string(&FontT48,&t3c2,text,0);
     }
-    requestBuzzerActivation(1);
+    requestBuzzerActivation(REQUEST_BUZZER_CONTINUOUS);
 }
 
 uint8_t t3_customview_disabled(uint8_t view)
@@ -1996,21 +1996,46 @@
     return t3_selection_customview;
 }
 
-int printScrubberText(char *text, size_t size, const SScrubberData *scrubberData, SSettings *settings)
+unsigned printScrubberText(char *text, size_t size, const SScrubberData scrubberData[], const SSettings *settings, bool useTwoLines)
 {
-    int16_t currentTimerMinutes = scrubberData[settings->scubberActiveId].TimerCur;
-    char colour = '\020';
-    if (currentTimerMinutes <= 0) {
-        colour = '\025';
-    } else if (currentTimerMinutes <= 30) {
-        colour = '\024';
+    unsigned textIndex = 0;
+	for (unsigned timerId = 0; timerId < 2; timerId++) {
+		if (settings->scrubberActiveId & (1 << timerId)) {
+            const SScrubberData *currentScrubberData = &scrubberData[timerId];
+            char colour = '\020';
+            if (isScrubberError(currentScrubberData)) {
+                colour = '\025';
+            } else if (isScrubberWarning(currentScrubberData)) {
+                colour = '\024';
+            }
+
+            if (useTwoLines) {
+                textIndex += snprintf(&text[textIndex], size, "\016\016");
+            }
+
+            int16_t currentTimerMinutes = currentScrubberData->TimerCur;
+            if (settings->scrubTimerMode == SCRUB_TIMER_MINUTES || currentTimerMinutes < 0) {
+                textIndex += snprintf(&text[textIndex], size, "%c%3i'", colour, currentTimerMinutes);
+            } else {
+                if (useTwoLines) {
+                    textIndex += snprintf(&text[textIndex], size, "%c%u%%", colour, currentTimerMinutes * 100 / settings->scrubberData[timerId].TimerMax);
+                } else {
+                    textIndex += snprintf(&text[textIndex], size, "%c%u\016\016%%\017", colour, currentTimerMinutes * 100 / settings->scrubberData[timerId].TimerMax);
+                }
+            }
+
+			if (settings->scrubberActiveId == 0x03 && timerId == 0)	{
+                /* both timers are active => print separator */
+                if (useTwoLines) {
+                    textIndex += snprintf(&text[textIndex], size, "\r\n");
+                } else {
+                    textIndex += snprintf(&text[textIndex], size, "\020|");
+                }
+			}
+        }
     }
 
-    if (settings->scrubTimerMode == SCRUB_TIMER_MINUTES || currentTimerMinutes < 0) {
-        return snprintf(text, size, "%c%3i'", colour, currentTimerMinutes);
-    } else {
-        return snprintf(text, size, "%c%u\016\016%%\017", colour, currentTimerMinutes * 100 / settingsGetPointer()->scrubberData[settings->scubberActiveId].TimerMax);
-    }
+	return textIndex;
 }
 
 void t3_AF_updateBorderConditions()
--- a/Discovery/Src/t7.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/t7.c	Sat Nov 15 19:29:44 2025 +0100
@@ -139,7 +139,7 @@
 	CVIEW_Charger,
     CVIEW_CcrSummary,
     CVIEW_Timer,
-#if defined ENABLE_GPIO_V2 || defined ENABLE_GNSS_SUPPORT
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 	CVIEW_Position,
 #endif
     CVIEW_END
@@ -705,9 +705,9 @@
 	static float debounceAmbientPressure = 0;
 	static uint8_t lastChargeStatus = 0;
 	static float lastTemperature = 100.0;
-    char text[256];
-    char timeSuffix;
-    uint8_t hours;
+    char text[200];
+    char tmpString[20];
+
     uint8_t loop, textIdx;
     uint8_t date[3], year,month,day;
     uint32_t color;
@@ -795,53 +795,20 @@
         dateNotSet = 1;
     else
         dateNotSet = 0;
-/*
-    if(Stime.Seconds % 2)
-        snprintf(text,255,"\001%02d:%02d",Stime.Hours,Stime.Minutes);
-    else
-        snprintf(text,255,"\001%02d\031:\020%02d",Stime.Hours,Stime.Minutes);
-    GFX_write_string(&FontT54,&t7surfaceR,text,3);
-*/
-// debug version:
-
-    if (settingsGetPointer()->amPMTime)
+
+
+
+    if((dateNotSet) && (Stime.Seconds % 2 == 0))
     {
-		if (Stime.Hours > 11)
-		{
-			timeSuffix = 'P';
-		}
-		else
-		{
-			timeSuffix = 'A';
-		}
-
-		if (Stime.Hours % 12 == 0)
-		{
-			hours = 12;
-		}
-		else
-		{
-			hours = (Stime.Hours % 12);
-		}
-
-	    if(Stime.Seconds % 2)
-	        snprintf(text,255,"\001%02d:%02d:%02d\016\016%cM\017",hours,Stime.Minutes,Stime.Seconds,timeSuffix);
-	    else if(dateNotSet)
-	        snprintf(text,255,"\001\031%02d:%02d:%02d\016\016%cM\017\020",hours,Stime.Minutes,Stime.Seconds,timeSuffix);
-	    else
-	        snprintf(text,255,"\001%02d\031:\020%02d:%02d\016\016%cM\017",hours,Stime.Minutes,Stime.Seconds,timeSuffix);
-	    GFX_write_string(&FontT48,&t7surfaceR,text,3);
+    	formatStringOfTime(tmpString,20,Stime,0,1);
+    	snprintf(text,100,"\031\001%s",tmpString);
     }
     else
     {
-        if(Stime.Seconds % 2)
-            snprintf(text,255,"\001%02d:%02d:%02d",Stime.Hours,Stime.Minutes,Stime.Seconds);
-        else if(dateNotSet)
-            snprintf(text,255,"\001\031%02d:%02d:%02d\020",Stime.Hours,Stime.Minutes,Stime.Seconds);
-        else
-            snprintf(text,255,"\001%02d\031:\020%02d:%02d",Stime.Hours,Stime.Minutes,Stime.Seconds);
-        GFX_write_string(&FontT54,&t7surfaceR,text,3);
+    	formatStringOfTime(tmpString,20,Stime,1,1);
+    	snprintf(text,100,"\030\001%s",tmpString);
     }
+    GFX_write_string(&FontT48,&t7surfaceR,text,3);
 
     if(settingsGetPointer()->date_format == DDMMYY)
     {
@@ -1065,6 +1032,7 @@
     else
     {
     	textIdx = 0;
+
         if(isLoopMode(stateUsed->diveSettings.diveMode))
             gasOffset = NUM_OFFSET_DILUENT;
         else
@@ -1095,9 +1063,23 @@
 			text[textIdx++] = 10;
     	}
     	text[textIdx++] = 0;
+    	if(!pSettings->FlipDisplay)
+    	{
+    		t7surfaceL.WindowX0 +=5;
+    	}
+    	else
+    	{
+    		t7surfaceL.WindowX1 -=2;
+    	}
         GFX_write_string(&FontT48,&t7surfaceL,text,6);
-
-
+        if(!pSettings->FlipDisplay)
+        {
+        	t7surfaceL.WindowX0 -=5;
+        }
+        else
+        {
+        	t7surfaceL.WindowX1 +=2;
+        }
         oxygen_percentage = 100;
         oxygen_percentage -= stateUsed->lifeData.actualGas.nitrogen_percentage;
         oxygen_percentage -= stateUsed->lifeData.actualGas.helium_percentage;
@@ -1121,7 +1103,7 @@
         	if(!pSettings->FlipDisplay)
         	{
         		start.y = t7surfaceL.WindowY0 + (3 * t7surfaceL.WindowLineSpacing);
-        		start.x = t7surfaceL.WindowX0 + ((stateUsed->lifeData.actualGas.GasIdInSettings - gasOffset - 1) * 35);
+        		start.x = t7surfaceL.WindowX0 + ((stateUsed->lifeData.actualGas.GasIdInSettings - gasOffset - 1) * 35) + 2;
         	}
 			else
 			{
@@ -1129,7 +1111,7 @@
 				start.x = t7surfaceR.WindowX0 + ((stateUsed->lifeData.actualGas.GasIdInSettings - gasOffset - 1) * 35);
 			}
 
-            stop.x = start.x + 25;
+            stop.x = start.x + 29;
             stop.y = start.y + 52;
             GFX_draw_box2(&t7screen, start, stop, CLUT_Font020, 1);
         }
@@ -1622,7 +1604,7 @@
     }
 */
     GFX_write_string(&FontT48,&t7cW,text,1);
-    requestBuzzerActivation(1);
+   	requestBuzzerActivation(REQUEST_BUZZER_CONTINUOUS);
 }
 
 
@@ -1820,7 +1802,7 @@
     }
 
     bool showScrubberTime = false;
-    if (settings->scrubTimerMode != SCRUB_TIMER_OFF) {
+    if (isScrubberTimerEnabled(settings)) {
         numLines++;
         showScrubberTime = true;
     }
@@ -1897,7 +1879,7 @@
     heading[headingIndex++] = '\016';
     heading[headingIndex++] = TXT_CCRmode;
 
-    data[dataIndex++] = '\t';
+    data[dataIndex++] = '\002';
     char *modeText;
     if (settings->CCR_Mode == CCRMODE_Sensors) {
         if (settings->fallbackToFixedSetpoint) {
@@ -1925,7 +1907,7 @@
 
         data[dataIndex++] = '\n';
         data[dataIndex++] = '\r';
-        data[dataIndex++] = '\t';
+        data[dataIndex++] = '\002';
         dataIndex += snprintf(&data[dataIndex], 10, "\020%01.2f", setpointsToShow[i]->setpoint_cbar / 100.0);
         if (setpointsToShow[i]->depth_meter && !(settings->autoSetpoint && i + 1 == SETPOINT_INDEX_AUTO_DECO)) {
             bool setpointDelayed = settings->autoSetpoint && i + 1 == SETPOINT_INDEX_AUTO_LOW && settings->delaySetpointLow;
@@ -1945,7 +1927,7 @@
 
         data[dataIndex++] = '\n';
         data[dataIndex++] = '\r';
-        data[dataIndex++] = '\t';
+        data[dataIndex++] = '\002';
         data[dataIndex++] = '\020';
         dataIndex += write_gas(&data[dataIndex], diluentsToShow[i]->oxygen_percentage, diluentsToShow[i]->helium_percentage);
         if (diluentsToShow[i]->note.ub.deco) {
@@ -1967,8 +1949,8 @@
 
         data[dataIndex++] = '\n';
         data[dataIndex++] = '\r';
-        data[dataIndex++] = '\t';
-        dataIndex += printScrubberText(&data[dataIndex], 10, settings->scrubberData, settings);
+        data[dataIndex++] = '\002';
+        dataIndex += printScrubberText(&data[dataIndex], 10, settings->scrubberData, settings, false);
     }
 
     heading[headingIndex++] = '\017';
@@ -1983,16 +1965,19 @@
     if (!settings->FlipDisplay) {
 	    t7cY0free.WindowY0 = t7cC.WindowY0 - 10;
         t7cY0free.WindowX0 += 10;
+        t7cY0free.WindowX1 = t7cC.WindowX1 - 10;
         t7cY0free.WindowY0 += 10;
         t7cY0free.WindowY1 = 355;
         GFX_write_string(&FontT24, &t7cY0free, heading, 1);
         t7cY0free.WindowX0 -= 10;
         t7cY0free.WindowY0 -= 10;
     } else {
+    	t7cY0free.WindowX0 -= 10;
 	    t7cY0free.WindowY1 = 400;
         t7cY0free.WindowY1 -= 10;
         t7cY0free.WindowX1 -= 10;
         GFX_write_string(&FontT24, &t7cY0free, heading, 1);
+        t7cY0free.WindowX0 += 10;
         t7cY0free.WindowY1 += 10;
         t7cY0free.WindowX1 += 10;
     }
@@ -2165,9 +2150,8 @@
 {
 	static uint8_t last_customview = CVIEW_END;
 
-    char text[256];
-	char timeSuffix;
-	uint8_t hoursToDisplay;
+    char text[200];
+    char tmpString[20];
 #ifdef ENABLE_PSCR_MODE
 	uint8_t showSimPPO2 = 1;
 #endif
@@ -2431,39 +2415,8 @@
         translateDate(stateRealGetPointer()->lifeData.dateBinaryFormat, &Sdate);
         translateTime(stateRealGetPointer()->lifeData.timeBinaryFormat, &Stime);
 
-        if (settingsGetPointer()->amPMTime)
-        {
-			if (Stime.Hours > 11)
-			{
-				timeSuffix = 'P';
-			}
-			else
-			{
-				timeSuffix = 'A';
-			}
-
-			if (Stime.Hours % 12 == 0)
-			{
-				hoursToDisplay = 12;
-			}
-			else
-			{
-				hoursToDisplay = (Stime.Hours % 12);
-			}
-
-			if(Stime.Seconds % 2)
-				textpointer += snprintf(&text[textpointer],100,"\030\001%02d:%02d %cM",hoursToDisplay,Stime.Minutes,timeSuffix);
-			else
-				textpointer += snprintf(&text[textpointer],100,"\030\001%02d\031:\030%02d %cM",hoursToDisplay,Stime.Minutes,timeSuffix);
-        }
-        else
-        {
-        	if(Stime.Seconds % 2)
-        		textpointer += snprintf(&text[textpointer],100,"\030\001%02d:%02d",Stime.Hours,Stime.Minutes);
-        	else
-        		textpointer += snprintf(&text[textpointer],100,"\030\001%02d\031:\030%02d",Stime.Hours,Stime.Minutes);
-        }
-
+        formatStringOfTime(tmpString,20,Stime,1,0);
+		snprintf(text,100,"\030\001%s",tmpString);
         GFX_write_string(&FontT42, &t7cY0free, text, 2);
 
         // EAD / END
@@ -2816,7 +2769,7 @@
 
 /* ascent rate graph */
     color = 0xff;
-    if((pSettings->slowExitTime != 0) && (nextstopDepthMeter == 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter))
+    if((pSettings->slowExitTime != 0) && (nextstopDepthMeter == 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter) && (stateUsed->lifeData.depth_meter > 0.3))
     {
     	color = t7_drawSlowExitGraph();
     }
@@ -3233,7 +3186,7 @@
     else
     {
         t7_refresh_customview();
-        requestBuzzerActivation(0);
+        requestBuzzerActivation(REQUEST_BUZZER_OFF);
     }
 
     /* the frame */
@@ -3254,18 +3207,18 @@
     {
     	selection_custom_field++;
     }
-    if((selection_custom_field == LLC_ScrubberTime) && ((settingsGetPointer()->scrubTimerMode == SCRUB_TIMER_OFF) || (!isLoopMode(settingsGetPointer()->dive_mode))))
-    {
+    SSettings *settings = settingsGetPointer();
+    if (selection_custom_field == LLC_ScrubberTime && !isScrubberTimerEnabled(settings)) {
     	selection_custom_field++;
     }
 #ifdef ENABLE_PSCR_MODE
-    if((selection_custom_field == LCC_SimPpo2) && (settingsGetPointer()->dive_mode != DIVEMODE_PSCR))
+    if((selection_custom_field == LCC_SimPpo2) && (settings->dive_mode != DIVEMODE_PSCR))
     {
     	selection_custom_field++;
     }
 #endif
 #ifdef ENABLE_CO2_SUPPORT
-    if((selection_custom_field == LCC_CO2) && (settingsGetPointer()->co2_sensor_active == 0))
+    if((selection_custom_field == LCC_CO2) && (settings->co2_sensor_active == 0))
     {
        	selection_custom_field++;
     }
@@ -3402,7 +3355,8 @@
     	tinyHeaderFont = 1;
         headerText[2] = TXT_ScrubTime;
 
-        printScrubberText(text, TEXTSIZE, stateUsed->scrubberDataDive, pSettings);
+        bool useTwoLines = (pSettings->scrubberActiveId == 0x03);
+        textpointer = printScrubberText(text, TEXTSIZE, stateUsed->scrubberDataDive, pSettings, useTwoLines);
 
 		break;
 #ifdef ENABLE_PSCR_MODE
@@ -3537,7 +3491,7 @@
     }
     else
     {
-        	GFX_write_string(&FontT48,&t7l3,text,line);
+        GFX_write_string(&FontT48,&t7l3,text,line);
     }
 #else
     GFX_write_string(&FontT105,&t7l3,text,line);
@@ -4176,7 +4130,7 @@
 
     t7cY0free.WindowLineSpacing = 48;
     t7cY0free.WindowNumberOfTextLines = 6;
-    t7cY0free.WindowTab = 420;
+    t7cY0free.WindowTab = 380;
 
     // header
     textpointer = 0;
@@ -4198,10 +4152,9 @@
     text[textpointer++] = TXT_FutureTTS;
     text[textpointer++] = '\n';
     text[textpointer++] = '\r';
-    if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)))
-    {
-		text[textpointer++] = TXT_ScrubTime;
-
+    if (isScrubberTimerEnabled(pSettings)) {
+		text[textpointer++] = TXT_2BYTE;
+		text[textpointer++] = TXT2BYTE_Scrubber;
     }
     text[textpointer++] = '\017';
 	text[textpointer++] = 0;
@@ -4247,13 +4200,12 @@
     else
     	textpointer += snprintf(&text[textpointer],10,"\020%ih", (pDecoinfoFuture->output_time_to_surface_seconds + 59) / 3600);
 
-    if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)))
-    {
+    if (isScrubberTimerEnabled(pSettings)) {
         text[textpointer++] = '\n';
         text[textpointer++] = '\r';
         text[textpointer++] = '\t';
 
-        textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings);
+        textpointer += printScrubberText(&text[textpointer], 10, stateUsed->scrubberDataDive, pSettings, false);
     }
     text[textpointer++] = 0;
     Gfx_colorsscheme_mod(text, 0);
@@ -4648,7 +4600,7 @@
 	}
 	else
 	{
-		memcpy (&ChargerLog[0],&ChargerLog[1],sizeof(ChargerLog) - 1);
+		memmove(&ChargerLog[0], &ChargerLog[1], sizeof(ChargerLog) - 1);
 		ChargerLog[curIndex] = level;
 	}
 	if(curIndex > 1)	/* estimate time til charging is complete */
--- a/Discovery/Src/tCCR.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tCCR.c	Sat Nov 15 19:29:44 2025 +0100
@@ -34,6 +34,7 @@
 #include "data_exchange.h"
 #include "check_warning.h"
 #include "configuration.h"
+#include "logbook.h"
 #include <math.h>
 
 /* Private types -------------------------------------------------------------*/
@@ -340,17 +341,30 @@
     // If we are in the simulator the counter is updated in `simulator.c`
     if (!is_stateUsedSetToSim()) {
         /* decrease scrubber timer only if we are not bailed out */
-        if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (stateUsed->mode == MODE_DIVE) && isLoopMode(stateUsed->diveSettings.diveMode))
-        {
+        if (isScrubberTimerRunning(stateUsed, pSettings)) {
             ScrubberTimeoutCount++;
-            if(ScrubberTimeoutCount >= 600)		/* resolution is minutes */
-            {
+            if (ScrubberTimeoutCount >= 600) {		/* resolution is minutes */
                 ScrubberTimeoutCount = 0;
-                if(stateUsed->scrubberDataDive[pSettings->scubberActiveId].TimerCur > MIN_SCRUBBER_TIME)
-                {
-                    stateUsedWrite->scrubberDataDive[pSettings->scubberActiveId].TimerCur--;
+
+                int16_t maxScrubberTime = INT16_MIN;
+                SScrubberData *longestScrubberData = NULL;
+                for (unsigned timerId = 0; timerId < 2; timerId++) {
+                    if (pSettings->scrubberActiveId & (1 << timerId)) {
+                        SScrubberData *scrubberData = &stateUsedWrite->scrubberDataDive[timerId];
+                        if (scrubberData->TimerCur > MIN_SCRUBBER_TIME) {
+                            scrubberData->TimerCur--;
+                        }
+
+                        if (scrubberData->TimerCur > maxScrubberTime) {
+                            maxScrubberTime = scrubberData->TimerCur;
+                            longestScrubberData = scrubberData;
+                        }
+
+                        translateDate(stateUsed->lifeData.dateBinaryFormat, &scrubberData->lastDive);
+                    }
                 }
-                translateDate(stateUsed->lifeData.dateBinaryFormat, &stateUsedWrite->scrubberDataDive[pSettings->scubberActiveId].lastDive);
+
+                logScrubberState(longestScrubberData);
             }
         }
     }
--- a/Discovery/Src/tComm.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tComm.c	Sat Nov 15 19:29:44 2025 +0100
@@ -188,11 +188,10 @@
         if(bluetoothActiveLastTime)
         {
         	HAL_UART_AbortReceive_IT(&UartHandle);
-            HAL_UART_DeInit(&UartHandle);
-            HAL_Delay(1);
-            UartHandle.Init.BaudRate   = 115200;	/* Module will be operating at default baud rate if powered again */
-            BmTmpConfig = BM_CONFIG_OFF;			/* Restart configuration if powered again */
-            HAL_UART_Init(&UartHandle);
+       		HAL_UART_DeInit(&UartHandle);
+       		HAL_Delay(1);
+       		UartHandle.Init.BaudRate   = 115200;	/* Module will be operating at default baud rate if powered again */
+        	BmTmpConfig = BM_CONFIG_OFF;			/* Restart configuration if powered again */
             HAL_Delay(1);
             UartReady = RESET;
             StartListeningToUART = 1;
@@ -205,8 +204,8 @@
     else
     {
         bluetoothActiveLastTime = 1;
-        if(RequestDisconnection)
-        {
+        if(RequestDisconnection)					/* at the moment disconnection does not seem to be in use. */
+        {											/* Instead the modul id usually powered off for disconnection */
         	RequestDisconnection = 0;
             tComm_Disconnect();
         }
@@ -225,6 +224,7 @@
 		if((UartReady == RESET) && StartListeningToUART)
 		{
 				StartListeningToUART = 0;
+				receiveStartByteUart = 0;
 				if(HAL_UART_Receive_IT(&UartHandle, &receiveStartByteUart, 1) != HAL_OK)
 						tComm_Error_Handler();
 		}
@@ -328,7 +328,7 @@
 #ifndef BOOTLOADER_STANDALONE
     if(updateSettingsAndMenuOnExit)
     {
-        check_and_correct_settings();
+        check_and_correct_settings(EF_SETTINGS);
         createDiveSettings();
         tM_rebuild_menu_after_tComm();
     }
@@ -453,7 +453,7 @@
 #ifndef BOOTLOADER_STANDALONE
 void tComm_Disconnect()
 {
-	uint8_t answer;
+	uint8_t answer = HAL_ERROR;
 	uint8_t retrycnt = 3;
 	char aTxDisconnect[] ="ATH\r";
 	char aTxBufferEnd[10];
@@ -461,31 +461,34 @@
 
 	uint8_t sizeDisconnect = sizeof(aTxDisconnect) -1;
 
-	tComm_GetBTCmdStr(BT_CMD_EXIT_CMD, aTxBufferEnd);
-	HAL_UART_AbortReceive_IT(&UartHandle);
-	do
+	if (isNewDisplay())		/* disconnect for OSTC5 BT is a little bit more complicated and not implemented yet, because function is not used */
 	{
-		HAL_Delay(200);
-		if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBufferEscapeSequence, 3, UART_OPERATION_TIMEOUT)== HAL_OK)
+		tComm_GetBTCmdStr(BT_CMD_EXIT_CMD, aTxBufferEnd);
+		HAL_UART_AbortReceive_IT(&UartHandle);
+		do
 		{
-			answer = tComm_CheckAnswerOK();
+			HAL_Delay(200);
+			if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBufferEscapeSequence, 3, UART_OPERATION_TIMEOUT)== HAL_OK)
+			{
+				answer = tComm_CheckAnswerOK();
+			}
+			retrycnt--;
 		}
-		retrycnt--;
-	}
-	while((answer != HAL_OK) && (retrycnt > 0));
+		while((answer != HAL_OK) && (retrycnt > 0));
 
-	if(answer == HAL_OK)
-	{
-		answer = HAL_ERROR;
-		if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxDisconnect,sizeDisconnect , UART_OPERATION_TIMEOUT)== HAL_OK)
+		if(answer == HAL_OK)
 		{
 			answer = HAL_ERROR;
-			if(tComm_CheckAnswerOK() == HAL_OK)
+			if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxDisconnect,sizeDisconnect , UART_OPERATION_TIMEOUT)== HAL_OK)
 			{
 				answer = HAL_ERROR;
-				if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBufferEnd, 4, UART_OPERATION_TIMEOUT) == HAL_OK)	/* exit terminal mode */
+				if(tComm_CheckAnswerOK() == HAL_OK)
 				{
-					answer = tComm_CheckAnswerOK();
+					answer = HAL_ERROR;
+					if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBufferEnd, 4, UART_OPERATION_TIMEOUT) == HAL_OK)	/* exit terminal mode */
+					{
+						answer = tComm_CheckAnswerOK();
+					}
 				}
 			}
 		}
@@ -1070,16 +1073,20 @@
     // get model + features
     case 0x60:
         aTxBuffer[count++] = 0x00; // hardware descriptor HIGH byte
-        aTxBuffer[count++] = 0x3B; // hardware descriptor LOW byte // 0x3B is OSTC4 //  0x1A is OTSC3
+        aTxBuffer[count++] = 0x3B; // hardware descriptor LOW byte // 0x3B is OSTC 4/5 //  0x1A is OTSC3
         aTxBuffer[count++] = 0x00; // feature descriptor HIGH byte
         aTxBuffer[count++] = 0x00; // feature descriptor LOW byte
-        aTxBuffer[count++] = 0x43; // model id
+        if (isNewDisplay()) {
+            aTxBuffer[count++] = 0x44; // model id OSTC5
+        } else {
+            aTxBuffer[count++] = 0x43; // model id OSTC4
+        }
         aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
 
     // get model
     case 0x6A:
-        aTxBuffer[count++] = 0x3B; // 0x3B is OSTC4 //  0x1A is OTSC3
+        aTxBuffer[count++] = 0x3B; // 0x3B is OSTC 4/5 //  0x1A is OTSC3
         aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
 
@@ -1179,7 +1186,7 @@
 #ifndef BOOTLOADER_STANDALONE
     //Reset all setting
     case 0x78:
-        set_settings_to_Standard();
+        set_settings_to_Standard(EF_SETTINGS);
         updateSettingsAndMenuOnExit = 1;
         aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
@@ -1546,6 +1553,7 @@
     const uint8_t id_Region1_firmware = 0xFF;
     const uint8_t id_RTE = 0xFE;
     uint8_t textpointer = 0;
+    uint32_t index = 0;
 
     //Get length
     if(HAL_UART_Receive(&UartHandle, sBuffer, 4,5000)!= HAL_OK) // 58000
@@ -1572,7 +1580,10 @@
 
     // neu 110212
     if(id == id_FONT)
+    {
         offsetTotal = 256 * 256 * 256 * (uint32_t)sBuffer[1] +  256 * 256 * (uint32_t)sBuffer[2] + 256 * (uint32_t)sBuffer[3];
+       /* todo set offset depending on font version offsetTotal = 0; */
+    }
     else
         offsetTotal = 256 * 256 * 256 * (uint32_t)sBuffer[0] +  256 * 256 * (uint32_t)sBuffer[1] + 256 * (uint32_t)sBuffer[2] + sBuffer[3];
 
@@ -1713,7 +1724,7 @@
             return 0xFF;
     }
     else
-    //if(region == 2)
+    if(id == id_FONT)
     {
         uint8_t ptr = 0;
         ptr += gfx_number_to_string(7,0,&display_text[ptr],lengthTotal);
@@ -1728,7 +1739,7 @@
     }
 
 
-    // only non RTE !!
+    /* only non RTE !! (at this point RTE path already performed a return some lines above */
     uint8_t* pBufferCompare = (uint8_t*)getFrame(20);
     ByteCompareStatus = 0;
 
@@ -1742,14 +1753,14 @@
 
         if(lengthCompare != length1)
             ByteCompareStatus = 10000;
-        for(int i = 0; i < length1; i++)
+        for(index = 0; index < length1; index++)
         {
-            if(pBuffer1[0] != pBufferCompare[0])
+            if(pBuffer1[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
     }
     else
-    //if(region == 2)
+    if(id == id_FONT)
     {
         /* upper region firmware can be larger (1MB) */
         if(ext_flash_read_firmware2(0, pBufferCompare,4, 0,0) != 0xFFFFFFFF)
@@ -1761,16 +1772,16 @@
             ByteCompareStatus = 10000;
         if(offsetTotal != offsetCompare)
             ByteCompareStatus += 20000;
-        for(int i = 0; i < length1; i++)
+        for(index = 0; index < length1; index++)
         {
-            if(pBuffer1[0] != pBufferCompare[0])
+            if(pBuffer1[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
 
         lengthCompare = ext_flash_read_firmware2(0, 0,768000, pBufferCompare,768000);
-        for(int i = 0; i < length2; i++)
+        for(index = 0; index < length2; index++)
         {
-            if(pBuffer2[0] != pBufferCompare[0])
+            if(pBuffer2[index] != pBufferCompare[index])
                 ByteCompareStatus++;
         }
     }
@@ -2033,7 +2044,14 @@
 			{
 				if(indexRef != 0)
 				{
-					indexRef = 0;
+					if((answerOkay[0] == aRxBuffer[indexBuf]))
+					{
+						indexRef = 1;
+					}
+					else
+					{
+						indexRef = 0;
+					}
 				}
 			}
 			indexBuf++;
@@ -2245,178 +2263,169 @@
 
 void tComm_StartBlueModConfig()
 {
-	uint8_t answer = HAL_OK;
-	uint8_t RxBuffer[UART_CMD_BUF_SIZE];
-	uint8_t index = 0;
+	HAL_UART_Init(&UartHandle);
 
-	BmTmpConfig = BM_CONFIG_ECHO;
-	do	/* flush RX buffer */
+	if (isNewDisplay())
 	{
-		answer = HAL_UART_Receive(&UartHandle, (uint8_t*)&RxBuffer[index], 1, 10);
-		if(index < UART_CMD_BUF_SIZE) index++;
-	}while(answer == HAL_OK);
+#ifdef ENABLE_FAST_COMM
+		BmTmpConfig = BM_CONFIG5_ESCAPE1;
+#else
+		BmTmpConfig = BM_CONFIG_DONE;	/* Configuration is stored in BT module => no configuration needed */
+#endif
+	}
+	else
+	{
+		BmTmpConfig = BM_CONFIG_ECHO;
+	}
 }
 
 uint8_t tComm_HandleBlueModConfig()
 {
 	static uint8_t RestartModule = 1; 		/* used to do power off / on cycle */
 	static uint8_t ConfigRetryCnt = 0;		/* Retry count without power cycle */
+	static uint32_t cmdTick = 0;
+#ifdef ENABLE_FAST_COMM
+	static uint32_t configTick = 0;
+#endif
 
 	char TxBuffer[UART_CMD_BUF_SIZE];
 	uint8_t CmdSize = 0;
 
 	uint8_t result = HAL_OK;
 
-	memset(TxBuffer, 0, sizeof(TxBuffer));
-
-	switch (BmTmpConfig)
+	if(time_elapsed_ms(cmdTick, HAL_GetTick()) > 100)	/* do config in 100ms steps */
 	{
-		case BM_CONFIG_ECHO: 			tComm_GetBTCmdStr (BT_CMD_ECHO, TxBuffer);
-			break;
-		case BM_CONFIG_SILENCE:			tComm_GetBTCmdStr (BT_CMD_SILENCE, TxBuffer);
-			break;
-		case BM_CONFIG_ESCAPE_DELAY:	tComm_GetBTCmdStr (BT_CMD_ESCAPE_DELAY, TxBuffer);
-			break;
-		case BM_CONFIG_SIGNAL_POLL:		tComm_GetBTCmdStr(BT_CMD_SIGNAL_POLL, TxBuffer);
-			break;
-		case BM_CONFIG_BAUD:
-#ifdef ENABLE_FAST_COMM
-										tComm_GetBTCmdStr(BT_CMD_BAUDRATE_460, TxBuffer);
-#else
-										BmTmpConfig = BM_CONFIG_DONE;
-#endif
-			break;
-		case BM_CONFIG_RETRY:			ConfigRetryCnt--;
-										HAL_Delay(1);
-										if(ConfigRetryCnt == 0)
+		cmdTick = HAL_GetTick();
+		memset(TxBuffer, 0, sizeof(TxBuffer));
+
+		switch (BmTmpConfig)
+		{
+			case BM_CONFIG_ECHO: 			tComm_GetBTCmdStr (BT_CMD_ECHO, TxBuffer);
+				break;
+			case BM_CONFIG_SILENCE:			tComm_GetBTCmdStr (BT_CMD_SILENCE, TxBuffer);
+				break;
+			case BM_CONFIG_ESCAPE_DELAY:	tComm_GetBTCmdStr (BT_CMD_ESCAPE_DELAY, TxBuffer);
+				break;
+			case BM_CONFIG_SIGNAL_POLL:		tComm_GetBTCmdStr(BT_CMD_SIGNAL_POLL, TxBuffer);
+				break;
+			case BM_CONFIG_BAUD:
+	#ifdef ENABLE_FAST_COMM
+											tComm_GetBTCmdStr(BT_CMD_BAUDRATE_460, TxBuffer);
+	#else
+											BmTmpConfig = BM_CONFIG_DONE;
+	#endif
+				break;
+			case BM_CONFIG_RETRY:			ConfigRetryCnt--;
+											HAL_Delay(1);
+											if(ConfigRetryCnt == 0)
+											{
+												MX_Bluetooth_PowerOn();
+												tComm_StartBlueModConfig();
+											}
+				break;
+			case BM_CONFIG_DONE:
+			case BM_CONFIG_OFF:
+				ConfigRetryCnt = 0;
+				RestartModule = 1;
+				break;
+
+			case BM_CONFIG5_ESCAPE1:	configTick = HAL_GetTick();
+										BmTmpConfig++;
+				break;
+			case BM_CONFIG5_ESCAPE2:	if(time_elapsed_ms(configTick, HAL_GetTick()) > 2600)
 										{
-											MX_Bluetooth_PowerOn();
-											tComm_StartBlueModConfig();
+											configTick = HAL_GetTick();
+											HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_SET);
+											BmTmpConfig++;
 										}
-			break;
-		case BM_CONFIG_DONE:
-		case BM_CONFIG_OFF:
-			ConfigRetryCnt = 0;
-			RestartModule = 1;
-			break;
-#ifdef BOOTLOADER_STANDALONE		/* the procedure below is just needed for the initial bluetooth module initialization */
-		case BM_INIT_TRIGGER_ON:	HAL_Delay(2000);
-									HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
-									BmTmpConfig++;
-								break;
-		case BM_INIT_TRIGGER_OFF:	HAL_Delay(1);
-									HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_SET);
-									HAL_Delay(2000);
-									BmTmpConfig++;
-								break;
-		case BM_INIT_ECHO: 			sprintf(TxBuffer,"ATE0\r");
-			break;
-		case BM_INIT_FACTORY:		sprintf(TxBuffer,"AT+UFACTORY\r");      /*Set to factory defined configuration */
-								break;
-		case BM_INIT_MODE:			sprintf(TxBuffer,"AT+UMSM=1\r");        /* start in Data mode */
-								break;
-		case BM_INIT_BLE:			sprintf(TxBuffer,"AT+UBTLE=2\r"); 		/* Bluetooth low energy Peripheral */
-								break;
-		case BM_INIT_NAME:			sprintf(TxBuffer,"AT+UBTLN=OSTC5-12345\r"); /* Bluetooth name */
-									if(hardwareDataGetPointer()->primarySerial != 0xFFFF) /* module reinit? => restore old name */
-									{
-										gfx_number_to_string(5,1,&TxBuffer[15],hardwareDataGetPointer()->primarySerial);
-									}
-								break;
-		case BM_INIT_SSP_IDO_OFF:	sprintf(TxBuffer,"AT+UDSC=0,0\r");    /* Disable SPP Server on ID0 */
-								break;
-		case BM_INIT_SSP_IDO_ON:	sprintf(TxBuffer,"AT+UDSC=0,3\r"); 	  /* SPP Server on ID0 */
-								break;
-		case BM_INIT_SSP_ID1_OFF:	sprintf(TxBuffer,"AT+UDSC=1,0\r");    /* Disable SPS Server on ID1 */
-								break;
-		case BM_INIT_SSP_ID1_ON:	sprintf(TxBuffer,"AT+UDSC=1,6\r");	  /* SPS Server on ID1 */
-								break;
-		case BM_INIT_STORE:			sprintf(TxBuffer,"AT&W\r");	          /* write settings into eeprom */
-								break;
-		case BM_INIT_RESTART:		sprintf(TxBuffer,"AT+CPWROFF\r");	  /* reboot module */
-								break;
-		case BM_INIT_DONE:			BmTmpConfig = BM_CONFIG_ECHO;
-								break;
-#endif
-		default:
-			break;
-	}
-	if(TxBuffer[0] != 0)		/* forward command to module */
-	{
-		CmdSize = strlen(TxBuffer);
-		if(HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 2000) == HAL_OK)
+				break;
+			case BM_CONFIG5_BAUD:		if(time_elapsed_ms(configTick, HAL_GetTick()) > 1100)
+										{
+											tComm_GetBTCmdStr(BT_CMD_BAUDRATE_460, TxBuffer);
+										}
+				break;
+			case BM_CONFIG5_DATAMODE:	tComm_GetBTCmdStr(BT_CMD_EXIT_CMD, TxBuffer);
+				break;
+
+			default:
+				break;
+		}
+		if(TxBuffer[0] != 0)		/* forward command to module */
 		{
-			result = tComm_CheckAnswerOK();
-
-			if((BmTmpConfig == BM_CONFIG_BAUD) && (result == HAL_OK) && (UartHandle.Init.BaudRate != 460800)) /* is com already switched to fast speed? */
-			{
-				HAL_UART_DeInit(&UartHandle);
-				HAL_Delay(1);
-				UartHandle.Init.BaudRate   = 460800;
-				HAL_UART_Init(&UartHandle);
-			}
-			else if((BmTmpConfig == BM_CONFIG_BAUD) && (result == HAL_OK) && (UartHandle.Init.BaudRate == 460800)) /* This shut not happen because default speed is 115200 => update module configuration */
-			{
-				tComm_GetBTCmdStr(BT_CMD_BAUDRATE_115, TxBuffer);
-
-				CmdSize = strlen(TxBuffer);
-				HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 2000);
-				HAL_UART_DeInit(&UartHandle);
-				HAL_Delay(10);
-				UartHandle.Init.BaudRate   = 115200;
-				HAL_UART_Init(&UartHandle);
-				sprintf(TxBuffer,"AT&W\r");		/* write configuration */
-				CmdSize = strlen(TxBuffer);
-				HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 2000);
-			}
+			CmdSize = strlen(TxBuffer);
+			result = HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 500);
 			if(result == HAL_OK)
 			{
-				BmTmpConfig++;
-				if(BmTmpConfig == BM_CONFIG_RETRY)
-				{
-					BmTmpConfig = BM_CONFIG_DONE;
-				}
-			}
-			if(BmTmpConfig == BM_CONFIG_ECHO)
-			{
-				BmTmpConfig = BM_CONFIG_DONE;
-				ConfigRetryCnt = 0;
-				RestartModule = 1;
-			}
-		}
-	}
-	else		/* no command for the configuration step found => skip step */
-	{
-		if((BmTmpConfig > BM_CONFIG_OFF) && (BmTmpConfig < BM_CONFIG_DONE))
-		{
-			BmTmpConfig++;
-		}
-	}
-	if(result != HAL_OK)
-	{
-		ConfigRetryCnt++;
-		if(ConfigRetryCnt > 3)		/* Configuration failed => switch off module */
-		{
-			MX_Bluetooth_PowerOff();
-			if(RestartModule)
-			{
-				RestartModule = 0;      /* only one try */
-				ConfigRetryCnt = 200;	/* used for delay to startup module again */
+				result = tComm_CheckAnswerOK();
 
-				if((BmTmpConfig == BM_CONFIG_ECHO) || (BmTmpConfig == BM_INIT_ECHO))	/* the module did not answer even once => try again with alternative baud rate */
+				if(((BmTmpConfig == BM_CONFIG_BAUD) || (BmTmpConfig == BM_CONFIG5_BAUD)) && (result == HAL_OK) && (UartHandle.Init.BaudRate != 460800)) /* is com already switched to fast speed? */
 				{
 					HAL_UART_DeInit(&UartHandle);
 					HAL_Delay(1);
 					UartHandle.Init.BaudRate   = 460800;
 					HAL_UART_Init(&UartHandle);
 				}
-				BmTmpConfig = BM_CONFIG_RETRY;
+				else if((BmTmpConfig == BM_CONFIG_BAUD) && (result == HAL_OK) && (UartHandle.Init.BaudRate == 460800)) /* This shut not happen because default speed is 115200 => update module configuration */
+				{
+					tComm_GetBTCmdStr(BT_CMD_BAUDRATE_115, TxBuffer);
+
+					CmdSize = strlen(TxBuffer);
+					HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 2000);
+					HAL_UART_DeInit(&UartHandle);
+					HAL_Delay(10);
+					UartHandle.Init.BaudRate   = 115200;
+					HAL_UART_Init(&UartHandle);
+					sprintf(TxBuffer,"AT&W\r");		/* write configuration */
+					CmdSize = strlen(TxBuffer);
+					HAL_UART_Transmit(&UartHandle, (uint8_t*)TxBuffer,CmdSize, 2000);
+				}
+				if(result == HAL_OK)
+				{
+					if((BmTmpConfig != BM_CONFIG5_DATAMODE) && (BmTmpConfig != BM_CONFIG_DONE))
+					{
+						BmTmpConfig++;
+					}
+					else
+					{
+						HAL_GPIO_WritePin(BLE_UBLOX_DSR_GPIO_PORT,BLE_UBLOX_DSR_PIN,GPIO_PIN_RESET);
+						BmTmpConfig = BM_CONFIG_DONE;
+					}
+				}
 			}
-			else						/* even restarting module failed => switch bluetooth off */
+		}
+		else		/* no command for the configuration step found => skip step */
+		{
+			if((BmTmpConfig > BM_CONFIG_OFF) && (BmTmpConfig < BM_CONFIG_DONE))
 			{
-				ConfigRetryCnt = 0;
-				BmTmpConfig = BM_CONFIG_OFF;
-				settingsGetPointer()->bluetoothActive = 0;
+				BmTmpConfig++;
+			}
+		}
+		if(result != HAL_OK)
+		{
+			ConfigRetryCnt++;
+			if(ConfigRetryCnt > 3)		/* Configuration failed => switch off module */
+			{
+				MX_Bluetooth_PowerOff();
+				if(RestartModule)
+				{
+					RestartModule = 0;      /* only one try */
+					ConfigRetryCnt = 200;	/* used for delay to startup module again */
+
+					if((BmTmpConfig == BM_CONFIG_ECHO) || (BmTmpConfig == BM_INIT_ECHO))	/* the module did not answer even once => try again with alternative baud rate */
+					{
+						HAL_UART_DeInit(&UartHandle);
+						HAL_Delay(1);
+						UartHandle.Init.BaudRate   = 460800;
+						HAL_UART_Init(&UartHandle);
+					}
+					BmTmpConfig = BM_CONFIG_RETRY;
+				}
+				else						/* even restarting module failed => switch bluetooth off */
+				{
+					ConfigRetryCnt = 0;
+					BmTmpConfig = BM_CONFIG_OFF;
+					settingsGetPointer()->bluetoothActive = 0;
+				}
 			}
 		}
 	}
--- a/Discovery/Src/tDebug.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tDebug.c	Sat Nov 15 19:29:44 2025 +0100
@@ -58,9 +58,12 @@
 
 void exitDebugMode(void)
 {
-    MX_Bluetooth_PowerOff();
-    settingsGetPointer()->debugModeOnStart = 0;
-    tD_debugModeActive = 0;
+	if(tD_debugModeActive)
+	{
+		MX_Bluetooth_PowerOff();
+		settingsGetPointer()->debugModeOnStart = 0;
+		tD_debugModeActive = 0;
+	}
 }
 
 
--- a/Discovery/Src/tHome.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tHome.c	Sat Nov 15 19:29:44 2025 +0100
@@ -59,7 +59,13 @@
 static uint16_t tHome_tick_count_field;
 static uint16_t tHome_tick_count_o2sens;
 
-const uint8_t cv_changelist[] = {CVIEW_Compass, CVIEW_SummaryOfLeftCorner, CVIEW_Tissues, CVIEW_Profile, CVIEW_EADTime, CVIEW_Gaslist, CVIEW_noneOrDebug, CVIEW_Decolist, CVIEW_sensors,CVIEW_sensors_mV, CVIEW_Timer, CVIEW_END};
+const uint8_t cv_changelist[] = {CVIEW_Compass, CVIEW_SummaryOfLeftCorner, CVIEW_Tissues,
+								 CVIEW_Profile, CVIEW_EADTime, CVIEW_Gaslist, CVIEW_noneOrDebug,
+								 CVIEW_Decolist, CVIEW_sensors,CVIEW_sensors_mV, CVIEW_Timer,
+#ifdef ENABLE_LOGGER_WINDOW
+	CVIEW_Logger,
+#endif
+								 CVIEW_END};
 const uint8_t cv_changelist_BS[] = {CVIEW_T3_Decostop, CVIEW_sensors, CVIEW_Compass, CVIEW_T3_MaxDepth,CVIEW_T3_StopWatch, CVIEW_T3_TTS, CVIEW_T3_GasList, CVIEW_T3_ppO2andGas, CVIEW_noneOrDebug,
 									CVIEW_T3_Navigation, CVIEW_T3_DepthData, CVIEW_T3_DecoTTS,
 #ifdef ENABLE_T3_PROFILE_VIEW
--- a/Discovery/Src/tInfo.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tInfo.c	Sat Nov 15 19:29:44 2025 +0100
@@ -38,6 +38,7 @@
 #include "tInfoCompass.h"
 #include "tInfoSensor.h"
 #include "tInfoPreDive.h"
+#include "tInfoLogger.h"
 #include "tMenu.h"
 #include "tMenuEdit.h"
 
@@ -227,6 +228,12 @@
     							infoColor = CLUT_MenuPageGasCC;
     							refreshInfo_PreDive(tIscreen);
     				break;
+#ifdef ENABLE_LOGGER_WINDOW
+    		case StILOGGER: 	tIscreen.FBStartAdress = getFrame(14);
+    							infoColor = CLUT_MenuPageCvOption;
+    							refreshInfo_Logger(tIscreen);
+    				break;
+#endif
 
     		default:
     				break;
@@ -256,6 +263,11 @@
     exitMenuEdit_to_BackMenu();
 }
 
+void exitInfoSilent(void)	/* no changes were done on info screen => just free buffer */
+{
+    releaseFrame(14,tIscreen.FBStartAdress);
+    updateMenu();
+}
 
 void sendActionToInfo(uint8_t sendAction)
 {
@@ -298,6 +310,32 @@
 
 }
 
+
+void tInfo_drawPixel(int16_t x, int16_t y, uint8_t color)
+{
+	int8_t xoff;
+	int8_t yoff;
+
+	for (xoff = -1; xoff < 2; xoff++)
+	{
+		for (yoff = -1; yoff < 2; yoff++)
+		{
+			GFX_draw_pixel(&tIscreen, x + xoff, y + yoff, color);
+		}
+	}
+	GFX_draw_pixel(&tIscreen, x, y, color);
+}
+
+void tInfo_draw_colorline(point_t start, point_t stop, uint8_t color)
+{
+	GFX_draw_colorline(&tIscreen, start, stop, color);
+}
+
+void t_Info_draw_circle(point_t center, uint8_t radius, int8_t color)
+{
+	GFX_draw_circle(&tIscreen, center, radius, color);
+}
+
 void tInfo_write_content_simple(uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle,  const tFont *Font, const char *text, uint8_t color)
 {
     GFX_DrawCfgWindow	hgfx;
--- a/Discovery/Src/tInfoCompass.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tInfoCompass.c	Sat Nov 15 19:29:44 2025 +0100
@@ -28,34 +28,77 @@
 
 /* Includes ------------------------------------------------------------------*/
 
-#include "gfx_engine.h"
+
 #include "gfx_fonts.h"
 #include "tHome.h"
 #include "tInfo.h"
 #include "tInfoCompass.h"
 
 #include <string.h>
+#include <math.h>
+
+#define PI 3.14159265358979323846
+
+#define PITCH 	(0)
+#define ROLL	(1)
+#define YAW 	(2)
 
 /* Private variables ---------------------------------------------------------*/
 
-uint16_t tInfoCompassTimeout = 0;
-int16_t minMaxCompassDX[3][2] = { 0 };
+static uint16_t tInfoCompassTimeout = 0;
+static int16_t minMaxCompassDX[3][2] = { 0 };
+
+static axisIndicator_t axis[3];
+static uint8_t activeAxis = PITCH;
+static uint32_t checkTick = 0;
 
 /* Exported functions --------------------------------------------------------*/
 void openInfo_Compass(void)
 {
+	uint16_t angle = 0;
+	uint8_t axisIndex = 0;
     set_globalState(StICOMPASS);
     tInfoCompassTimeout = settingsGetPointer()->timeoutInfoCompass;
     tInfoCompassTimeout *= 10;
 
+    for(axisIndex = 0; axisIndex < 3; axisIndex++)
+    {
+    	memset(axis[axisIndex].check,0, 360);
+    }
+    for(angle = 170; angle < 360; angle++)
+    {
+       	axis[PITCH].check[angle] = 1;	/* pitch only from -90 to +90 */
+    }
+    axis[YAW].coord.x = 100;
+    axis[YAW].coord.y = 70;
+    axis[PITCH].coord.x = 100;
+    axis[PITCH].coord.y = 300;
+    axis[ROLL].coord.x = 100;
+    axis[ROLL].coord.y = 200;
+
+    axis[YAW].eclipse.x = 50;
+    axis[YAW].eclipse.y = 50;
+    axis[PITCH].eclipse.x = 20;
+    axis[PITCH].eclipse.y = 50;
+    axis[ROLL].eclipse.x = 50;
+    axis[ROLL].eclipse.y = 20;
+
     for(int i = 0; i<3;i ++)
     {
             minMaxCompassDX[i][0] = 999;
             minMaxCompassDX[i][1] = -999;
     }
+    checkTick = HAL_GetTick();
+
+    activeAxis = PITCH;
 }
 
-
+void getElipsePoint(uint16_t elipseX , int16_t elipseY, int16_t degree, int16_t *x, int16_t *y)
+{
+    double rad = degree * (PI / 180.0);
+    *x = (int16_t) (elipseX * cos(rad));
+    *y = (int16_t) (elipseY * sin(rad));
+}
 //  ===============================================================================
 //	refreshInfo_Compass
 /// @brief	there is only compass_DX_f, compass_DY_f, compass_DZ_f output during this mode
@@ -63,6 +106,20 @@
 //  ===============================================================================
 void refreshInfo_Compass(GFX_DrawCfgScreen s)
 {
+	static int16_t cursorAngle = 0;
+
+	int16_t angle = 0.0;
+	int16_t drawX = 0;
+	int16_t drawY = 0;
+	uint8_t color = 0;
+	point_t start;
+	point_t stop;
+	point_t center;
+
+	int8_t offset = 0;
+	uint8_t axisIndex = 0;
+	int16_t index = 0;
+	uint8_t textIndex = 0;
 
 	tHome_show_lost_connection_count(&s);
     tInfoCompassTimeout--;
@@ -80,6 +137,106 @@
     compassValues[1] = stateUsed->lifeData.compass_DY_f;
     compassValues[2] = stateUsed->lifeData.compass_DZ_f;
 
+   /* draw indicator */
+    for(axisIndex = 0; axisIndex < 3; axisIndex++)
+    {
+    	switch(axisIndex)
+    	{
+    		default:
+    		case YAW:	index = (uint16_t)(stateUsed->lifeData.compass_heading);
+    					textIndex = snprintf(text,80,"yaw %.1f", stateUsed->lifeData.compass_heading);
+
+    					if((tInfoCompassTimeout < 50) && (activeAxis == YAW))
+    					{
+    						snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[YAW][0], minMaxCompassDX[YAW][1]);
+    					}
+
+    					start.x = axis[axisIndex].coord.x - 1;
+    		    	    start.y = axis[axisIndex].coord.y;
+    		    	    stop.x = axis[axisIndex].coord.x + 1;
+    		    	    stop.y = axis[axisIndex].coord.y;
+    			break;
+    		case PITCH:	index = (uint16_t)(stateUsed->lifeData.compass_pitch + 90);
+    					textIndex = snprintf(text,80,"pitch %.1f", stateUsed->lifeData.compass_pitch);
+    					if((tInfoCompassTimeout < 50) && (activeAxis == YAW))
+    					{
+    						snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[PITCH][0], minMaxCompassDX[PITCH][1]);
+    					}
+    					start.x = axis[axisIndex].coord.x - 30;
+    					start.y = axis[axisIndex].coord.y;
+    					stop.x = axis[axisIndex].coord.x + 30;
+    					stop.y = axis[axisIndex].coord.y;
+
+    			break;
+    		case ROLL: index = (uint16_t)(stateUsed->lifeData.compass_roll + 180);
+    					textIndex = snprintf(text,80,"roll %.1f", stateUsed->lifeData.compass_roll);
+    					if((tInfoCompassTimeout < 50) && (activeAxis == YAW))
+    					{
+    						snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[ROLL][0], minMaxCompassDX[ROLL][1]);
+    					}
+    					start.x = axis[axisIndex].coord.x;
+    					start.y = axis[axisIndex].coord.y - 30;
+    					stop.x = axis[axisIndex].coord.x;
+    					stop.y = axis[axisIndex].coord.y +30;
+    			break;
+    	}
+		if(settingsGetPointer()->FlipDisplay)
+		{
+			start.x = 800 - start.x;
+			stop.x = 800 - stop.x;
+			start.y = 480 - start.y;
+			stop.y = 480 - stop.y;
+		}
+    	if(activeAxis == axisIndex)			/* only check one axis at a time. reason: yaw will be unstable at the beginning of calibration */
+    	{
+    		for(offset = -6; offset <= 6; offset++)	/* it is hard to hit every single angle and the resolution is not needed */
+    		{
+				if(( (index + offset) >= 0) && (index + offset < 360))
+				{
+					axis[axisIndex].check[index + offset] = 1;							/* => check surrounding angles as well */
+				}
+    		}
+    	}
+    	if(axisIndex == activeAxis)
+    	{
+    		color = CLUT_InfoCompass;
+    		getElipsePoint(axis[axisIndex].eclipse.x,axis[axisIndex].eclipse.y,cursorAngle, &drawX, &drawY);
+    		center.x = axis[axisIndex].coord.x + drawX;
+    		center.y = axis[axisIndex].coord.y + drawY;
+
+    		t_Info_draw_circle(center, 4, CLUT_Font020);
+    		cursorAngle += 15;
+    		if(cursorAngle >= 360)
+    		{
+    			cursorAngle = 0;
+    		}
+    	}
+    	else
+    	{
+    		color = CLUT_Font021;
+    	}
+    	tInfo_write_content_simple(  200, 600, 480 - axis[axisIndex].coord.y - 35 , &FontT42, text, color);
+  	    tInfo_draw_colorline(start, stop, CLUT_Font020);
+  	    for(angle = 0; angle < 360; angle = angle + 3)
+  	    {
+  	    	if(axis[axisIndex].check[angle])
+  	    	{
+  	    		color = CLUT_NiceGreen;
+  	    	}
+  	    	else
+  	    	{
+  	    		color = CLUT_WarningRed;
+  	    	}
+  	    	getElipsePoint(axis[axisIndex].eclipse.x,axis[axisIndex].eclipse.y,angle, &drawX, &drawY);
+  	    	tInfo_drawPixel(axis[axisIndex].coord.x + drawX, axis[axisIndex].coord.y + drawY,color);
+  	    	if((axisIndex == PITCH) && (angle == 180))		/* pitch only from -90 to +90 */
+  	    	{
+  	    		break;
+  	    	}
+  	    }
+
+    }
+
     for(int i = 0; i<3;i ++)
     {
         // do not accept zero
@@ -100,18 +257,33 @@
     snprintf(text,80,"Time left: %u s",(tInfoCompassTimeout+9)/10);
     tInfo_write_content_simple(  20,800,  25, &FontT42, text, CLUT_InfoCompass);
 
-    for(int i = 0; i<3;i ++)
+
+    if(time_elapsed_ms(checkTick, HAL_GetTick() > 1000))
     {
-        snprintf(text,80,"%c: %i" "\t(%i, %i)",
-            'X'+i,
-            compassValues[i],
-            minMaxCompassDX[i][0],
-            minMaxCompassDX[i][1]);
-        tInfo_write_content_simple(  20,800, 96 + (i*96), &FontT48, text, CLUT_InfoCompass);
+    	index = 0;
+    	 for(angle = 0; angle < 360; angle++)
+    	 {
+    		 if(axis[activeAxis].check[angle])
+    		 {
+    			 index++;
+    		 }
+    	 }
+    	 if(index > 350)
+    	 {
+    		 if(activeAxis < 2)
+    		 {
+    			 activeAxis++;
+    		 }
+    		 else
+    		 {
+    			 if(tInfoCompassTimeout > 50)
+    			 {
+    				 tInfoCompassTimeout = 50;	/* reduce exit time to five seconds */
+    			 }
+    		 }
+    	 }
+
+
+    	checkTick = HAL_GetTick();
     }
-
-    snprintf(text,80,"roll %.1f" "\tpitch %.1f",
-        stateUsed->lifeData.compass_roll,
-        stateUsed->lifeData.compass_pitch);
-    tInfo_write_content_simple(  20,800, 96 * 4, &FontT42, text, CLUT_InfoCompass);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/tInfoLogger.c	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,170 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Src/tInfoLogger.c
+/// \brief  Show data which is received / send through UART interface
+/// \author heinrichs weikamp gmbh
+/// \date   23-Feb-2015
+///
+/// \details
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "gfx_engine.h"
+#include "gfx_fonts.h"
+#include "tHome.h"
+#include "tInfo.h"
+#include "tInfoLogger.h"
+#include "tMenuEdit.h"
+#include "data_exchange_main.h"
+#include "t7.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+
+/* Private variables ---------------------------------------------------------*/
+static uint8_t lines[MAX_LOGGER_LINES][MAX_CHAR_PER_LINE + LINE_HEADER_BYTES];
+static uint8_t lineWriteIndex = 0;
+static uint8_t lineReadIndex = 0;
+static uint32_t receivedLinesCount = 0;
+
+static uint32_t loggerUpdateTime = 0;
+static uint32_t previousGlobalState = 0;
+
+/* Exported functions --------------------------------------------------------*/
+
+
+void InfoLogger_writeLine(uint8_t* pLine,uint8_t lineLength,uint8_t direction)
+{
+#ifdef ENABLE_LOGGER_WINDOW
+	uint8_t LogIndex = 0;
+
+	if(!t7_customview_disabled(CVIEW_Logger))
+	{
+		if(lineLength <= MAX_CHAR_PER_LINE)
+		{
+			memset(&lines[lineWriteIndex][0],0, (MAX_CHAR_PER_LINE + LINE_HEADER_BYTES));
+			if(direction == LOG_TX_LINE)
+			{
+				lines[lineWriteIndex][LogIndex] = '\002';	/* align right */
+				LogIndex++;
+			}
+			memcpy(&lines[lineWriteIndex][LogIndex],pLine,lineLength);
+			lineWriteIndex++;
+			if(lineWriteIndex == MAX_LOGGER_LINES)
+			{
+				lineWriteIndex = 0;
+			}
+			receivedLinesCount++;
+		}
+	}
+#endif
+}
+
+uint8_t InfoLogger_isUpdated()
+{
+	uint8_t ret = 0;
+	if(lineReadIndex != lineWriteIndex)
+	{
+		ret = 1;
+	}
+	return ret;
+}
+
+void openInfo_Logger()
+{
+	previousGlobalState = get_globalState();
+	set_globalState(StILOGGER);
+
+	loggerUpdateTime = HAL_GetTick();
+}
+
+void refreshInfo_Logger(GFX_DrawCfgScreen s)
+{
+	uint8_t index = 0;
+    char text[31];
+    uint8_t displayLine = 0;
+    uint8_t color = CLUT_Font020;
+
+	sprintf(text,"\001%c%c", TXT_2BYTE, TXT2BYTE_Logger);
+
+	tInfo_write_content_simple(  30, 770, ME_Y_LINE_BASE, &FontT48, text, CLUT_InfoSurface);
+
+
+	if(InfoLogger_isUpdated())
+	{
+		loggerUpdateTime = HAL_GetTick();
+	}
+	if(receivedLinesCount > MAX_LOGGER_LINES)
+	{
+		displayLine = MAX_LOGGER_LINES-1;
+	}
+	else
+	{
+		displayLine = lineWriteIndex;
+	}
+
+	if(lineReadIndex != lineWriteIndex)			/* needed for isUpdated function */
+	{
+		lineReadIndex++;
+		if(lineReadIndex == MAX_LOGGER_LINES)
+		{
+			lineReadIndex = 0;
+		}
+	}
+	while (index < displayLine)
+	{
+		color = CLUT_Font020;
+		if(lines[index][0] == '\002')
+		{
+			color = CLUT_NiceGreen;
+		}
+		if(lineReadIndex == index)
+		{
+			color = CLUT_NiceBlue;
+		}
+		tInfo_write_content_simple(  30, 770, 60 + (index * 30), &FontT24, (char*)lines[index], color);
+
+		if(lineReadIndex != lineWriteIndex)			/* needed for isUpdated function */
+		{
+			lineReadIndex++;
+			if(lineReadIndex == MAX_LOGGER_LINES)
+			{
+				lineReadIndex = 0;
+			}
+		}
+		index++;
+	}
+	if((time_elapsed_ms(loggerUpdateTime, HAL_GetTick()) > 10000))
+	{
+		set_globalState(previousGlobalState); /* restore state which was active before log data was received */
+		exitInfo();
+	}
+}
+
+void sendActionToInfoLogger(uint8_t sendAction)
+{
+/* TODO: at the moment a generic return to home is used because the logger window could be opened from everywhere => implement context based return from view */
+    set_globalState(previousGlobalState); /* restore state which was active before log data was received */
+    exitInfoSilent();
+}
+
--- a/Discovery/Src/tInfoPreDive.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tInfoPreDive.c	Sat Nov 15 19:29:44 2025 +0100
@@ -70,7 +70,7 @@
 	}
 	else
 	{
-		memcpy (&pressureHistory[0],&pressureHistory[2],sizeof(pressureHistory) - 2);
+		memmove(&pressureHistory[0], &pressureHistory[2], sizeof(pressureHistory) - 2);
 		pressureHistory[pressureHistoryIndex] = newValue;
 	}
 }
@@ -87,7 +87,7 @@
 	}
 	else
 	{
-		memcpy (&temperatureHistory[0],&temperatureHistory[2],sizeof(temperatureHistory) - 2);
+		memmove(&temperatureHistory[0], &temperatureHistory[2], sizeof(temperatureHistory) - 2);
 		temperatureHistory[temperatureHistoryIndex] = newValue;
 	}
 }
--- a/Discovery/Src/tMenu.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenu.c	Sat Nov 15 19:29:44 2025 +0100
@@ -42,6 +42,7 @@
 #include "tMenuEditSystem.h"
 #include "tMenuEditXtra.h"
 #include "tMenuEditCustom.h"
+#include "tMenuEditCvOption.h"
 #include "tMenuGas.h"
 #include "tMenuHardware.h"
 #include "tMenuPlanner.h"
@@ -51,13 +52,16 @@
 #include "tMenuCustom.h"
 
 /* Private types -------------------------------------------------------------*/
-#define MAXPAGES 		11
+#define MAXPAGES 		12
 #define CURSOR_HIGH 	25
 #define TAB_HEADER_HIGH	25
 #define TAB_BAR_HIGH	5
 #define MENU_WDW_HIGH	390
 #define KEY_LABEL_HIGH	25	/* Height of the label used for the the user keys */
 
+#define TAB_BAR_WIDTH	50
+#define TAB_BAR_SPACING	5
+
 #define SLOW_UPDATE_CNT	10	/* Some content shall not be update in short intervals => add prescalar */
 #define MAXLINES	6
 
@@ -580,6 +584,7 @@
         tM_add(StMDECO);
         tM_add(StMHARD);
         tM_add(StMCustom);
+        tM_add(StMOption);
 //		tM_add(StMSYS); now in both modes
     }
     else
@@ -649,6 +654,9 @@
 
     id = tMCustom_refresh(0, text, &tabPosition, subtext);
     tM_build_page(id, text, tabPosition, subtext);
+
+    id = tMCvOption_refresh(0, text, &tabPosition, subtext);
+    tM_build_page(id, text, tabPosition, subtext);
 }
 
 
@@ -789,7 +797,7 @@
         update_content_with_new_frame(page, text, tabPosition, subtext);
         break;
     case StMDECO:
-        if((line == 1) || (line == 3)) // dive mode or ppO2 limits (the later for correct MOD in gaslists)
+        if((line == get_lineOfID(StMDECO1_OC)) || (line == get_lineOfID(StMDECO3_PPO2Max))) // dive mode or ppO2 limits (the later for correct MOD in gaslists)
         {
             tM_rebuild_pages();
             menu.lineMemoryForNavigationForPage[page] = line; // fix 160623
@@ -818,7 +826,12 @@
         update_content_actual_page(text, tabPosition, subtext);
         break;
     case StMSYS:
-        if((line == 2) || (line == 3) || (line == 6))
+        if((line == get_lineOfID(StMSYS1_DateTime)) || (line == get_lineOfID(StMSYS2_English))
+#ifdef ENABLE_SETTING_PROFILES
+        		|| (line == get_lineOfID(StMSYS_Profile)))
+#else
+        	)
+#endif
         {
             tM_rebuild_pages();
             menu.lineMemoryForNavigationForPage[page] = line; // fix 160623
@@ -837,6 +850,11 @@
     	    clean_line_actual_page();
         	update_content_actual_page(text, tabPosition, subtext);
         break;
+    case StMOption:
+    	 	 	 tMCvOption_refresh(line, text, &tabPosition, subtext);
+    	         clean_line_actual_page();
+    	         update_content_actual_page(text, tabPosition, subtext);
+    	break;
     default:
         break;
     }
@@ -864,7 +882,10 @@
     if((page == 0) || (line == 0))
         return;
 
-    requestBuzzerActivation(0);
+    if( getBuzzerActivationRequest() != REQUEST_BUZZER_ONCE)
+    {
+    	requestBuzzerActivation(REQUEST_BUZZER_OFF);
+    }
 
     menu.pageMemoryForNavigation = page;
     /* new test for 3button design */
@@ -947,7 +968,7 @@
 {
 	switch(get_globalState())
 	{
-		case StMSYS: tMSystem_checkLineStatus();
+		case StMOption: tMCvOption_checkLineStatus();
 			break;
 		case StMXTRA: tMXtra_checkLineStatus();
 			break;
@@ -1150,6 +1171,9 @@
     case StMCustom:
     	openEdit_Custom(line);
     	break;
+    case StMOption:
+    	openEdit_CvOption(line);
+    	break;
     default:
         break;
     }
@@ -1347,19 +1371,21 @@
     {   "",
         "OC",
         "CC",
-        "SP",
+        "",
         "DATA",
         "DECO",
         "",
         "SYS",
         "",
 		"",
-        "SIM"
+		"",
+		"SIM",
+        ""
     };
 
     _Bool spacing[MAXPAGES+1] =
     {   0,
-        0, // behind OC
+        1, // behind OC
         0, // behind CC
         1, // behind SP
         1, // behind DATA
@@ -1367,7 +1393,8 @@
         1, // behind DECO2
         0, // behind SYS1
         0, // behind SYS2
-		1, // behind SYS3
+		0, // behind SYS3
+		1, // behind SYS4
         1, // behind SIM
         0
     };
@@ -1375,7 +1402,7 @@
     if(actual_menu_content == MENU_SURFACE)
     {
     	spacing[3] = 0;		/* Display extra menu directly after setpoint */
-    	sprintf(text8max[4],"OP");
+    	memset(text8max[4],0,8);
     }
 
     pBackup = tMscreen.FBStartAdress;
@@ -1386,6 +1413,7 @@
 
     gfx_write_page_number(&tMscreen ,menu.pageCountNumber[page],menu.pageCountTotal,0);
 
+    /* Find the matching master text if a tab has no direct name e.g. SYS subtabs */
     while((text8max[pageText][0] == 0) && (pageText > 1))
     {
         pageText--;
@@ -1427,9 +1455,9 @@
 /* Draw color bars */
             if(!settingsGetPointer()->FlipDisplay)
             {
-				pDestination +=  5 * 480;
+				pDestination +=  TAB_BAR_SPACING * 480;
 
-					for(j = 60; j > 0; j--)
+					for(j = TAB_BAR_WIDTH; j > 0; j--)
 					{
 						pDestination += (390 + 26);
 
@@ -1440,13 +1468,13 @@
 						pDestination += 48;
 					}
 
-					pDestination += 5 * 480;
-					positionText += 70;
+					pDestination += TAB_BAR_SPACING * 480;
+					positionText += TAB_BAR_WIDTH + 2* TAB_BAR_SPACING;
 
 					if(((k == 4) && (actual_menu_content != MENU_SURFACE)) || ((k == 6) && (menu.pageCountNumber[5] == 0)))
 					{
-						pDestination += 70 * 480;
-						positionText += 70;
+						pDestination += (TAB_BAR_WIDTH + 2* TAB_BAR_SPACING) * 480;
+						positionText += TAB_BAR_WIDTH + 2* TAB_BAR_SPACING;
 					}
 
 					if(spacing[k])
@@ -1495,3 +1523,9 @@
 {
     return isGrey ? "\031" : "";
 }
+
+
+char printCheckbox(bool isChecked)
+{
+    return isChecked ? '\005' : '\006';
+}
--- a/Discovery/Src/tMenuCustom.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuCustom.c	Sat Nov 15 19:29:44 2025 +0100
@@ -39,6 +39,7 @@
 #include "gfx_fonts.h"
 #include "tInfo.h"
 #include "motion.h"
+#include "ostc.h"
 
 
 /* Exported functions --------------------------------------------------------*/
@@ -119,24 +120,21 @@
 	textPointer += 2;
 #endif
 
-#ifdef ENABLE_GPIO_V2
     if((line == 0) || (line == 5))
     {
-    /* MotionCtrl */
-		text[textPointer++] = TXT_2BYTE;
-		text[textPointer++] = TXT2BYTE_BUZZER;
-		text[textPointer++] = ' ';
-		text[textPointer++] = TXT_Warning;
-		text[textPointer++] = '\t';
-	    if(settingsGetPointer()->warningBuzzer)
-	            text[textPointer++] = '\005';
-	        else
-	            text[textPointer++] = '\006';
+            text[textPointer++] = TXT_2BYTE;
+            text[textPointer++] = TXT2BYTE_FLIPDISPLAY;
+            text[textPointer++] = '\t';
+            if(settingsGetPointer()->FlipDisplay)
+                text[textPointer++] = '\005';
+            else
+                text[textPointer++] = '\006';
+            text[textPointer] = 0;
+
     }
 
 	strcpy(&text[textPointer],"\n\r");
 	textPointer += 2;
-#endif
 
     return StMCustom;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/tMenuCvOption.c	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Src/tMenuCvOption.c
+/// \brief  Main Template file for Menu Page System settings
+/// \author heinrichs weikamp gmbh
+/// \date   24-Apr-2025
+///
+/// \details
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Includes ------------------------------------------------------------------*/
+#include "tMenu.h"
+#include "tMenuCvOption.h"
+#include "tHome.h"  // for enum CUSTOMVIEWS and init_t7_compass()
+#include "t7.h"
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+uint32_t tMCvOption_refresh(uint8_t line, char *text, uint16_t *tab, char *subtext)
+{
+    SSettings *data;
+    uint8_t textPointer;
+
+    data = settingsGetPointer();
+    textPointer = 0;
+    *tab = 300;
+    *subtext = 0;
+
+    resetLineMask(StMOption);
+
+    if((line == 0) || (line == 1))
+    {
+        text[textPointer++] = TXT_2BYTE;
+        text[textPointer++] = TXT2BYTE_Compass;
+        text[textPointer++] = '\t';
+
+        if(settingsGetPointer()->compassBearing != 0)
+        {
+            textPointer += snprintf(&text[textPointer], 20, "(%03u`)", settingsGetPointer()->compassBearing % 360);
+        }
+        text[textPointer] = 0;
+    }
+    nextline(text,&textPointer);
+    if (line == 0 || line == 2)
+    {
+    	if(t7_customview_disabled(CVIEW_Timer))
+    	{
+    		text[textPointer++] = '\031';		/* change text color */
+    	    textPointer += snprintf(&text[textPointer], 21, "%c%c\t%u:%02u \016\016[m:ss]\017", TXT_2BYTE, TXT2BYTE_Timer, data->timerDurationS / 60, data->timerDurationS % 60);
+            text[textPointer++] = '\020';		/* restore text color */
+    	}
+    	else
+    	{
+    		textPointer += snprintf(&text[textPointer], 21, "%c%c\t%u:%02u \016\016[m:ss]\017", TXT_2BYTE, TXT2BYTE_Timer, data->timerDurationS / 60, data->timerDurationS % 60);
+    	}
+    }
+    nextline(text,&textPointer);
+
+#ifdef ENABLE_PULSE_SENSOR_BT
+    if (line == 0 || line == 3)
+    {
+   		textPointer += snprintf(&text[textPointer], 21, "%c%c", TXT_2BYTE, TXT2BYTE_Pulse);
+    }
+    nextline(text,&textPointer);
+
+#endif
+
+    return StMOption;
+}
+void tMCvOption_checkLineStatus(void)
+{
+	uint8_t localLineMask = 0;
+	uint8_t lineMask = getLineMask(StMOption);
+
+	if(t7_customview_disabled(CVIEW_Timer))
+    {
+    	localLineMask |= 1 << 2;
+    }
+
+	if(lineMask != localLineMask)
+	{
+		updateMenu();
+	}
+}
+
+/* Private functions ---------------------------------------------------------*/
--- a/Discovery/Src/tMenuEdit.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEdit.c	Sat Nov 15 19:29:44 2025 +0100
@@ -42,10 +42,14 @@
 #include "tMenuEditSystem.h"
 #include "tMenuEditXtra.h"
 #include "tMenuEditCustom.h"
+#include "cv_heartbeat.h"
 
 /* Private types -------------------------------------------------------------*/
 #define TEXTSIZE 16
 
+#define IDENT_MAY_INPUT_NUM		4	/* legacy value of ident.input struct */
+#define IDENT_MAX_INPUT_TEXT	9	/* 8 data items + 0 for string operations */
+
 typedef struct
 {
     uint32_t pEventFunction;
@@ -63,9 +67,9 @@
 {
     char orgText[32];
     char newText[32];
-    uint32_t input[4];
+    uint32_t input[IDENT_MAX_INPUT_TEXT];
     uint16_t coord[3];
-    int8_t begin[4], size[4];
+    int8_t begin[IDENT_MAX_INPUT_TEXT], size[IDENT_MAX_INPUT_TEXT];
     tFont *fontUsed;
     uint32_t callerID;
     uint8_t maintype;
@@ -85,6 +89,7 @@
     FIELD_3DIGIT,
     FIELD_SDIGIT,
     FIELD_FLOAT,
+	FIELD_TEXT,
     FIELD_END
 } SField;
 
@@ -229,7 +234,7 @@
 	 	 case (StMHARD3_Sensor_Detect):
 	 	 case (StMHARD3_Sensor_Info):							refreshFct = refresh_O2Sensors;
 	 	 	 break;
-		 case (StMHARD2_Compass & MaskFieldDigit):
+		 case (StMOption_Compass & MaskFieldDigit):
              refreshFct = refresh_CompassEdit;
 			 break;
 		 case (StMXTRA_CompassHeading & MaskFieldDigit):
@@ -256,6 +261,11 @@
 	 	 case StMCustom3_CViewSelection5:
 	 	 case StMCustom3_CViewSelection6: refreshFct = CustomviewDivemode_refresh;
 	 	 	 break;
+#ifdef ENABLE_PULSE_SENSOR_BT
+	 	case (StMOption_Heartbeat):		refreshFct = refresh_Heartbeat;
+	 		break;
+#endif
+
 #ifdef ENABLE_MOTION_CONTROL
 	 	 case (StMCustom5_CViewPortCalib & MaskFieldDigit):
 	 	 case StMCustom5_CViewPortLayout:
@@ -284,7 +294,7 @@
     {
     	reset_SettingWarning();
         GFX_logoAutoOff();
-        ext_flash_write_settings(0);
+        ext_flash_write_settings(EF_SETTINGS,0);
         WriteSettings = 0;
     }
 }
@@ -442,7 +452,7 @@
         return 1;
     }
 
-    if(((block + 1) < 4) && (ident[actualId].size[block+1] > 0))
+    if((((block + 1) < 4) || ((ident[actualId].maintype == FIELD_TEXT) && ((block + 1) < IDENT_MAX_INPUT_TEXT)))  && (ident[actualId].size[block+1] > 0))
     {
         block++;
         subBlockPosition = 0;
@@ -476,7 +486,7 @@
         content += ident[actualId].newText[ident[actualId].begin[block] + 1];
     }
     else
-    if(ident[actualId].maintype == FIELD_NUMBERS)
+    if((ident[actualId].maintype == FIELD_NUMBERS) || (ident[actualId].maintype == FIELD_TEXT))
         content = ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition];
     else
     if((ident[actualId].maintype == FIELD_ON_OFF) || (ident[actualId].maintype == FIELD_TOGGLE))
@@ -495,7 +505,7 @@
     if(event[actualevid].callerID != ident[actualId].callerID)
         return;
 
-    if(ident[actualId].maintype == FIELD_NUMBERS)
+    if((ident[actualId].maintype == FIELD_NUMBERS) || (ident[actualId].maintype == FIELD_TEXT))
     {
         oneCharText[0] = ident[actualId].newText[ident[actualId].begin[oldblock] + oldsubblockpos];
         oneCharText[1] = 0;
@@ -547,18 +557,34 @@
 void mark_new_digit_of_actual_id_block_and_subBlock(void)
 {
     char oneCharText[2];
+    char text[10];
     uint16_t positionOffset;
+    uint8_t index = 0;
+    uint8_t textPos = 0;
 
     if(event[actualevid].callerID != ident[actualId].callerID)
         return;
 
-    if(ident[actualId].maintype == FIELD_NUMBERS)
+    if((ident[actualId].maintype == FIELD_NUMBERS) || (ident[actualId].maintype == FIELD_TEXT))
     {
         oneCharText[0] = ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition];
         oneCharText[1] = 0;
         positionOffset = GFX_return_offset(ident[actualId].fontUsed, ident[actualId].newText, ident[actualId].begin[block] + subBlockPosition);
         write_content( ident[actualId].coord[0] + positionOffset, ident[actualId].coord[1], ident[actualId].coord[2], ident[actualId].fontUsed, oneCharText, CLUT_MenuEditDigit);
     }
+    if(ident[actualId].maintype == FIELD_TEXT)		/* letter width may change from character to character => output end of string */
+    {
+    	if(block + 1 < 8)
+    	{
+			for(index = block + 1; index < 8; index++)
+			{
+				text[textPos++] = ident[actualId].newText[ident[actualId].begin[index] + 0];
+			}
+			text[textPos] = 0;
+		    positionOffset = GFX_return_offset(ident[actualId].fontUsed, ident[actualId].newText, ident[actualId].begin[block + 1] + subBlockPosition);
+			write_content( ident[actualId].coord[0] + positionOffset, ident[actualId].coord[1], ident[actualId].coord[2], ident[actualId].fontUsed, text, CLUT_MenuEditFieldSelected);
+    	}
+    }
 }
 
 
@@ -582,7 +608,7 @@
     block = 0;
     subBlockPosition = 0;
 
-    if(ident[actualId].maintype == FIELD_NUMBERS)
+    if((ident[actualId].maintype == FIELD_NUMBERS) || (ident[actualId].maintype == FIELD_TEXT))
     {
         change_CLUT_entry(CLUT_MenuEditLineSelected, CLUT_MenuEditCursor);
         // old stuff? hw 150916, reactivated 150923, this shows which digit will be changed now as it marks the other grey/black
@@ -690,7 +716,13 @@
         break;
     case FIELD_SELECT:
         write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
+        break;
+    case FIELD_TEXT:
+    	write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
+        if((newContent >= 'A') && (newContent <= '_'))
+            ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
 
+        mark_new_digit_of_actual_id_block_and_subBlock();
         break;
     }
 }
@@ -815,6 +847,9 @@
     else
     if((ident[actualId].maintype == FIELD_NUMBERS) && (action == ACTION_BUTTON_ENTER) && (newContent >= '0') && (newContent <= '9'))
         ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
+    else
+        if((ident[actualId].maintype == FIELD_TEXT) && (action == ACTION_BUTTON_ENTER) && (newContent >= '0') && (newContent <= '9'))
+            ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
 
     if(action == ACTION_BUTTON_ENTER)
     {
@@ -911,6 +946,10 @@
         ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
     }
 
+    if ((ident[actualId].maintype == FIELD_TEXT) && (newContent >= 'A' && newContent <= '_'))
+    {
+        ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
+    }
     mark_new_digit_of_actual_id_block_and_subBlock();
 }
 
@@ -950,6 +989,9 @@
     } else if (ident[actualId].maintype == FIELD_NUMBERS && newContent >= '0' && newContent <= '9') {
         ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
     }
+    if ((ident[actualId].maintype == FIELD_TEXT) && (newContent >= 'A' && newContent <= '_')) {
+        ident[actualId].newText[ident[actualId].begin[block] + subBlockPosition] = newContent;
+    }
 
     mark_new_digit_of_actual_id_block_and_subBlock();
 }
@@ -1018,7 +1060,27 @@
     *pNewValue3 = sum[2];
     *pNewValue4 = sum[3];
 }
+void evaluateNewStringText(uint32_t editID, uint8_t *pNewString)
+{
+    if(editID != ident[actualId].callerID)
+        return;
 
+    uint8_t i, digitCount;
+	uint8_t digit = '_';
+
+    memset(pNewString, 0 , IDENT_MAX_INPUT_TEXT);
+
+    i = 0;
+    while( ident[actualId].size[i] && (i < IDENT_MAX_INPUT_TEXT - 1))
+    {
+        for(digitCount = 0; digitCount < ident[actualId].size[i]; digitCount++)
+        {
+            digit = ident[actualId].newText[ident[actualId].begin[i] + digitCount];
+        }
+        pNewString[i] = digit;
+        i++;
+    }
+}
 
 uint8_t get_id_of(uint32_t editID)
 {
@@ -1156,7 +1218,38 @@
 
     id = backup_id;
 }
+void tMenuEdit_newInputText(uint32_t editID, uint8_t* ptext)
+{
+    uint8_t backup_id, temp_id;
+    uint8_t index = 0;
 
+    temp_id = get_id_of(editID);
+    if(temp_id == 255)
+        return;
+
+    backup_id = id;
+    id = temp_id;
+
+    if(editID != ident[id].callerID)
+    {
+        temp_id = 0;
+        while((temp_id < IDENT_MAX_INPUT_TEXT) && (editID != ident[temp_id].callerID))
+            temp_id++;
+        if(editID != ident[temp_id].callerID)
+            return;
+        id = temp_id;
+    }
+    for(index = 0; index < IDENT_MAX_INPUT_TEXT; index++)
+    {
+    	ident[id].input[index] = *ptext++;
+    }
+    create_newText_for_Id(id);
+    if(id <= idLast)
+        change_CLUT_entry((CLUT_MenuEditField0 + id), CLUT_MenuEditFieldRegular);
+    write_content_of_Id(id);
+
+    id = backup_id;
+}
 
 void resetEnterPressedToStateBeforeButtonAction(void)
 {
@@ -1257,6 +1350,20 @@
     }
 }
 
+void create_newText_for_Id_and_field_text(int8_t localId)
+{
+    uint8_t i;
+
+    i = 0;
+    while( ident[localId].size[i] && (i < 9))
+    {
+        if(ident[localId].input[i])
+            ident[localId].newText[ident[localId].begin[i]] = ident[localId].input[i];
+        i++;
+    }
+}
+
+
 void create_newText_for_actual_Id_and_field_select(void)
 {
 	create_newText_for_Id_and_field_select(actualId);
@@ -1276,6 +1383,12 @@
         return;
     }
 
+    if(	ident[localId].maintype == FIELD_TEXT)
+    {
+        create_newText_for_Id_and_field_text(localId);
+        return;
+    }
+
 	while( ident[localId].size[i] && (i < 4))
 	{
 		bool isNegative = false;
@@ -1443,6 +1556,66 @@
     write_field_udigit_and_2digit(FIELD_SDIGIT, editID, XleftGimpStyle, XrightGimpStyle, YtopGimpStyle, Font, text, ((input_u)int1).uint32, ((input_u)int2).uint32, ((input_u)int3).uint32, ((input_u)int4).uint32);
 }
 
+void write_field_text(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t* pInput)
+{
+    if(id >= 9)
+        return;
+
+    int8_t beginTmp;
+
+    ident[id].maintype = FIELD_TEXT;
+    ident[id].subtype  = FIELD_TEXT;
+
+    ident[id].coord[0] = XleftGimpStyle;
+    ident[id].coord[1] = XrightGimpStyle;
+    ident[id].coord[2] = YtopGimpStyle;
+    ident[id].fontUsed = (tFont *)Font;
+    ident[id].callerID = editID;
+
+    strncpy(ident[id].orgText, text, 32);
+    strncpy(ident[id].newText, text, 32);
+    ident[id].orgText[31] = 0;
+    ident[id].newText[31] = 0;
+
+    for(int i=0;i < IDENT_MAX_INPUT_TEXT -1;i++)
+    {
+    	ident[id].input[i] = pInput[i];
+        ident[id].size[i] = 0;
+    }
+    pInput[8] = 0;
+
+    beginTmp = 0;
+    for(int i=0;i < IDENT_MAX_INPUT_TEXT;i++)
+    {
+        while((ident[id].orgText[beginTmp] != '#')&& ident[id].orgText[beginTmp])
+            beginTmp++;
+
+        if(ident[id].orgText[beginTmp] == '#')
+        {
+
+            ident[id].begin[i] = beginTmp;
+            ident[id].size[i] = 1;
+            beginTmp = ident[id].begin[i] + ident[id].size[i];
+        }
+        else
+            break;
+    }
+
+    change_CLUT_entry((CLUT_MenuEditField0 + id), CLUT_MenuEditFieldRegular);
+
+    create_newText_for_Id(id);
+
+    if(editID == 0)
+    	write_content_without_Id();
+    else
+    {
+        write_content_of_Id(id);
+        if(!tME_stop)
+            idLast = id;
+        id++;
+    }
+}
+
 
 void write_field_select(uint32_t editID, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t int1,  uint8_t int2,  uint8_t int3,  uint8_t int4)
 {
--- a/Discovery/Src/tMenuEditCustom.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEditCustom.c	Sat Nov 15 19:29:44 2025 +0100
@@ -40,6 +40,7 @@
 #include "motion.h"
 #include "tMenu.h"
 #include "tMenuSystem.h"
+#include "ostc.h"
 #include <math.h>
 
 
@@ -56,7 +57,7 @@
 void openEdit_BigScreen(void);
 void openEdit_MotionCtrl(void);
 void openEdit_ViewPort(void);
-void openEdit_WarningBuz(void);
+void openEdit_FlipDisplay(void);
 void refresh_Customviews(void);
 void setMenuContentStructure();
 char customview_TXT2BYTE_helper(uint8_t customViewId);
@@ -379,10 +380,10 @@
     	case 5:		openEdit_ViewPort();
     		break;
 #endif
-#ifdef ENABLE_GPIO_V2
-    	case 5:		openEdit_WarningBuz();
-    	    	break;
-#endif
+        case 5:
+        	openEdit_FlipDisplay();
+        break;
+
     }
 }
 
@@ -473,19 +474,16 @@
     setEvent(StMCustom5_CViewPortControl,	(uint32_t)OnAction_CViewPortControl);
 #endif
 }
-void openEdit_WarningBuz(void)
+void openEdit_FlipDisplay(void)
 {
-    SSettings *pSettings = settingsGetPointer();
+/* does not work like this	resetEnterPressedToStateBeforeButtonAction(); */
 
-    if(pSettings->warningBuzzer == 0)
-    {
-        pSettings->warningBuzzer = 1;
-    }
-    else
-    {
-        pSettings->warningBuzzer = 0;
-    }
-    exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only();
+    bool oldValue = settingsGetPointer()->FlipDisplay;
+
+    setFlipDisplay(!oldValue);
+
+    exitEditWithUpdate();
+    exitMenuEdit_to_Home();
 }
 
 char customview_TXT2BYTE_helper(uint8_t customViewId)
@@ -530,6 +528,10 @@
     case CVIEW_noneOrDebug:
     	text = TXT2BYTE_DispNoneDbg;
     	break;
+#ifdef ENABLE_LOGGER_WINDOW
+    case CVIEW_Logger: text = TXT2BYTE_Logger;
+    	break;
+#endif
     default:
         break;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/tMenuEditCvOption.c	Sat Nov 15 19:29:44 2025 +0100
@@ -0,0 +1,362 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Src/tMenuEditCvOption.c
+/// \brief  Menu for configuration depended items
+/// \author heinrichs weikamp gmbh
+/// \date   24-Apr-2025
+///
+/// \details
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Includes ------------------------------------------------------------------*/
+#include "tMenuEditCvOption.h"
+#include "tMenuEdit.h"
+
+#include "gfx_fonts.h"
+#include "ostc.h"
+#include "tMenuEdit.h"
+#include "tHome.h"
+
+#include "cv_heartbeat.h"
+
+/* Private function prototypes -----------------------------------------------*/
+static void openEdit_Timer(void);
+void openEdit_Compass(void);
+
+/* Announced function prototypes -----------------------------------------------*/
+uint8_t OnAction_Compass		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+static uint8_t OnAction_CompassDeclination(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_Bearing		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_BearingClear	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_InertiaLevel	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+static uint8_t OnAction_Timer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+
+/* Exported functions --------------------------------------------------------*/
+
+void openEdit_CvOption(uint8_t line)
+{
+    set_globalState_Menu_Line(line);
+
+    switch(line)
+    {
+		case 1:
+		default:	resetMenuEdit(CLUT_MenuPageHardware);
+					openEdit_Compass();
+			break;
+		case 2:		openEdit_Timer();
+			break;
+#ifdef ENABLE_PULSE_SENSOR_BT
+		case 3: 	openEdit_Heartbeat();
+#endif
+			break;
+    }
+}
+
+/* Private functions ---------------------------------------------------------*/
+
+static uint8_t OnAction_CompassDeclination(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    SSettings *settings = settingsGetPointer();
+    uint8_t digitContentNew;
+    switch (action) {
+    case ACTION_BUTTON_ENTER:
+
+        return digitContent;
+    case ACTION_BUTTON_ENTER_FINAL:
+        {
+            int32_t compassDeclinationDeg;
+            evaluateNewString(editId, (uint32_t *)&compassDeclinationDeg, NULL, NULL, NULL);
+
+            if (compassDeclinationDeg > 99) {
+                compassDeclinationDeg = 99;
+            } else if (compassDeclinationDeg < -99) {
+                compassDeclinationDeg = -99;
+            }
+
+            settings->compassDeclinationDeg = compassDeclinationDeg;
+
+            tMenuEdit_newInput(editId, ((input_u)compassDeclinationDeg).uint32, 0, 0, 0);
+        }
+
+        break;
+    case ACTION_BUTTON_NEXT:
+        if (digitNumber == 0) {
+            digitContentNew = togglePlusMinus(digitContent);
+        } else {
+            digitContentNew = digitContent + 1;
+            if (digitContentNew > '9') {
+                digitContentNew = '0';
+            }
+        }
+
+        return digitContentNew;
+    case ACTION_BUTTON_BACK:
+        if (digitNumber == 0) {
+            digitContentNew = togglePlusMinus(digitContent);
+        } else {
+            digitContentNew = digitContent - 1;
+            if (digitContentNew < '0') {
+                digitContentNew = '9';
+            }
+        }
+
+        return digitContentNew;
+    }
+
+    return UNSPECIFIC_RETURN;
+}
+
+
+static void showCompassDeclination(SSettings *settings, bool isRefresh)
+{
+    char text[16];
+    snprintf(text, 16, "%c%c:", TXT_2BYTE, TXT2BYTE_CompassDeclination);
+    write_label_var(30, 800, ME_Y_LINE6, &FontT48, text);
+    if (isRefresh) {
+        tMenuEdit_refresh_field(StMOption_Compass_Declination);
+    } else {
+        write_field_sdigit(StMOption_Compass_Declination, 500, 800, ME_Y_LINE6, &FontT48, "\034###`", settings->compassDeclinationDeg, 0, 0, 0);
+    }
+}
+
+
+void refresh_CompassEdit(void)
+{
+    SSettings *settings = settingsGetPointer();
+
+    uint16_t heading;
+    char text[32];
+    uint8_t textIndex = 0;
+
+    text[0] = '\001';
+    text[1] = TXT_2BYTE;
+    text[2] = TXT2BYTE_Compass;
+    text[3] = 0;
+    write_topline(text);
+
+    if(settings->compassInertia)
+    {
+    	heading = (uint16_t)compass_getCompensated();
+    }
+    else
+    {
+    	heading = (uint16_t)stateUsed->lifeData.compass_heading;
+    }
+    snprintf(text,32,"\001%03i`",heading);
+    write_label_var(   0, 800, ME_Y_LINE1, &FontT54, text);
+
+    tMenuEdit_refresh_field(StMOption_Compass_SetCourse);
+    tMenuEdit_refresh_field(StMOption_Compass_Calibrate);
+    tMenuEdit_refresh_field(StMOption_Compass_ResetCourse);
+    text[textIndex++] = TXT_2BYTE;
+    text[textIndex++] = TXT2BYTE_CompassInertia;
+    text[textIndex++] = ':';
+    text[textIndex++] = ' ';
+    text[textIndex++] = '0' + settings->compassInertia;
+
+    write_label_var(30, 800, ME_Y_LINE5,  &FontT48, text);
+
+    showCompassDeclination(settings, true);
+
+    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
+}
+
+
+void openEdit_Compass(void)
+{
+    SSettings *settings = settingsGetPointer();
+
+    char text[10];
+    uint8_t textIndex = 0;
+
+
+    set_globalState(StMOption_Compass);
+    resetMenuEdit(CLUT_MenuPageHardware);
+
+    text[textIndex++] = '\001';
+    text[textIndex++] = TXT_2BYTE;
+    text[textIndex++] = TXT2BYTE_Compass;
+    text[textIndex++] = 0;
+    write_topline(text);
+
+    text[0] = TXT_2BYTE;
+    text[2] = 0;
+
+    text[1] = TXT2BYTE_SetBearing;
+    write_field_button(StMOption_Compass_SetCourse,	 30, 800, ME_Y_LINE2,  &FontT48, text);
+
+    text[1] = TXT2BYTE_ResetBearing;
+    write_field_button(StMOption_Compass_ResetCourse, 30, 800, ME_Y_LINE3,  &FontT48, text);
+
+    text[1] = TXT2BYTE_CompassCalib;
+    write_field_button(StMOption_Compass_Calibrate,	 30, 800, ME_Y_LINE4,  &FontT48, text);
+
+    text[1] = TXT2BYTE_CompassInertia;
+    textIndex = 2;
+    text[textIndex++] = ':';
+    text[textIndex++] = ' ';
+    text[textIndex++] = '0' + settings->compassInertia;
+    text[textIndex++] = 0;
+
+    write_field_button(StMOption_Compass_Inertia, 30, 800, ME_Y_LINE5,  &FontT48, text);
+
+    showCompassDeclination(settings, false);
+
+    setEvent(StMOption_Compass_SetCourse,		(uint32_t)OnAction_Bearing);
+    setEvent(StMOption_Compass_ResetCourse,	(uint32_t)OnAction_BearingClear);
+    setEvent(StMOption_Compass_Calibrate,		(uint32_t)OnAction_Compass);
+    setEvent(StMOption_Compass_Inertia,	(uint32_t)OnAction_InertiaLevel);
+    setEvent(StMOption_Compass_Declination, (uint32_t)OnAction_CompassDeclination);
+
+    tMenuEdit_select(StMOption_Compass_SetCourse);
+
+    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
+}
+
+
+uint8_t OnAction_Compass (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    calibrateCompass();
+    return EXIT_TO_INFO_COMPASS;
+}
+
+
+uint8_t OnAction_Bearing	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    if((int16_t)stateUsed->lifeData.compass_heading != -1)
+	{
+		settingsGetPointer()->compassBearing = (int16_t)stateUsed->lifeData.compass_heading;
+	}
+	else
+	{
+		settingsGetPointer()->compassBearing = 0;
+	}
+
+    if(settingsGetPointer()->compassBearing == 0)
+        settingsGetPointer()->compassBearing = 360;
+    return UPDATE_AND_EXIT_TO_MENU;
+}
+
+
+uint8_t OnAction_BearingClear	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    settingsGetPointer()->compassBearing = 0;
+    return UPDATE_AND_EXIT_TO_MENU;
+}
+
+
+uint8_t OnAction_InertiaLevel	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+	uint8_t newLevel = 0;
+
+	newLevel = settingsGetPointer()->compassInertia + 1;
+	if(newLevel > MAX_COMPASS_COMP)
+	{
+		newLevel = 0;
+	}
+	settingsGetPointer()->compassInertia = newLevel;
+    return UPDATE_DIVESETTINGS;
+}
+
+static void openEdit_Timer(void)
+{
+    SSettings *settings = settingsGetPointer();
+
+    char text[32];
+    snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Timer);
+    write_topline(text);
+
+    set_globalState(StMOption_Timer);
+    resetMenuEdit(CLUT_MenuPageCvOption);
+
+    uint16_t yPos = ME_Y_LINE_BASE + get_globalState_Menu_Line() * ME_Y_LINE_STEP;
+    snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_Timer);
+    write_label_var(30, 299, yPos, &FontT48, text);
+    write_field_udigit(StMOption_Timer_Value, 300, 392, yPos, &FontT48, "#:##", settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0);
+    write_label_var(393, 800, yPos, &FontT48, "\016\016 [m:ss]\017");
+
+    write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
+
+    setEvent(StMOption_Timer_Value, (uint32_t)OnAction_Timer);
+    startEdit();
+}
+static uint8_t OnAction_Timer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    SSettings *settings = settingsGetPointer();
+    uint8_t digitContentNew;
+    switch (action) {
+    case ACTION_BUTTON_ENTER:
+
+        return digitContent;
+    case ACTION_BUTTON_ENTER_FINAL:
+        {
+            uint32_t timerM;
+            uint32_t timerS;
+            evaluateNewString(editId, &timerM, &timerS, 0, 0);
+            if (timerM > 9) {
+                timerM = 9;
+            }
+            if (timerS > 59) {
+                timerS = 59;
+            }
+
+            uint16_t timerDurationS = 60 * timerM + timerS;
+
+            if (timerDurationS < 1) {
+                timerDurationS = 1;
+            }
+
+            if (timerDurationS != settings->timerDurationS) {
+                settings->timerDurationS = timerDurationS;
+
+                disableTimer();
+
+                tMenuEdit_newInput(editId, settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0);
+            }
+
+            settings->cv_configuration |= (1 << CVIEW_Timer);
+
+            return EXIT_TO_MENU;
+        }
+    case ACTION_BUTTON_NEXT:
+        digitContentNew = digitContent + 1;
+        if ((blockNumber == 1 && digitNumber == 0 && digitContentNew > '5') || digitContentNew > '9') {
+            digitContentNew = '0';
+        }
+
+        return digitContentNew;
+    case ACTION_BUTTON_BACK:
+        digitContentNew = digitContent - 1;
+        if (digitContentNew < '0') {
+            if (blockNumber == 1 && digitNumber == 0) {
+                digitContentNew = '5';
+            } else {
+                digitContentNew = '9';
+            }
+        }
+
+        return digitContentNew;
+    }
+
+    return EXIT_TO_MENU;
+}
+
+
--- a/Discovery/Src/tMenuEditHardware.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEditHardware.c	Sat Nov 15 19:29:44 2025 +0100
@@ -43,34 +43,27 @@
 #include "data_exchange_main.h"
 
 
-extern void tM_build_pages(void);
+//extern void tM_build_pages(void);
 
 /* Private function prototypes -----------------------------------------------*/
 void openEdit_Bluetooth(void);
-void openEdit_Compass(void);
 void openEdit_O2Sensors(void);
 void openEdit_Brightness(void);
 //void openEdit_Luftintegration(void);
 void openEdit_ButtonSens(void);
-void openEdit_FlipDisplay(void);
+void openEdit_WarningBuz(void);
+
 
 /* Announced function prototypes -----------------------------------------------*/
-uint8_t OnAction_Compass		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-uint8_t OnAction_Bearing		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-uint8_t OnAction_BearingClear	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-uint8_t OnAction_InertiaLevel	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-//uint8_t OnAction_ExitHardw	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Sensor1		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Sensor2		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Sensor3		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_O2_Calibrate   (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-//uint8_t OnAction_O2_Source		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Sensor_Info	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Sensor_Detect	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Button			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_ButtonBalance	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_ButtonLock		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-// not required uint8_t OnAction_Bluetooth				(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 
 /* Exported functions --------------------------------------------------------*/
 
@@ -87,26 +80,20 @@
     switch(line)
     {
     case 1:
-    default:
-        openEdit_Bluetooth();
-    break;
-    case 2:
-    	resetMenuEdit(CLUT_MenuPageHardware);
-        openEdit_Compass();
-    break;
-    case 3:
-        openEdit_O2Sensors();
-    break;
-    case 4:
-        openEdit_Brightness();
-    break;
-    case 5:
-    	resetMenuEdit(CLUT_MenuPageHardware);
-        openEdit_ButtonSens();
-    break;
-    case 6:
-    	openEdit_FlipDisplay();
-    break;
+    default:	openEdit_Bluetooth();
+        break;
+    case 2:    	openEdit_O2Sensors();
+        break;
+    case 3:    	openEdit_Brightness();
+        break;
+    case 4:   	resetMenuEdit(CLUT_MenuPageHardware);
+        	openEdit_ButtonSens();
+        break;
+	case 5:		if(isNewDisplay())
+				{
+					openEdit_WarningBuz();
+				}
+	    	break;
     }
 }
 
@@ -131,245 +118,24 @@
     exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only();
 }
 
-void openEdit_FlipDisplay(void)
+void openEdit_WarningBuz(void)
 {
-/* does not work like this	resetEnterPressedToStateBeforeButtonAction(); */
-
     SSettings *pSettings = settingsGetPointer();
 
-    if(pSettings->FlipDisplay == 0)
-    {
-        pSettings->FlipDisplay = 1;
-    }
-    else
+    if(pSettings->warningBuzzer == 0)
     {
-        pSettings->FlipDisplay = 0;
-    }
-    /* reinit all views */
-    tHome_init();
-    tI_init();
-    tM_init();
-    tMenuEdit_init();
-    tInfoLog_init();
-    tM_build_pages();
-    GFX_build_logo_frame();
-    GFX_build_hw_background_frame();
-
-    exitEditWithUpdate();
-    exitMenuEdit_to_Home();
-}
-
-static uint8_t OnAction_CompassDeclination(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    SSettings *settings = settingsGetPointer();
-    uint8_t digitContentNew;
-    switch (action) {
-    case ACTION_BUTTON_ENTER:
-
-        return digitContent;
-    case ACTION_BUTTON_ENTER_FINAL:
-        {
-            int32_t compassDeclinationDeg;
-            evaluateNewString(editId, (uint32_t *)&compassDeclinationDeg, NULL, NULL, NULL);
-
-            if (compassDeclinationDeg > 99) {
-                compassDeclinationDeg = 99;
-            } else if (compassDeclinationDeg < -99) {
-                compassDeclinationDeg = -99;
-            }
-
-            settings->compassDeclinationDeg = compassDeclinationDeg;
-
-            tMenuEdit_newInput(editId, ((input_u)compassDeclinationDeg).uint32, 0, 0, 0);
-        }
-
-        break;
-    case ACTION_BUTTON_NEXT:
-        if (digitNumber == 0) {
-            digitContentNew = togglePlusMinus(digitContent);
-        } else {
-            digitContentNew = digitContent + 1;
-            if (digitContentNew > '9') {
-                digitContentNew = '0';
-            }
-        }
-
-        return digitContentNew;
-    case ACTION_BUTTON_BACK:
-        if (digitNumber == 0) {
-            digitContentNew = togglePlusMinus(digitContent);
-        } else {
-            digitContentNew = digitContent - 1;
-            if (digitContentNew < '0') {
-                digitContentNew = '9';
-            }
-        }
-
-        return digitContentNew;
-    }
-
-    return UNSPECIFIC_RETURN;
-}
-
-
-static void showCompassDeclination(SSettings *settings, bool isRefresh)
-{
-    char text[16];
-    snprintf(text, 16, "%c%c:", TXT_2BYTE, TXT2BYTE_CompassDeclination);
-    write_label_var(30, 800, ME_Y_LINE6, &FontT48, text);
-    if (isRefresh) {
-        tMenuEdit_refresh_field(StMHARD2_Compass_Declination);
-    } else {
-        write_field_sdigit(StMHARD2_Compass_Declination, 500, 800, ME_Y_LINE6, &FontT48, "\034###`", settings->compassDeclinationDeg, 0, 0, 0);
-    }
-}
-
-
-void refresh_CompassEdit(void)
-{
-    SSettings *settings = settingsGetPointer();
-
-    uint16_t heading;
-    char text[32];
-    uint8_t textIndex = 0;
-
-    text[0] = '\001';
-    text[1] = TXT_2BYTE;
-    text[2] = TXT2BYTE_Compass;
-    text[3] = 0;
-    write_topline(text);
-
-    if(settings->compassInertia)
-    {
-    	heading = (uint16_t)compass_getCompensated();
+        pSettings->warningBuzzer = 1;
+        requestBuzzerActivation(REQUEST_BUZZER_ONCE);
     }
     else
     {
-    	heading = (uint16_t)stateUsed->lifeData.compass_heading;
+        pSettings->warningBuzzer = 0;
+        deactivateBuzzer();
     }
-    snprintf(text,32,"\001%03i`",heading);
-    write_label_var(   0, 800, ME_Y_LINE1, &FontT54, text);
-
-    tMenuEdit_refresh_field(StMHARD2_Compass_SetCourse);
-    tMenuEdit_refresh_field(StMHARD2_Compass_Calibrate);
-    tMenuEdit_refresh_field(StMHARD2_Compass_ResetCourse);
-    text[textIndex++] = TXT_2BYTE;
-    text[textIndex++] = TXT2BYTE_CompassInertia;
-    text[textIndex++] = ':';
-    text[textIndex++] = ' ';
-    text[textIndex++] = '0' + settings->compassInertia;
-
-    write_label_var(30, 800, ME_Y_LINE5,  &FontT48, text);
-
-    showCompassDeclination(settings, true);
-
-    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
+    exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only();
 }
 
 
-void openEdit_Compass(void)
-{
-    SSettings *settings = settingsGetPointer();
-
-    char text[10];
-    uint8_t textIndex = 0;
-
-
-    set_globalState(StMHARD2_Compass);
-    resetMenuEdit(CLUT_MenuPageHardware);
-
-    text[textIndex++] = '\001';
-    text[textIndex++] = TXT_2BYTE;
-    text[textIndex++] = TXT2BYTE_Compass;
-    text[textIndex++] = 0;
-    write_topline(text);
-
-    text[0] = TXT_2BYTE;
-    text[2] = 0;
-
-    text[1] = TXT2BYTE_SetBearing;
-    write_field_button(StMHARD2_Compass_SetCourse,	 30, 800, ME_Y_LINE2,  &FontT48, text);
-
-    text[1] = TXT2BYTE_ResetBearing;
-    write_field_button(StMHARD2_Compass_ResetCourse, 30, 800, ME_Y_LINE3,  &FontT48, text);
-
-    text[1] = TXT2BYTE_CompassCalib;
-    write_field_button(StMHARD2_Compass_Calibrate,	 30, 800, ME_Y_LINE4,  &FontT48, text);
-
-    text[1] = TXT2BYTE_CompassInertia;
-    textIndex = 2;
-    text[textIndex++] = ':';
-    text[textIndex++] = ' ';
-    text[textIndex++] = '0' + settings->compassInertia;
-    text[textIndex++] = 0;
-
-    write_field_button(StMHARD2_Compass_Inertia, 30, 800, ME_Y_LINE5,  &FontT48, text);
-
-    showCompassDeclination(settings, false);
-
-    setEvent(StMHARD2_Compass_SetCourse,		(uint32_t)OnAction_Bearing);
-    setEvent(StMHARD2_Compass_ResetCourse,	(uint32_t)OnAction_BearingClear);
-    setEvent(StMHARD2_Compass_Calibrate,		(uint32_t)OnAction_Compass);
-    setEvent(StMHARD2_Compass_Inertia,	(uint32_t)OnAction_InertiaLevel);
-    setEvent(StMHARD2_Compass_Declination, (uint32_t)OnAction_CompassDeclination);
-
-    tMenuEdit_select(StMHARD2_Compass_SetCourse);
-
-    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
-}
-
-
-uint8_t OnAction_Compass (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    calibrateCompass();
-    return EXIT_TO_INFO_COMPASS;
-}
-
-
-uint8_t OnAction_Bearing	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    if((int16_t)stateUsed->lifeData.compass_heading != -1)
-	{
-		settingsGetPointer()->compassBearing = (int16_t)stateUsed->lifeData.compass_heading;
-	}
-	else
-	{
-		settingsGetPointer()->compassBearing = 0;
-	}
-
-    if(settingsGetPointer()->compassBearing == 0)
-        settingsGetPointer()->compassBearing = 360;
-    return UPDATE_AND_EXIT_TO_MENU;
-}
-
-
-uint8_t OnAction_BearingClear	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    settingsGetPointer()->compassBearing = 0;
-    return UPDATE_AND_EXIT_TO_MENU;
-}
-
-
-uint8_t OnAction_InertiaLevel	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-	uint8_t newLevel = 0;
-
-	newLevel = settingsGetPointer()->compassInertia + 1;
-	if(newLevel > MAX_COMPASS_COMP)
-	{
-		newLevel = 0;
-	}
-	settingsGetPointer()->compassInertia = newLevel;
-    return UPDATE_DIVESETTINGS;
-}
-
-/*
-uint8_t OnAction_ExitHardw (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    return EXIT_TO_MENU;
-}
-*/
-
 void refresh_O2Sensors(void)
 {
     char strSensorId[20];
--- a/Discovery/Src/tMenuEditPlanner.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEditPlanner.c	Sat Nov 15 19:29:44 2025 +0100
@@ -396,11 +396,7 @@
 
     resultPage = 0;
     pDecoinfo = simulation_decoplaner(tMplan_depth_meter, tMplan_intervall_time_minutes, tMplan_dive_time_minutes, gasChangeList);
-    simulation_evaluate_profil( &tMplan_pGasConsumption,
-    							&tMplan_Summary,
-								tMplan_depth_meter, tMplan_dive_time_minutes, tMplan_gasConsumTravel, tMplan_gasConsumDeco,
-								pDecoinfo,
-								gasChangeList);
+    simulation_evaluate_profil(&tMplan_pGasConsumption[0], &tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, tMplan_gasConsumTravel, tMplan_gasConsumDeco, pDecoinfo, gasChangeList);
   //  simulation_gas_consumption(tMplan_pGasConsumption, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, tMplan_gasConsumTravel, tMplan_gasConsumDeco, gasChangeList);
  //   simulation_helper_change_points(&tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, gasChangeListDepth);
 
--- a/Discovery/Src/tMenuEditSystem.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEditSystem.c	Sat Nov 15 19:29:44 2025 +0100
@@ -46,18 +46,38 @@
 
 /*#define HAVE_DEBUG_VIEW */
 static uint8_t infoPage = 0;
+#ifdef ENABLE_SETTING_PROFILES
+static uint32_t profileStartCrc[NUMBER_OF_PROFILES];
+static uint8_t profileActiveStart = 0;
+#endif
 
 /* Private function prototypes -----------------------------------------------*/
 void openEdit_DateTime(void);
 void openEdit_DateFormat(void);
 void openEdit_Language(void);
 void openEdit_Design(void);
+#ifdef ENABLE_SETTING_PROFILES
+void openEdit_Profile(void);
+#endif
 void openEdit_Information(void);
 void openEdit_Reset(void);
 void openEdit_Maintenance(void);
 //void openEdit_ShowDebugInfo(void);
 //void openEdit_Salinity(void);
 
+static uint32_t swapBytes(uint32_t source)
+{
+	uint32_t ret = 0;
+
+	ret =  		((source & 0x000000FF) << 24)
+			| 	((source & 0x0000FF00) <<  8)
+			| 	((source & 0x00FF0000) >>  8)
+			| 	((source & 0xFF000000) >> 24);
+
+	return ret;
+}
+
+
 /* Announced function prototypes -----------------------------------------------*/
 uint8_t OnAction_Date					(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Time					(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -81,7 +101,10 @@
 uint8_t OnAction_Units				(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Colorscheme	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_DebugInfo		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
-
+#ifdef ENABLE_SETTING_PROFILES
+uint8_t OnAction_Profile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_SetProfile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+#endif
 uint8_t OnAction_Exit					(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Confirm			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Maintenance			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -101,7 +124,9 @@
 #ifdef SCREENTEST
 uint8_t OnAction_ScreenTest		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 #endif
-uint8_t OnAction_Information	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_Information	 (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_FlashBootloader (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+
 /*
 uint8_t OnAction_Salinity			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_TestCLog			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -109,87 +134,6 @@
 
 /* Exported functions --------------------------------------------------------*/
 
-static uint8_t OnAction_Timer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
-{
-    SSettings *settings = settingsGetPointer();
-    uint8_t digitContentNew;
-    switch (action) {
-    case ACTION_BUTTON_ENTER:
-
-        return digitContent;
-    case ACTION_BUTTON_ENTER_FINAL:
-        {
-            uint32_t timerM;
-            uint32_t timerS;
-            evaluateNewString(editId, &timerM, &timerS, 0, 0);
-            if (timerM > 9) {
-                timerM = 9;
-            }
-            if (timerS > 59) {
-                timerS = 59;
-            }
-
-            uint16_t timerDurationS = 60 * timerM + timerS;
-
-            if (timerDurationS < 1) {
-                timerDurationS = 1;
-            }
-
-            if (timerDurationS != settings->timerDurationS) {
-                settings->timerDurationS = timerDurationS;
-
-                disableTimer();
-
-                tMenuEdit_newInput(editId, settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0);
-            }
-
-            return EXIT_TO_MENU;
-        }
-    case ACTION_BUTTON_NEXT:
-        digitContentNew = digitContent + 1;
-        if ((blockNumber == 1 && digitNumber == 0 && digitContentNew > '5') || digitContentNew > '9') {
-            digitContentNew = '0';
-        }
-
-        return digitContentNew;
-    case ACTION_BUTTON_BACK:
-        digitContentNew = digitContent - 1;
-        if (digitContentNew < '0') {
-            if (blockNumber == 1 && digitNumber == 0) {
-                digitContentNew = '5';
-            } else {
-                digitContentNew = '9';
-            }
-        }
-
-        return digitContentNew;
-    }
-
-    return EXIT_TO_MENU;
-}
-
-
-static void openEdit_Timer(void)
-{
-    SSettings *settings = settingsGetPointer();
-
-    char text[32];
-    snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Timer);
-    write_topline(text);
-
-    uint16_t yPos = ME_Y_LINE_BASE + get_globalState_Menu_Line() * ME_Y_LINE_STEP;
-    snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_Timer);
-    write_label_var(30, 299, yPos, &FontT48, text);
-    write_field_udigit(StMSYS_Timer, 300, 392, yPos, &FontT48, "#:##", settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0);
-    write_label_var(393, 800, yPos, &FontT48, "\016\016 [m:ss]\017");
-
-    write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
-
-    setEvent(StMSYS_Timer, (uint32_t)OnAction_Timer);
-    startEdit();
-}
-
-
 void openEdit_System(uint8_t line)
 {
     set_globalState_Menu_Line(line);
@@ -197,36 +141,33 @@
 
     if(actual_menu_content == MENU_SURFACE)
     {
-        switch(line)
-        {
-        case 1:
-        default:
-            openEdit_DateTime();
-        break;
-        case 2:
-            openEdit_Timer();
-        break;
-        case 3:
-            openEdit_Language();
-        break;
-        case 4:
-            openEdit_Design();
-        break;
-        case 5:
-            openEdit_Information();
-        break;
-        case 6:
-            openEdit_Reset();
-        break;
-/*
-        case 3:
-            openEdit_DecoFutureTTS();
-        break;
-        case 4:
-            openEdit_DecoLastStop();
-        break;
-*/
-        }
+
+    	if(line == get_lineOfID(StMSYS1_DateTime))
+    	{
+    		openEdit_DateTime();
+    	}
+    	else if(line == get_lineOfID(StMSYS2_English))
+    	{
+    		 openEdit_Language();
+    	}
+    	else if(line == get_lineOfID(StMSYS3_Units))
+    	{
+    		openEdit_Design();
+    	}
+    	else if(line == get_lineOfID(StMSYS4_Info))
+    	{
+    		openEdit_Information();
+    	}
+    	else if(line == get_lineOfID(StMSYS5_ResetAll))
+    	{
+    		openEdit_Reset();
+    	}
+#ifdef ENABLE_SETTING_PROFILES
+    	else if(line == get_lineOfID(StMSYS_Profile))
+    	{
+    		openEdit_Profile();
+    	}
+#endif
     }
     else
     {
@@ -247,7 +188,7 @@
     char formatStr[20];
     SSettings *pSettings;
     const SFirmwareData *pFirmwareInfo;
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
     uint8_t localHours = 0;
     uint8_t localMinutes = 0;
 #endif
@@ -285,7 +226,7 @@
     write_label_fix(  20, 340, ME_Y_LINE2, &FontT42, TXT_Format);
     write_label_fix(  20, 340, ME_Y_LINE3, &FontT42, TXT_DateConfig);
     write_label_fix(  20, 790, ME_Y_LINE4, &FontT42, TXT_Format);
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
     write_label_var(  20, 340, ME_Y_LINE5, &FontT42, "GNSS");
     snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_TIMEZONE);
     write_label_var(  20, 340, ME_Y_LINE6, &FontT42, text);
@@ -307,7 +248,7 @@
     }
     tMenuEdit_newButtonText(StMSYS1_FORMAT, formatStr);
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
     if(pStateReal->lifeData.gnssData.alive & GNSS_ALIVE_STATE_TIME)
     {
         convertUTCToLocal(pStateReal->lifeData.gnssData.DateTime.hour, pStateReal->lifeData.gnssData.DateTime.min, &localHours, &localMinutes);
@@ -373,7 +314,7 @@
     write_label_fix(  20, 340, ME_Y_LINE2, &FontT42, TXT_Format);
     write_label_fix(  20, 340, ME_Y_LINE3, &FontT42, TXT_DateConfig);
     write_label_fix(  20, 790, ME_Y_LINE4, &FontT42, TXT_Format);
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
     write_label_var(  20, 340, ME_Y_LINE5, &FontT42, "GNSS");
     snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_TIMEZONE);
     write_label_var(  20, 340, ME_Y_LINE6, &FontT42, text);
@@ -395,7 +336,7 @@
 
     write_field_button(StMSYS1_FORMAT, 320, 790, ME_Y_LINE4,  &FontT48, formatStr);
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 	snprintf(text, 32, "--:--");
 	write_field_button(StMSYS1_GNSSDT, 320, 790, ME_Y_LINE5,  &FontT48, text);
     write_field_sdigit(StMSYS1_ZONE, 320, 780, ME_Y_LINE6,  &FontT48, "UTC: ###:###", pSettings->timeZone.hours, pSettings->timeZone.minutes,0,0);
@@ -405,7 +346,7 @@
     setEvent(StMSYS1_Time, 		(uint32_t)OnAction_Time);
     setEvent(StMSYS1_12HR,      (uint32_t)OnAction_12HR);
     setEvent(StMSYS1_FORMAT,	(uint32_t)OnAction_Format);
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
    	setEvent(StMSYS1_GNSSDT, (uint32_t)OnAction_SetGnss);
 	setEvent(StMSYS1_ZONE,		(uint32_t)OnAction_UTC);
 #endif
@@ -986,10 +927,131 @@
 #endif
 }
 
+#ifdef ENABLE_SETTING_PROFILES
+void changeActiveProfil(uint8_t newProfile)
+{
+	SSettings *pSettings = settingsGetPointer();
+	SSettings* pOldProfile = profileGetPointer(pSettings->activeProfile);
+	SSettings* pNewProfile = profileGetPointer(newProfile);
+    uint16_t personalDiveCountBackup;
+    uint8_t lastDiveLogIdBackup;
+    uint32_t sampleStartBackup;
+    char customTextBackup[60];
+
+    if( newProfile < NUMBER_OF_PROFILES)
+    {
+	/* some data needs to be the same in all profiles => make backup before gettings the new profile */
+		personalDiveCountBackup = pSettings->personalDiveCount;
+		lastDiveLogIdBackup = pSettings->lastDiveLogId;
+		sampleStartBackup = pSettings->logFlashNextSampleStartAddress;
+		memcpy(customTextBackup, pSettings->customtext, 60);
+
+
+		memcpy(pOldProfile,pSettings,sizeof(SSettings));
+		memcpy(pSettings,pNewProfile,sizeof(SSettings));
+
+		set_new_settings_missing_in_ext_flash(EF_PROFILE0 + newProfile);
+		check_and_correct_settings(EF_PROFILE0 + newProfile);
+
+		pSettings->personalDiveCount = personalDiveCountBackup;
+		pSettings->lastDiveLogId = lastDiveLogIdBackup;
+		pSettings->logFlashNextSampleStartAddress = sampleStartBackup;
+
+		pSettings->firmwareVersion[0] = firmware_FirmwareData.versionFirst;
+		pSettings->firmwareVersion[1] = firmware_FirmwareData.versionSecond;
+		pSettings->firmwareVersion[2] = firmware_FirmwareData.versionThird;
+		pSettings->firmwareVersion[3] = firmware_FirmwareData.versionBeta;
+
+		memcpy(pSettings->customtext, customTextBackup,  60);
+
+		if(pOldProfile->tX_colorscheme != pSettings->tX_colorscheme)
+		{
+		    GFX_use_colorscheme(pSettings->tX_colorscheme);
+		    tHome_init_compass();
+		}
+    }
+}
+
+void exitMenuProfil()
+{
+	uint8_t index = 0;
+	SSettings* pProfile;
+	uint8_t writeFlash = 0;
+	uint32_t profileExitCrc;
+
+	for(index = 0; index < NUMBER_OF_PROFILES; index++)
+	{
+		pProfile = profileGetPointer(index);
+		profileExitCrc = CalcFletcher32((uint32_t)pProfile, (uint32_t)pProfile + sizeof(SSettings));
+
+		if(profileExitCrc != profileStartCrc[index])
+		{
+			writeFlash = 1;
+			break;
+		}
+	}
+	if(writeFlash)
+	{
+		for(index = EF_PROFILE0; index <= EF_PROFILE3; index++)
+		ext_flash_write_settings(index,0);
+	}
+	if(profileActiveStart != settingsGetPointer()->activeProfile)
+	{
+		createDiveSettings();
+	}
+	exitMenuEdit(1);
+}
+#endif
+#ifdef ENABLE_SETTING_PROFILES
+void openEdit_Profile(void)
+{
+	char text[50];
+	uint8_t index = 0;
+	SSettings *pSettings = settingsGetPointer();
+	SSettings* pProfile;
+
+	setBackMenu((uint32_t)exitMenuProfil,0,0);
+
+	profileActiveStart = pSettings->activeProfile;
+
+/* read profiles from flash */
+	for(index = EF_PROFILE0; index <= EF_PROFILE3; index++)
+	{
+		set_settings_to_Standard(index);		/* this is needed because details like header version are used by the read block function */
+		ext_flash_read_settings(index);			/* will overwrite standard settings if reading is successfull */
+		pProfile = profileGetPointer(index - EF_PROFILE0);
+		profileStartCrc[index - EF_PROFILE0] = CalcFletcher32((uint32_t)pProfile, (uint32_t)pProfile + sizeof(SSettings));
+		set_new_settings_missing_in_ext_flash(index);
+		check_and_correct_settings(index);
+	}
+
+    sprintf(text,"\001%c%c",TXT_2BYTE,TXT2BYTE_Profile);
+    write_topline(text);
+
+    sprintf(text,"%c %c%c:",TXT_Active,TXT_2BYTE,TXT2BYTE_Profile);
+    write_label_var(  30, 300, ME_Y_LINE1, &FontT48, text);
+    sprintf(text,"%s",pSettings->profileName[pSettings->activeProfile]);
+    write_field_button(StMSYS_Profile,		400, 700, ME_Y_LINE1,  &FontT48, text);
+    write_field_text(StMSYS_ProfileA,		400, 700, ME_Y_LINE3,  &FontT48, "########", pSettings->profileName[0]);
+    write_field_text(StMSYS_ProfileB,		400, 700, ME_Y_LINE4,  &FontT48, "########", pSettings->profileName[1]);
+    write_field_text(StMSYS_ProfileC,		400, 700, ME_Y_LINE5,  &FontT48, "########", pSettings->profileName[2]);
+    write_field_text(StMSYS_ProfileD,		400, 700, ME_Y_LINE6,  &FontT48, "########", pSettings->profileName[3]);
+
+    setEvent(StMSYS_Profile,	(uint32_t)OnAction_SetProfile);
+    setEvent(StMSYS_ProfileA,	(uint32_t)OnAction_Profile);
+    setEvent(StMSYS_ProfileB,	(uint32_t)OnAction_Profile);
+    setEvent(StMSYS_ProfileC,	(uint32_t)OnAction_Profile);
+    setEvent(StMSYS_ProfileD,	(uint32_t)OnAction_Profile);
+
+    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
+}
+#endif
+
 
 void refresh_Design(void)
 {
-    char text[32];
+	char text[32];
+	SSettings *pSettings = settingsGetPointer();
 
     // header
     text[0] = '\001';
@@ -1004,7 +1066,7 @@
     text[2] = 0;
     write_label_var(  30, 200, ME_Y_LINE1, &FontT48, text);
 
-    if(settingsGetPointer()->nonMetricalSystem)
+    if(pSettings->nonMetricalSystem)
     {
         text[1] = TXT2BYTE_Units_feet;
     }
@@ -1020,7 +1082,7 @@
     text[2] = 0;
     write_label_var(  30, 300, ME_Y_LINE2, &FontT48, text);
 
-    text[0] = '0' + settingsGetPointer()->tX_colorscheme;
+    text[0] = '0' + pSettings->tX_colorscheme;
     text[1] = 0;
     write_label_var( 400, 700, ME_Y_LINE2, &FontT48, text);
 
@@ -1081,8 +1143,103 @@
     return UPDATE_DIVESETTINGS;
 }
 
+#ifdef ENABLE_SETTING_PROFILES
+uint8_t OnAction_SetProfile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+	SSettings *pSettings = settingsGetPointer();
 
+	uint8_t newProfile = pSettings->activeProfile + 1;
 
+	if(newProfile == NUMBER_OF_PROFILES)
+	{
+		newProfile = 0;
+	}
+	changeActiveProfil(newProfile);
+	pSettings->activeProfile = newProfile;
+
+	tMenuEdit_newButtonText(editId,(char*)pSettings->profileName[pSettings->activeProfile]);
+    return UNSPECIFIC_RETURN;
+}
+
+uint8_t OnAction_Profile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    SSettings *pSettings = settingsGetPointer();
+    SSettings *pProfile;
+    uint8_t digitContentNew;
+    uint8_t profilName[9];
+    uint8_t updateProfilIndex = 0;
+    uint8_t index = 0;
+
+    uint8_t returnValue = UNSPECIFIC_RETURN;
+
+    switch (editId)
+    {
+    	default:
+    	case StMSYS_ProfileA: updateProfilIndex = 0;
+    		break;
+    	case StMSYS_ProfileB: updateProfilIndex = 1;
+    	    		break;
+    	case StMSYS_ProfileC: updateProfilIndex = 2;
+    	    		break;
+    	case StMSYS_ProfileD: updateProfilIndex = 3;
+    	    		break;
+    }
+
+    switch (action)
+    {
+		case ACTION_BUTTON_ENTER: returnValue = digitContent;
+			break;
+		case ACTION_BUTTON_ENTER_FINAL:
+			{
+				evaluateNewStringText(editId, profilName);
+				tMenuEdit_newInputText(editId, profilName);
+				if(pSettings->activeProfile == updateProfilIndex)
+				{
+					tMenuEdit_newButtonText(StMSYS_Profile, (char*)profilName);
+				}
+				strcpy((char*)pSettings->profileName[updateProfilIndex],(char*)profilName);
+				for (index = 0; index < NUMBER_OF_PROFILES; index++)
+				{
+					pProfile = profileGetPointer(index);
+					strcpy((char*)pProfile->profileName[updateProfilIndex],(char*)profilName);
+				}
+			}
+
+			break;
+		case ACTION_BUTTON_NEXT:
+				if(digitContent == 'Z')
+				{
+					digitContentNew = '_';
+				}
+				else if (digitContent == '_')
+				{
+					digitContentNew = 'A';
+				}
+				else
+				{
+					digitContentNew = digitContent + 1;
+				}
+				returnValue = digitContentNew;
+			break;
+		case ACTION_BUTTON_BACK:
+				if(digitContent == 'A')
+				{
+					digitContentNew = '_';
+				}
+				else if (digitContent == '_')
+				{
+					digitContentNew = 'Z';
+				}
+				else
+				{
+					digitContentNew = digitContent - 1;
+				}
+				returnValue = digitContentNew;
+			break;
+    }
+    return returnValue;
+}
+#endif
 
 /*
 uint8_t OnAction_Design_t7ft		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
@@ -1192,7 +1349,14 @@
         text_header[1] = TXT_Information;
         text_header[2] = 0;
 
-        write_label_var(  20, 800, ME_Y_LINE1, &FontT42, "Dive Computer OSTC4");
+        if(isNewDisplay())
+        {
+        	write_label_var(  20, 800, ME_Y_LINE1, &FontT42, "Dive Computer OSTC5");
+        }
+        else
+        {
+        	write_label_var(  20, 800, ME_Y_LINE1, &FontT42, "Dive Computer OSTC4");
+        }
         write_label_var(  20, 800, ME_Y_LINE2, &FontT42, "Design heinrichs/weikamp");
 
         Sdate.Year = firmwareDataGetPointer()->release_year;
@@ -1468,6 +1632,8 @@
     write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
 }
 
+customBlockInfo_t blockInfo;
+
 void openEdit_Maintenance(void)
 {
     char text[32];
@@ -1475,6 +1641,12 @@
     SSettings *pSettings = settingsGetPointer();
     SSensorDataDiveO2* pDiveO2Data = NULL;
 
+    customBlockInfo_t* pCustumBlockInfo = (customBlockInfo_t *) CUSTOM_BLOCK_INFO_ADDR;
+
+    blockInfo.Type = swapBytes(pCustumBlockInfo->Type);
+    blockInfo.fletcher = swapBytes(pCustumBlockInfo->fletcher);
+    blockInfo.length = swapBytes(pCustumBlockInfo->length);
+
     resetMenuEdit(CLUT_MenuPageSystem);
 
     text[0] = '\001';
@@ -1517,6 +1689,12 @@
     	}
     }
 
+    if((blockInfo.Type & 0x0000FF00)== 0x0100)
+    {
+    	snprintf(text,32,"Flash Bootloader");
+		write_field_button(StMSYS5_FlashBoot,			30, 800, ME_Y_LINE4,  &FontT48, text);
+    }
+
 #ifdef ENABLE_ANALYSE_SAMPLES
     text[0] = TXT_2BYTE;
     text[1] = TXT2BYTE_SetSampleIndex;
@@ -1540,6 +1718,12 @@
     setEvent(StMSYS5_SetSampleIndx, (uint32_t)OnAction_RecoverSampleIdx);
 #endif
 
+    if((blockInfo.Type & 0x0000FF00)== 0x0100)
+    {
+    	setEvent(StMSYS5_FlashBoot, (uint32_t)OnAction_FlashBootloader);
+    }
+
+
 
     text[0] = TXT_2BYTE;
     text[1] = TXT2BYTE_WarnBatteryLow;
@@ -1624,8 +1808,8 @@
 
 uint8_t OnAction_ResetAll			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
-    set_settings_to_Standard();
-    check_and_correct_settings();
+    set_settings_to_Standard(EF_SETTINGS);
+    check_and_correct_settings(EF_SETTINGS);
 
     return UPDATE_AND_EXIT_TO_HOME;
 }
@@ -1755,6 +1939,31 @@
     FrameCount++;
 }
 #endif
+
+uint8_t OnAction_FlashBootloader (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+	SHardwareData HwInfo;
+    customBlockInfo_t* pCustumBlockInfo = (customBlockInfo_t *) CUSTOM_BLOCK_INFO_ADDR;
+    customBlockInfo_t blockInfo;
+    uint32_t checksum;
+    uint8_t* pSource = (uint8_t *) 0x08100000;
+
+    checksum = CalcFletcher32(0x08100000,0x0811FFEF);	/* last nibble contains block info => exclude */
+
+    blockInfo.Type = swapBytes(pCustumBlockInfo->Type);
+    blockInfo.fletcher = swapBytes(pCustumBlockInfo->fletcher);
+    blockInfo.length = swapBytes(pCustumBlockInfo->length);
+
+    if(checksum == blockInfo.fletcher)
+    {
+		memcpy (&HwInfo, hardwareDataGetPointer(), sizeof(SHardwareData)); /* create backup copy because data will be overwritten during flash erase */
+
+		bootloader_eraseFlashMemory();
+		bootloader_programFlashMemory(pSource, blockInfo.length, &HwInfo);
+    }
+	return UNSPECIFIC_RETURN;
+}
+
 /*
 uint8_t OnAction_TestCLog	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
--- a/Discovery/Src/tMenuEditXtra.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuEditXtra.c	Sat Nov 15 19:29:44 2025 +0100
@@ -41,6 +41,9 @@
 #include "tInfoPreDive.h"
 
 
+#define SCRUBBER_COUNT 2
+
+
 /* Private function prototypes -----------------------------------------------*/
 void openEdit_CompassHeading(void);
 void openEdit_ResetStopwatch(void);
@@ -62,6 +65,7 @@
 static uint8_t OnAction_ScrubberTimerMax(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 static uint8_t OnAction_ScrubberReset(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 static uint8_t OnAction_ScrubberMode(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+static uint8_t OnAction_ScrubberActive(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 #ifdef ENABLE_PSCR_MODE
 static uint8_t OnAction_PSCRO2Drop(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 static uint8_t OnAction_PSCRLungRation(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -69,6 +73,7 @@
 
 /* Exported functions --------------------------------------------------------*/
 
+static uint8_t scrubberMenuId = 0;
 
 void openEdit_Xtra(uint8_t line)
 {
@@ -194,84 +199,109 @@
 }
 
 
-static void printScrubberResetText(char *text, SSettings *settings)
+static void printScrubberResetText(char *text, SSettings *settings, uint8_t scrubberId, bool isActive)
 {
-    int16_t currentTimerMinutes = settings->scrubberData[settings->scubberActiveId].TimerCur;
-    char colour = '\020';
-    if (currentTimerMinutes <= 0) {
-        colour = '\025';
-    } else if (currentTimerMinutes <= 30) {
-        colour = '\024';
+    int16_t currentTimerMinutes = settings->scrubberData[scrubberId].TimerCur;
+
+    char *colour = "";
+    if (isActive) {
+        if (currentTimerMinutes <= 0) {
+            colour = "\025";
+        } else if (currentTimerMinutes <= 30) {
+            colour = "\024";
+        }
     }
-    snprintf(text, 32, "%c\002%c%03i\016\016 %c\017", TXT_ScrubTimeReset, colour, currentTimerMinutes, TXT_Minutes);
+    snprintf(text, 32, "%s%c\002%s%03i\016\016 %c\017", makeGrey(!isActive), TXT_ScrubTimeReset, colour, currentTimerMinutes, TXT_Minutes);
 }
 
 
+static void drawScrubberMenu(bool isRefresh)
+{
+    SSettings *settings = settingsGetPointer();
+
+    resetMenuContentStructure();
+
+	char text[32];
+    snprintf(text, 32, "%c \002#%d", TXT_ScrubTime, scrubberMenuId);
+    if (isRefresh) {
+        clean_content(20, 780, ME_Y_LINE1, &FontT48);
+    }
+    write_field_button(StMXTRA_ScrubTimer, 20, 780, ME_Y_LINE1, &FontT48, text);
+
+    bool currentScrubberIsActive = settings->scrubberActiveId & (1 << scrubberMenuId);
+
+    snprintf(text, 32, "%c %c \002%c", TXT_ScrubTime, TXT_Active, printCheckbox(currentScrubberIsActive));
+    if (isRefresh) {
+        clean_content(20, 780, ME_Y_LINE2, &FontT48);
+    }
+    write_field_button(StMXTRA_ScrubTimer_Active, 20, 780, ME_Y_LINE2, &FontT48, text);
+
+    snprintf(text, 32, "%s%c\016\016(%c)\017", makeGrey(!currentScrubberIsActive), TXT_ScrubTime, TXT_Maximum);
+    if (isRefresh) {
+        clean_content(20, 340, ME_Y_LINE3, &FontT48);
+    }
+    write_label_var(20, 340, ME_Y_LINE3, &FontT48, text);
+
+    uint16_t timerMax =  settings->scrubberData[scrubberMenuId].TimerMax;
+    if (isRefresh) {
+        clean_content(610, 780, ME_Y_LINE3, &FontT48);
+    }
+    if (currentScrubberIsActive) {
+        snprintf(text, 32, "%s\002###\016\016 %c\017", makeGrey(!currentScrubberIsActive), TXT_Minutes);
+        write_field_udigit(StMXTRA_ScrubTimer_Max, 610, 780, ME_Y_LINE3, &FontT48, text, timerMax, 0, 0, 0);
+    } else {
+        snprintf(text, 32, "%s\002%03i\016\016 %c\017", makeGrey(!currentScrubberIsActive), timerMax, TXT_Minutes);
+        write_label_var(610, 780, ME_Y_LINE3, &FontT48, text);
+    }
+
+    printScrubberResetText(text, settings, scrubberMenuId, currentScrubberIsActive);
+    if (isRefresh) {
+        clean_content(20, 780, ME_Y_LINE4, &FontT48);
+    }
+    if (currentScrubberIsActive) {
+        write_field_button(StMXTRA_ScrubTimer_Reset, 20, 780, ME_Y_LINE4, &FontT48, text);
+    } else {
+        write_label_var(20, 780, ME_Y_LINE4, &FontT48, text);
+    }
+
+    if (settings->scrubberData[scrubberMenuId].lastDive.WeekDay != 0) {
+        snprintf(text, 32, "%s%c%c\002       %02d.%02d.%02d", makeGrey(!currentScrubberIsActive), TXT_2BYTE, TXT2BYTE_SimDiveTime, settings->scrubberData[scrubberMenuId].lastDive.Date, settings->scrubberData[scrubberMenuId].lastDive.Month, settings->scrubberData[scrubberMenuId].lastDive.Year);
+    } else {
+        snprintf(&text[0], 32, "%s%c%c\002       --.--.--", makeGrey(!currentScrubberIsActive), TXT_2BYTE, TXT2BYTE_SimDiveTime);
+    }
+    if (isRefresh) {
+        clean_content(20, 780, ME_Y_LINE5, &FontT48);
+    }
+	write_label_var(20, 780, ME_Y_LINE5, &FontT48, text);
+
+    switch (settings->scrubTimerMode) {
+    	case SCRUB_TIMER_MINUTES:
+        default:					snprintf(text, 32, "%c\002%c", TXT_ScrubTimeMode, TXT_Minutes);
+        	break;
+        case SCRUB_TIMER_PERCENT:  	snprintf(text, 32, "%c\002%c", TXT_ScrubTimeMode, TXT_Percent);
+            break;
+    }
+    write_field_button(StMXTRA_ScrubTimer_OP_Mode, 20, 780, ME_Y_LINE6, &FontT48, text);
+
+    setEvent(StMXTRA_ScrubTimer, (uint32_t)OnAction_ScrubberTimerId);
+    setEvent(StMXTRA_ScrubTimer_Active, (uint32_t)OnAction_ScrubberActive);
+    setEvent(StMXTRA_ScrubTimer_Max, (uint32_t)OnAction_ScrubberTimerMax);
+    setEvent(StMXTRA_ScrubTimer_Reset, (uint32_t)OnAction_ScrubberReset);
+    setEvent(StMXTRA_ScrubTimer_OP_Mode, (uint32_t)OnAction_ScrubberMode);
+}
+
 static void openEdit_Scrubber(void)
 {
 	char text[32];
-	uint8_t textIndex = 0;
-    uint16_t localScrubTimer;
-
-    SSettings *pSettings = settingsGetPointer();
-
-    localScrubTimer =  pSettings->scrubberData[pSettings->scubberActiveId].TimerMax;
 
 	resetMenuEdit(CLUT_MenuPageXtra);
 
-
-	snprintf(&text[0], 32,"\001%c",TXT_ScrubTime);
+	snprintf(text, 32, "\001%c", TXT_ScrubTime);
     write_topline(text);
 
-
-    snprintf(&text[0], 32,"%c \002#%d",TXT_ScrubTime,pSettings->scubberActiveId);
-    write_field_button(StMXTRA_ScrubTimer, 20, 780, ME_Y_LINE1,  &FontT48, text);
-
-    snprintf(&text[textIndex], 32,\
-        "%c"
-    	"\016\016(%c)\017"
-        ,TXT_ScrubTime
-		,TXT_Maximum);
-
-    write_label_var(  20, 340, ME_Y_LINE2, &FontT48, text);
-    snprintf(&text[textIndex], 32, "\002###\016\016 %c\017",TXT_Minutes);
-
-    write_field_udigit(StMXTRA_ScrubTimer_Max,	 610, 780, ME_Y_LINE2,  &FontT48, text,localScrubTimer, 0, 0, 0);
-
-    printScrubberResetText(text, pSettings);
-    write_field_button(StMXTRA_ScrubTimer_Reset, 20, 780, ME_Y_LINE3,  &FontT48, text);
+    drawScrubberMenu(false);
 
-    if(pSettings->scrubberData[pSettings->scubberActiveId].lastDive.WeekDay != 0)
-    {
-    	snprintf(&text[0], 32,"%c%c\002       %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, 	pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Date,
-																				pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Month,
-																				pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Year);
-    }
-    else
-    {
-       	snprintf(&text[0], 32,"%c%c\002       --.--.--", TXT_2BYTE, TXT2BYTE_SimDiveTime);
-    }
-	write_label_var(  20, 780, ME_Y_LINE4, &FontT48, text);
-
-   	switch(pSettings->scrubTimerMode)
-    	{
-    		case SCRUB_TIMER_OFF:
-    		default: 	snprintf(&text[0], 32,"%c\002%c%c",TXT_ScrubTimeMode, TXT_2BYTE, TXT2BYTE_MoCtrlNone );
-    			break;
-    		case SCRUB_TIMER_MINUTES: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes );
-    			break;
-    		case SCRUB_TIMER_PERCENT: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent );
-    			break;
-    	}
-    write_field_button(StMXTRA_ScrubTimer_OP_Mode,	 20, 780, ME_Y_LINE5,  &FontT48, text);
-
-    setEvent(StMXTRA_ScrubTimer, (uint32_t)OnAction_ScrubberTimerId);
-    setEvent(StMXTRA_ScrubTimer_Max, (uint32_t)OnAction_ScrubberTimerMax);
-    setEvent(StMXTRA_ScrubTimer_Reset, (uint32_t)OnAction_ScrubberReset);
-    setEvent(StMXTRA_ScrubTimer_OP_Mode, (uint32_t)OnAction_ScrubberMode);
-
-    write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
-
+    write_buttonTextline(TXT2BYTE_ButtonBack, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonNext);
 }
 
 static void openEdit_PSCR(void)
@@ -460,40 +490,9 @@
 
 uint8_t OnAction_ScrubberTimerId(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
-	char text[32];
-	SSettings *pSettings;
-    pSettings = settingsGetPointer();
-
-    if(pSettings->scubberActiveId == 0)
-    {
-    	pSettings->scubberActiveId = 1;
-    }
-    else
-    {
-       	pSettings->scubberActiveId = 0;
-    }
-
-
-    snprintf(&text[0], 32,"%c \002#%d",TXT_ScrubTime,pSettings->scubberActiveId);
-    tMenuEdit_newButtonText(StMXTRA_ScrubTimer, text);
+    scrubberMenuId = (scrubberMenuId + 1) % SCRUBBER_COUNT;
 
-    printScrubberResetText(text, pSettings);
-    tMenuEdit_newButtonText(StMXTRA_ScrubTimer_Reset, text);
-
-    tMenuEdit_newInput(StMXTRA_ScrubTimer_Max, pSettings->scrubberData[pSettings->scubberActiveId].TimerMax,  0,  0, 0);
-
-    if(pSettings->scrubberData[pSettings->scubberActiveId].lastDive.WeekDay != 0)
-    {
-    	snprintf(&text[0], 32,"%c%c\002   %02d.%02d.%02d", TXT_2BYTE, TXT2BYTE_SimDiveTime, 	pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Date,
-																				pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Month,
-																				pSettings->scrubberData[pSettings->scubberActiveId].lastDive.Year);
-    }
-    else
-    {
-       	snprintf(&text[0], 32,"%c%c\002   --.--.--", TXT_2BYTE, TXT2BYTE_SimDiveTime);
-    }
-    clean_content(  20, 780, ME_Y_LINE4, &FontT48);
-	write_label_var(  20, 780, ME_Y_LINE4, &FontT48, text);
+    drawScrubberMenu(true);
 
     return UNSPECIFIC_RETURN;
 }
@@ -516,10 +515,10 @@
         	newScrubberTime = MAX_SCRUBBER_TIME;
 
         pSettings = settingsGetPointer();
-        pSettings->scrubberData[pSettings->scubberActiveId].TimerMax = newScrubberTime;
-        if(pSettings->scrubberData[pSettings->scubberActiveId].TimerCur > newScrubberTime)
+        pSettings->scrubberData[scrubberMenuId].TimerMax = newScrubberTime;
+        if(pSettings->scrubberData[scrubberMenuId].TimerCur > newScrubberTime)
         {
-        	pSettings->scrubberData[pSettings->scubberActiveId].TimerCur = newScrubberTime;
+        	pSettings->scrubberData[scrubberMenuId].TimerCur = newScrubberTime;
         }
 
         tMenuEdit_newInput(editId, newScrubberTime, 0, 0, 0);
@@ -542,19 +541,11 @@
 
 uint8_t OnAction_ScrubberReset(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
-	char text[32];
-	SSettings *pSettings;
-    pSettings = settingsGetPointer();
-    pSettings->scrubberData[pSettings->scubberActiveId].TimerCur = pSettings->scrubberData[pSettings->scubberActiveId].TimerMax;
-    pSettings->scrubberData[pSettings->scubberActiveId].lastDive.WeekDay = 0;	/* invalidate date */
+    SSettings *pSettings = settingsGetPointer();
+    pSettings->scrubberData[scrubberMenuId].TimerCur = pSettings->scrubberData[scrubberMenuId].TimerMax;
+    pSettings->scrubberData[scrubberMenuId].lastDive.WeekDay = 0;	/* invalidate date */
 
-    printScrubberResetText(text, pSettings);
-    tMenuEdit_newButtonText(StMXTRA_ScrubTimer_Reset, text);
-
-   	snprintf(&text[0], 32,"%c%c\002   --.--.--", TXT_2BYTE, TXT2BYTE_SimDiveTime);
-   	clean_content(  20, 780, ME_Y_LINE4, &FontT48);
-	write_label_var(  20, 780, ME_Y_LINE4, &FontT48, text);
-
+    drawScrubberMenu(true);
 
     return UNSPECIFIC_RETURN;
 }
@@ -566,27 +557,42 @@
 	SSettings *pSettings;
     pSettings = settingsGetPointer();
     newMode = pSettings->scrubTimerMode + 1;
-    if(newMode >= SCRUB_TIMER_END)
-    {
-   	 newMode = SCRUB_TIMER_OFF;
+    if (newMode >= SCRUB_TIMER_END) {
+        newMode = SCRUB_TIMER_MINUTES;
     }
     pSettings->scrubTimerMode = newMode;
 
-   	switch(pSettings->scrubTimerMode)
-    	{
-    		case SCRUB_TIMER_OFF:
-    		default: 	snprintf(&text[0], 32,"%c\002%c%c",TXT_ScrubTimeMode, TXT_2BYTE, TXT2BYTE_MoCtrlNone );
-    			break;
-    		case SCRUB_TIMER_MINUTES: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes );
-    			break;
-    		case SCRUB_TIMER_PERCENT: snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent );
-    			break;
-    	}
+    switch (pSettings->scrubTimerMode) {
+        case SCRUB_TIMER_MINUTES:
+        default:
+            snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Minutes );
+
+            break;
+        case SCRUB_TIMER_PERCENT:
+            snprintf(&text[0], 32,"%c\002%c",TXT_ScrubTimeMode, TXT_Percent );
+
+            break;
+    }
     tMenuEdit_newButtonText(StMXTRA_ScrubTimer_OP_Mode, text);
 
     return UNSPECIFIC_RETURN;
 }
 
+uint8_t OnAction_ScrubberActive(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+    SSettings *pSettings = settingsGetPointer();
+
+    if (pSettings->scrubberActiveId & (1 << scrubberMenuId)) {
+        pSettings->scrubberActiveId &= ~(1 << scrubberMenuId);
+    } else {
+        pSettings->scrubberActiveId |= (1 << scrubberMenuId);
+    }
+
+    drawScrubberMenu(true);
+
+    return UNSPECIFIC_RETURN;
+}
+
 #ifdef ENABLE_PSCR_MODE
 static uint8_t OnAction_PSCRO2Drop(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
--- a/Discovery/Src/tMenuHardware.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuHardware.c	Sat Nov 15 19:29:44 2025 +0100
@@ -29,6 +29,7 @@
 /* Includes ------------------------------------------------------------------*/
 #include "tMenu.h"
 #include "tMenuHardware.h"
+#include "ostc.h"
 
 //#define NEXTLINE(text, textPointer) 	{text[(textPointer)++] = '\n'; text[textPointer++] = '\r'; text[textPointer] = 0;}
 //	NEXTLINE(text,textPointer);
@@ -75,26 +76,6 @@
 
     if((line == 0) || (line == 2))
     {
-        text[textPointer++] = TXT_2BYTE;
-        text[textPointer++] = TXT2BYTE_Compass;
-        text[textPointer++] = '\t';
-
-        if(settingsGetPointer()->compassBearing != 0)
-        {
-            textPointer += snprintf(&text[textPointer], 20, "(%03u`)", settingsGetPointer()->compassBearing % 360);
-        }
-        text[textPointer] = 0;
-/*
-        textPointer += snprintf(&text[textPointer],20,"%i  %i  %i"
-            ,stateUsed->lifeData.compass_DX_f
-            ,stateUsed->lifeData.compass_DY_f
-            ,stateUsed->lifeData.compass_DZ_f);
-*/
-    }
-    nextline(text,&textPointer);
-
-    if((line == 0) || (line == 3))
-    {
         text[textPointer++] = TXT_o2Sensors;
         if((stateUsed->lifeData.ppO2Sensor_bar[0] != 0) || (stateUsed->lifeData.ppO2Sensor_bar[1] != 0) || (stateUsed->lifeData.ppO2Sensor_bar[2] != 0))
         {
@@ -118,7 +99,7 @@
     }
     nextline(text,&textPointer);
 
-    if((line == 0) || (line == 4))
+    if((line == 0) || (line == 3))
     {
         text[textPointer++] = TXT_Brightness;
         text[textPointer++] = '\t';
@@ -140,7 +121,7 @@
     }
     nextline(text,&textPointer);
 
-    if((line == 0) || (line == 5))
+    if((line == 0) || (line == 4))
     {
         text[textPointer++] = TXT_2BYTE;
         text[textPointer++] = TXT2BYTE_ButtonSensitivity;
@@ -160,17 +141,18 @@
     }
     nextline(text,&textPointer);
 
-    if((line == 0) || (line == 6))
+    if((isNewDisplay()) && ((line == 0) || (line == 5)))
     {
-            text[textPointer++] = TXT_2BYTE;
-            text[textPointer++] = TXT2BYTE_FLIPDISPLAY;
-            text[textPointer++] = '\t';
-            if(settingsGetPointer()->FlipDisplay)
-                text[textPointer++] = '\005';
-            else
-                text[textPointer++] = '\006';
-            text[textPointer] = 0;
-            nextline(text,&textPointer);
+		text[textPointer++] = TXT_2BYTE;
+		text[textPointer++] = TXT2BYTE_BUZZER;
+		text[textPointer++] = ' ';
+		text[textPointer++] = TXT_Warning;
+		text[textPointer++] = '\t';
+	    if(settingsGetPointer()->warningBuzzer)
+	            text[textPointer++] = '\005';
+	        else
+	            text[textPointer++] = '\006';
+	    nextline(text,&textPointer);
     }
 
     return StMHARD;
--- a/Discovery/Src/tMenuSystem.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/tMenuSystem.c	Sat Nov 15 19:29:44 2025 +0100
@@ -58,7 +58,7 @@
     textPointer = 0;
     *tab = 300;
     *subtext = 0;
-    char tmpString[15];
+    char tmpString[20];
 
     resetLineMask(StMSYS);
 
@@ -131,40 +131,32 @@
         text[textPointer++] = TXT_Date;
         getStringOfFormat_DDMMYY(tmpString,15);
         textPointer += snprintf(&text[textPointer], 40,"\016\016 %s ",tmpString);
-       convertStringOfDate_DDMMYY(tmpString,15,Sdate.Date, Sdate.Month, Sdate.Year);
+        convertStringOfDate_DDMMYY(tmpString,15,Sdate.Date, Sdate.Month, Sdate.Year);
         textPointer += snprintf(&text[textPointer], 40,"\017\t%s   ",tmpString);
-
-        textPointer += snprintf(&text[textPointer], 60,
-            "%02d:%02d:%02d"
-            "\n\r"
-            ,Stime.Hours, Stime.Minutes, Stime.Seconds
-        );
+        formatStringOfTime(tmpString,20,Stime,0,1);
+        textPointer += snprintf(&text[textPointer], 60,"%s\n\r",tmpString);
     }
     else
     {
         strcpy(&text[textPointer],"\n\r");
         textPointer += 2;
     }
-
-    if (line == 0 || line == 2)
+#ifdef ENABLE_SETTING_PROFILES
+    if((line == 0) || (line == 2))
+    {
+    	textPointer += snprintf(&text[textPointer], 40,"%c%c:\t%s\n\r",TXT_2BYTE,TXT2BYTE_Profile,data->profileName[data->activeProfile]);
+    }
+    else
     {
-    	if(t7_customview_disabled(CVIEW_Timer))
-    	{
-    		text[textPointer++] = '\031';		/* change text color */
-    	    textPointer += snprintf(&text[textPointer], 21, "%c%c\t%u:%02u \016\016[m:ss]\017\n\r", TXT_2BYTE, TXT2BYTE_Timer, data->timerDurationS / 60, data->timerDurationS % 60);
-    	    disableLine(StMSYS_Timer);
-            text[textPointer++] = '\020';		/* restore text color */
-    	}
-    	else
-    	{
-    		textPointer += snprintf(&text[textPointer], 21, "%c%c\t%u:%02u \016\016[m:ss]\017\n\r", TXT_2BYTE, TXT2BYTE_Timer, data->timerDurationS / 60, data->timerDurationS % 60);
-    	}
-    } else
-    {
-        textPointer += snprintf(&text[textPointer], 3, "\n\r");
+    	strcpy(&text[textPointer],"\n\r");
+    	textPointer += 2;
     }
-
+#endif
+#ifdef ENABLE_SETTING_PROFILES
     if((line == 0) || (line == 3))
+#else
+    if((line == 0) || (line == 2))
+#endif
     {
         text[textPointer++] = TXT_Language;
         text[textPointer++] = '\t';
@@ -178,8 +170,11 @@
         strcpy(&text[textPointer],"\n\r");
         textPointer += 2;
     }
-
+#ifdef ENABLE_SETTING_PROFILES
     if((line == 0) || (line == 4))
+#else
+    if((line == 0) || (line == 3))
+#endif
     {
         text[textPointer++] = TXT_2BYTE;
         text[textPointer++] = TXT2BYTE_Layout;
@@ -252,7 +247,11 @@
         textPointer += 2;
     }
 
+#ifdef ENABLE_SETTING_PROFILES
     if((line == 0) || (line == 5))
+#else
+    if((line == 0) || (line == 4))
+#endif
     {
         text[textPointer++] = TXT_Information;
         text[textPointer++] = '\t';
@@ -267,7 +266,11 @@
     strcpy(&text[textPointer],"\n\r");
     textPointer += 2;
 
+#ifdef ENABLE_SETTING_PROFILES
     if((line == 0) || (line == 6))
+#else
+    if((line == 0) || (line == 5))
+#endif
     {
         text[textPointer++] = TXT_2BYTE;
         text[textPointer++] = TXT2BYTE_ResetMenu;
@@ -278,19 +281,6 @@
 
     return StMSYS;
 }
-void tMSystem_checkLineStatus(void)
-{
-	uint8_t localLineMask = 0;
-	uint8_t lineMask = getLineMask(StMSYS);
 
-	if(t7_customview_disabled(CVIEW_Timer))
-    {
-    	localLineMask |= 1 << 2;
-    }
-	if(lineMask != localLineMask)
-	{
-		updateMenu();
-	}
-}
 
 /* Private functions ---------------------------------------------------------*/
--- a/Discovery/Src/text_multilanguage.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Discovery/Src/text_multilanguage.c	Sat Nov 15 19:29:44 2025 +0100
@@ -2005,6 +2005,18 @@
 static uint8_t text_IT_Reverse[] = "Invertire";
 static uint8_t text_ES_Reverse[] = "Invertir";
 
+static uint8_t text_EN_Pulse[] = "Heartbeat sensor (BT)";
+static uint8_t text_DE_Pulse[] = "Pulssensor (BT)";
+static uint8_t text_FR_Pulse[] = "";
+static uint8_t text_IT_Pulse[] = "";
+static uint8_t text_ES_Pulse[] = "";
+
+static uint8_t text_EN_Logger[] = "Debug Messages";
+static uint8_t text_DE_Logger[] = "Logger";
+static uint8_t text_FR_Logger[] = "";
+static uint8_t text_IT_Logger[] = "";
+static uint8_t text_ES_Logger[] = "";
+
 /* Lookup Table -------------------------------------------------------------*/
 
 const tText text_array[] =
@@ -2319,6 +2331,8 @@
  	{(uint8_t)TXT2BYTE_Log, 			{text_EN_Log, text_DE_Log, text_FR_Log, text_IT_Log, text_ES_Log}},
 	{(uint8_t)TXT2BYTE_Reverse, 		{text_EN_Reverse, text_DE_Reverse, text_FR_Reverse, text_IT_Reverse, text_ES_Reverse}},
 
+	{(uint8_t)TXT2BYTE_Pulse, 			{text_EN_Pulse, text_DE_Pulse, text_FR_Pulse, text_IT_Pulse, text_ES_Pulse}},
+	{(uint8_t)TXT2BYTE_Logger, 			{text_EN_Logger, text_DE_Logger, text_FR_Logger, text_IT_Logger, text_ES_Logger}},
 
 
 };
Binary file Documentations/hwos4_interface_v16.odt has changed
Binary file Documentations/hwos4_interface_v16.pdf has changed
--- a/OtherSources/data_central_mini.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/OtherSources/data_central_mini.c	Sat Nov 15 19:29:44 2025 +0100
@@ -111,10 +111,12 @@
 
 uint32_t	CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words)
 {
- cm_t        crc_model;
- uint32_t      word_to_do;
- uint8_t       byte_to_do;
- int         i;
+	 cm_t        crc_model;
+	 uint32_t      word_to_do;
+	 uint8_t       byte_to_do;
+	 int         i;
+
+	 uint32_t wordCnt = 0;
  
      // Values for the STM32F generator.
  
@@ -127,10 +129,10 @@
  
      cm_ini(&crc_model);
  
-     while (words--)
+     do
      {
          // The STM32F10x hardware does 32-bit words at a time!!!
-				if(words > (768000/4))
+				if(wordCnt >= (768000/4))
 					word_to_do = *buffer2++;
 				else
 					word_to_do = *buffer1++;
@@ -159,7 +161,8 @@
  
              cm_nxt(&crc_model, byte_to_do);
          }
-     }
+         wordCnt++;
+     } while (wordCnt != words);
  
      // Return the final result.
  
--- a/OtherSources/firmwareEraseProgram.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/OtherSources/firmwareEraseProgram.c	Sat Nov 15 19:29:44 2025 +0100
@@ -83,6 +83,9 @@
 
 #define SECTOR_SIZE_128KB     ((uint32_t)0x00020000) 
 
+#define FLASH_BOOT_START_ADDR   ADDR_FLASH_SECTOR_0
+#define FLASH_BOOT_END_ADDR     (ADDR_FLASH_SECTOR_5 - 1)
+
 #define FLASH_FW_START_ADDR   ADDR_FLASH_SECTOR_6
 #define FLASH_FW_END_ADDR     (ADDR_FLASH_SECTOR_12 - 1)
 
@@ -447,6 +450,133 @@
 	
 }
 
+
+uint8_t bootloader_eraseFlashMemory(void)
+{
+//	HAL_StatusTypeDef answer;
+  /* Unlock the Flash to enable the flash control register access *************/
+  HAL_FLASH_Unlock();
+
+  /* Erase the user Flash area
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+  /* Get the 1st sector to erase */
+  FirstSector = GetSector(FLASH_BOOT_START_ADDR);
+  /* Get the number of sector to erase from 1st sector*/
+  NbOfSectors = GetSector(FLASH_BOOT_END_ADDR) - FirstSector + 1;
+
+  /* Fill EraseInit structure*/
+  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
+  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
+  EraseInitStruct.Sector = FirstSector;
+  EraseInitStruct.NbSectors = NbOfSectors;
+
+  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
+     you have to make sure that these data are rewritten before they are accessed during code
+     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
+     DCRST and ICRST bits in the FLASH_CR register. */
+	return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
+}
+
+uint8_t bootloader_programFlashMemory(uint8_t *pBuffer1, uint32_t length1, SHardwareData* pHwInfo)
+{
+	HAL_StatusTypeDef answer;
+
+  /* Program the user Flash area word by word
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+	uint32_t index = 0;
+	Address = FLASH_BOOT_START_ADDR;
+
+	uint8_t* pHardwareInfo = (uint8_t*) pHwInfo;
+	uint8_t tmp = 0;
+
+	index = 0;
+	while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
+	{
+		if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
+		{
+			answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, *pHardwareInfo++);
+		}
+		else
+		{
+			answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[index]);
+		}
+		if (answer == HAL_OK)
+		{
+			Address = Address + 1;
+			index++;
+		}
+		else
+		{
+				return answer;
+		}
+	}
+  /* Lock the Flash to disable the flash control register access (recommended
+     to protect the FLASH memory against possible unwanted operation) *********/
+	HAL_FLASH_Lock();
+
+  /* Check if the programmed data is OK
+      MemoryProgramStatus = 0: data programmed correctly
+      MemoryProgramStatus != 0: number of words not programmed correctly ******/
+	Address = FLASH_BOOT_START_ADDR;
+	MemoryProgramStatus = 0x0;
+
+	index = 0;
+	pHardwareInfo = (uint8_t*) pHwInfo;
+
+	while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
+	{
+		if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
+		{
+			tmp = *pHardwareInfo++;
+		}
+		else
+		{
+			tmp = pBuffer1[index];
+		}
+
+		data32 = *(__IO uint8_t*)Address;
+		if (data32 != tmp)
+		{
+			MemoryProgramStatus++;
+		}
+
+		Address = Address + 1;
+		index++;
+	}
+  /* Check if there is an issue to program data */
+	if (MemoryProgramStatus == 0)
+	{
+		return HAL_OK;
+    /* No error detected. Switch on LED3 */
+	}
+	else
+	{
+		return 0xEE;
+	}
+}
+
+
+uint32_t CalcFletcher32(uint32_t startAddr, uint32_t endAddr)
+{
+	uint32_t fletcher = 0;
+	uint16_t* pData = (uint16_t*) startAddr;
+	uint32_t index = 0;
+
+	uint16_t sum1 = 0;
+	uint16_t sum2 = 0;
+	for(index = startAddr; index <= endAddr; index +=2)
+	{
+		sum1 = sum1 + *pData++;
+	    sum2 = (sum2 + sum1);
+	}
+	fletcher = (sum2 << 16) | sum1;
+
+	return fletcher;
+}
+
+
 /* Private functions ---------------------------------------------------------*/
 
 /**
--- a/Small_CPU/Inc/GNSS.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/GNSS.h	Sat Nov 15 19:29:44 2025 +0100
@@ -101,6 +101,44 @@
 
 GNSS_StateHandle GNSS_Handle;
 
+typedef struct {
+	uint8_t header1;
+	uint8_t header2;
+    uint8_t msgClass;
+    uint8_t msgID;
+    uint16_t length;
+    uint8_t type;
+    uint8_t version;
+    uint8_t ref;
+    uint8_t leapsec;
+    uint16_t year;
+    uint8_t month;
+    uint8_t day;
+    uint8_t hour;
+    uint8_t minute;
+    uint8_t second;
+    uint8_t flags;
+    uint32_t nanoseconds;
+    uint16_t accuracy_seconds;
+    uint16_t reserved;
+    uint32_t accuracy_nano;
+}  __attribute__((packed)) UBX_MGA_INI_TIME_UTC_t;
+
+typedef struct {
+    uint8_t header1;
+    uint8_t header2;
+    uint8_t class_id;
+    uint8_t msg_id;
+    uint16_t length;
+    uint8_t type;
+    uint8_t version;
+    uint16_t reserved;
+    int32_t latitude;
+    int32_t longitude;
+    int32_t altitude;
+    uint32_t accuracy;
+} __attribute__((packed)) UBX_MGA_INI_POS_LLH_t;
+
 
 enum GNSSMode{Portable=0, Stationary=1, Pedestrian=2, Automotiv=3, Airbone1G=5, Airbone2G=6,Airbone4G=7,Wirst=8,Bike=9};
 
@@ -125,11 +163,13 @@
 
 static const uint8_t setPowerNormal[]={0xB5,0x62,0x06,0x86,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
+/* UBX-CFG-NAV5 */
 static const uint8_t setPortableMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x00,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
 static const uint8_t setPedestrianMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
 static const uint8_t setConfig[]={0xB5,0x62,0x06,0x09,0x0D,0x00, 0x00,0x00,0x00,0x00, 0x18,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x01};
+/* UBX-MGA-INI-TIME_UTC */
+static const uint8_t setDateTime[] = {0xB5,0x62,0x13,0x40,0x18,0x00,0x10,0x00,0x00,0x80,0x07,0xE9,0x01,0x02,0x03,0x04,0x05,0x00,0x01,0x02,0x03,0x04,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00};
 
 static const uint8_t setPortableType[]={};
 void GNSS_Init(GNSS_StateHandle *GNSS, UART_HandleTypeDef *huart);
--- a/Small_CPU/Inc/externalInterface.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/externalInterface.h	Sat Nov 15 19:29:44 2025 +0100
@@ -72,7 +72,7 @@
 	DETECTION_CO2_2,
 	DETECTION_CO2_3,
 #endif
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 	DETECTION_GNSS_0,			/* check UART channel for connected gnss sensor */
 	DETECTION_GNSS_1,
 	DETECTION_GNSS_2,
--- a/Small_CPU/Inc/gpio.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/gpio.h	Sat Nov 15 19:29:44 2025 +0100
@@ -38,7 +38,7 @@
 void GPIO_Power_MainCPU_ON(void);
 void GPIO_Power_MainCPU_OFF(void);
 
-#ifdef ENABLE_GPIO_V2
+
 void GPIO_LED_RED_OFF(void);
 void GPIO_LED_RED_ON(void);
 void GPIO_LED_GREEN_OFF(void);
@@ -50,11 +50,13 @@
 void GPIO_GPS_BCKP_OFF(void);
 void GPIO_GPS_BCKP_ON(void);
 
+uint8_t GPIO_GetVersion(void);
+void GPIO_Activate_V2(void);
+void GPIO_Init_V2(void);
 void GPIO_HandleBuzzer();
 #endif
 #ifdef __cplusplus
 }
-#endif
 #endif /* GPIO_H */
 
 
--- a/Small_CPU/Inc/rtc.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/rtc.h	Sat Nov 15 19:29:44 2025 +0100
@@ -41,6 +41,7 @@
 void RTC_SetDate(RTC_DateTypeDef sdatestructure);
 
 void RTC_GetTime(RTC_TimeTypeDef* pstimestructure);
+void RTC_GetDate(RTC_DateTypeDef* psdatestructure);
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Inc/uart.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/uart.h	Sat Nov 15 19:29:44 2025 +0100
@@ -68,7 +68,7 @@
 void DigitalCO2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint8_t *cmdLength);
 #endif
 
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 void UART_HandleGnssData(void);
 #endif
 #ifdef ENABLE_SENTINEL_MODE
--- a/Small_CPU/Inc/uartProtocol_GNSS.h	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Inc/uartProtocol_GNSS.h	Sat Nov 15 19:29:44 2025 +0100
@@ -42,6 +42,8 @@
 		UART_GNSS_LOADCONF_1,
 		UART_GNSS_LOADCONF_2,
 		UART_GNSS_SETMODE_MOBILE,
+		UART_GNSS_SETDATE_TIME,
+		UART_GNSS_SET_POSITION,
 		UART_GNSS_PWRDOWN,
 		UART_GNSS_PWRUP,
 		UART_GNSS_SETCONF,		/* save configuration */
@@ -74,6 +76,8 @@
 	GNSSCMD_LOADCONF_1,
 	GNSSCMD_LOADCONF_2,
 	GNSSCMD_SETMOBILE,
+	GNSSCMD_SETDATETIME,
+	GNSSCMD_SET_POSITION,
 	GNSSCMD_MODE_PWS,
 	GNSSCMD_MODE_NORMAL,
 	GNSSCMD_SET_CONFIG,
--- a/Small_CPU/Src/baseCPU2.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/baseCPU2.c	Sat Nov 15 19:29:44 2025 +0100
@@ -172,7 +172,7 @@
 // See CPU2-RTE.ld
 const SFirmwareData cpu2_FirmwareData __attribute__(( section(".firmware_data") ))= {
 		.versionFirst = 3,
-		.versionSecond = 4,
+		.versionSecond = 7,
 		.versionThird = 0,
 		.versionBeta = 0,
 
@@ -180,8 +180,8 @@
 		.signature = "mh",
 
 		.release_year = 25,
-		.release_month = 1,
-		.release_day = 18,
+		.release_month = 6,
+		.release_day = 9,
 		.release_sub = 0,
 
 		/* max 48 with trailing 0 */
@@ -285,8 +285,6 @@
 	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
 
 	MX_RTC_init();
-	GPIO_LEDs_VIBRATION_Init();
-	GPIO_GNSS_Init();
 	GPIO_new_DEBUG_Init(); // added 170322 hw
 	initGlobals();
 
@@ -402,46 +400,19 @@
 
 			if (global.mode == MODE_BOOT) {
 				GPIO_Power_MainCPU_OFF();
-#ifdef ENABLE_GPIO_V2
-				GPIO_LED_GREEN_ON();
-#endif
 				HAL_Delay(100); // for GPIO_Power_MainCPU_ON();
 				GPIO_Power_MainCPU_ON();
-#ifdef ENABLE_GPIO_V2
-				GPIO_LED_GREEN_OFF();
-
-				GPIO_LED_RED_ON();
-				GPIO_VIBRATION_ON();
-#endif
 				HAL_Delay(100);
-#ifdef ENABLE_GPIO_V2
-				GPIO_LED_RED_OFF();
-				GPIO_VIBRATION_OFF();
-#endif
 			}
-#ifdef ENABLE_GPIO_V2
-			GPIO_LED_RED_OFF();
-			GPIO_LED_GREEN_OFF();
-			GPIO_VIBRATION_OFF();
-#endif
 			SPI_synchronize_with_Master();
 			MX_DMA_Init();
 			MX_SPI1_Init();
 			SPI_Start_single_TxRx_with_Master(); /* be prepared for the first data exchange */
 			Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD);
 
-#ifdef ENABLE_GPIO_V2
-			// GNSS tests
-			GNSS_IO_init();
-			GPIO_GPS_ON();
-			GPIO_GPS_BCKP_ON();
-			MX_USART6_UART_Init();
-			GNSS_Init(&GNSS_Handle, &huart6);
-#else
-#ifdef  ENABLE_GNSS_SUPPORT
+#ifdef  ENABLE_GNSS_EXTERN
 			GNSS_Init(&GNSS_Handle, &huart1);
 #endif
-#endif
 
 			global.mode = MODE_SURFACE;
 			break;
@@ -466,8 +437,11 @@
             global.no_fly_time_minutes = 0;
             global.lifeData.dive_time_seconds = 0;
             global.lifeData.dive_time_seconds_without_surface_time = 0;
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
-            uartGnss_ReqPowerDown(1);
+#if defined ENABLE_GNSS_INTERN
+            if(GPIO_GetVersion() > 0)
+            {
+            	uartGnss_ReqPowerDown(1);
+            }
 #endif
             scheduleDiveMode();
             // done now in scheduler prior to change mode: global.seconds_since_last_dive = 1;
@@ -494,8 +468,11 @@
 
             backup.no_fly_time_minutes = 0;
             backup.seconds_since_last_dive = 0;
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
-            uartGnss_ReqPowerDown(0);
+#if defined ENABLE_GNSS_INTERN
+            if(GPIO_GetVersion() > 0)
+            {
+            	uartGnss_ReqPowerDown(0);
+            }
 #endif
 			break;
 
@@ -504,27 +481,43 @@
 
 			MX_SPI3_Init();
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
-			if(shutdownTick == 0)
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
+
+		do
+		{
+			if(GPIO_GetVersion() > 0)
 			{
-				shutdownTick = HAL_GetTick();
-				uartGnss_ReqPowerDown(1);
+				if(shutdownTick == 0)
+				{
+					shutdownTick = HAL_GetTick();
+					uartGnss_ReqPowerDown(1);
+				}
 			}
-#ifdef ENABLE_GNSS_SUPPORT
+#endif
+#ifdef ENABLE_GNSS_EXTERN
 			externalInterface_HandleUART();
 #else
-			UART6_HandleUART();
+#ifdef ENABLE_GNSS_INTERN
+			if(GPIO_GetVersion() > 0)
+			{
+				UART6_HandleUART();
+			}
 #endif
-			if((uartGnss_GetState() == UART_GNSS_INACTIVE) || (time_elapsed_ms(shutdownTick,HAL_GetTick()) > 3000))
+#endif
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
+			if((uartGnss_GetState() == UART_GNSS_INACTIVE) || (time_elapsed_ms(shutdownTick,HAL_GetTick()) > 4000))
 			{
 				global.mode = MODE_SLEEP;
 				uartGnss_ReqPowerDown(0);	/* release power down request */
+				uartGnss_SetState(UART_GNSS_INACTIVE);
 			}
+
 #else
 			global.mode = MODE_SLEEP;
 #endif
-
-
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
+		}while (global.mode == MODE_SHUTDOWN);
+#endif
 			break;
 
 		case MODE_SLEEP:
@@ -533,7 +526,6 @@
 			externalInterface_SwitchPower33(false);
 			if (hasExternalClock())
 				SystemClock_Config_HSI();
-			GPIO_LEDs_VIBRATION_Init();
 			sleep_prepare();
 
 			while(time_elapsed_ms(shutdownTick,HAL_GetTick()) < 1000 )	/* delay shutdown till shutdown animation is finished */
@@ -542,6 +534,8 @@
 			}
 			shutdownTick = 0;
 			scheduleSleepMode();
+
+			/* wakeup starts here */
 			if (hasExternalClock())
 				SystemClock_Config_HSE();
 			EXTI_Wakeup_Button_DeInit();
@@ -560,6 +554,7 @@
 				externalInterface_SwitchPower33(true);
 			}
 			externalInterface_InitDatastruct();
+			GPIO_Init_V2();
 			// EXTILine0_Button_DeInit(); not now, later after testing
 			break;
 		}
@@ -888,6 +883,9 @@
 }
 
 void sleep_prepare(void) {
+
+	GPIO_InitTypeDef GPIO_InitStruct;
+
 	EXTI_Wakeup_Button_Init();
 
 	compass_sleep();
@@ -900,7 +898,12 @@
 	MX_SPI3_DeInit();
 	ADCx_DeInit();
 
-	GPIO_InitTypeDef GPIO_InitStruct;
+	if(GPIO_GetVersion() > 0)
+	{
+		GPIO_LED_GREEN_OFF();
+		GPIO_LED_RED_OFF();
+		GPIO_VIBRATION_OFF();
+	}
 
 	__HAL_RCC_GPIOA_CLK_ENABLE();
 	__HAL_RCC_GPIOB_CLK_ENABLE();
@@ -912,41 +915,41 @@
 	GPIO_InitStruct.Pull = GPIO_NOPULL;
 	GPIO_InitStruct.Pin = GPIO_PIN_All;
 	HAL_GPIO_Init( GPIOH, &GPIO_InitStruct);
+
 #ifdef ENABLE_SLEEP_DEBUG
 	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_3 | GPIO_PIN_8 | GPIO_PIN_9); /* debug */
 #endif
 
-/*
+#ifdef ENABLE_GNSS_INTERN
 	GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_POWER_CONTROL_PIN | GPS_BCKP_CONTROL_PIN);
+#else
+	GPIO_InitStruct.Pin = GPIO_PIN_All;
+#endif
 	HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
-*/
+
 	GPIO_InitStruct.Pin =  GPIO_PIN_All ^ ( MAINCPU_CONTROL_PIN | CHARGE_OUT_PIN | EXT33V_CONTROL_PIN); /* power off & charger in & charge out & OSC32 & ext33Volt */
-
 	HAL_GPIO_Init( GPIOC, &GPIO_InitStruct);
 
-	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0 | VIBRATION_CONTROL_PIN | LED_CONTROL_PIN_RED | LED_CONTROL_PIN_GREEN);
+	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0 ); /* could be added for debug purpose: | VIBRATION_CONTROL_PIN | LED_CONTROL_PIN_RED | LED_CONTROL_PIN_GREEN */
 #ifdef ENABLE_SLEEP_DEBUG
 	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0 | GPIO_PIN_13 | GPIO_PIN_14); /* wake up button & debug */
 #endif
 	HAL_GPIO_Init( GPIOA, &GPIO_InitStruct);
 
-	GPIO_InitStruct.Pin = GPIO_PIN_All;
-	HAL_GPIO_Init( GPIOH, &GPIO_InitStruct);
+	GPIO_Power_MainCPU_OFF();
 
-	GPIO_Power_MainCPU_OFF();
-#ifdef ENABLE_GPIO_V2
-	GPIO_LED_GREEN_OFF();
-	GPIO_LED_RED_OFF();
-	GPIO_VIBRATION_OFF();
-	GPIO_GPS_BCKP_ON();			// mH : costs 100µA in sleep - beware
-/*	GPIO_GPS_OFF();				will be done in transition sleep => deep sleep */
-
-	MX_USART6_UART_DeInit();
+#ifdef ENABLE_GNSS_INTERN
+	if(GPIO_GetVersion() > 0)
+	{
+		GPIO_GPS_BCKP_ON();			// mH : costs 100µA in sleep - beware
+		/*	GPIO_GPS_OFF();				will be done in transition sleep => deep sleep */
+		MX_USART6_UART_DeInit();
+	}
 #endif
 #ifndef ENABLE_SLEEP_DEBUG
-/*
+#ifndef ENABLE_GNSS_INTERN
 	__HAL_RCC_GPIOB_CLK_DISABLE();
-*/
+#endif
 #endif
 	__HAL_RCC_GPIOH_CLK_DISABLE();
 }
--- a/Small_CPU/Src/compass.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/compass.c	Sat Nov 15 19:29:44 2025 +0100
@@ -86,6 +86,17 @@
 int16_t compass_CZ_f; ///< calibration value
 
 
+float compass_DX_min;
+float compass_DX_max;
+
+float compass_DY_min;
+float compass_DY_max;
+
+float compass_DZ_min;
+float compass_DZ_max;
+
+
+
 /// The (filtered) components of the accelerometer sensor
 int16_t accel_DX_f; ///< output from sensor
 int16_t accel_DY_f; ///< output from sensor
@@ -1070,8 +1081,25 @@
 //  ===============================================================================
 void compass_calc_roll_pitch_only(void)
 {
-	 float sinPhi, cosPhi;
+	 float sinPhi, cosPhi, sinTeta, cosTeta;
 	 float Phi, Teta;
+	 float mx_corr, my_corr;
+
+	 float offsetX, offsetY, offsetZ;
+	 float scaleX, scaleY,scaleZ;
+
+	 float local_DX = compass_DX_f;
+	 float local_DY = compass_DY_f;
+	 float local_DZ = compass_DZ_f;
+
+
+	 if(local_DX < compass_DX_min) compass_DX_min = local_DX;
+	 if(local_DY < compass_DY_min) compass_DY_min = local_DY;
+	 if(local_DZ < compass_DZ_min) compass_DZ_min = local_DZ;
+
+	 if(local_DX > compass_DX_max) compass_DX_max = local_DX;
+	 if(local_DY > compass_DY_max) compass_DY_max = local_DY;
+	 if(local_DZ > compass_DZ_max) compass_DZ_max = local_DZ;
 
 	//---- Calculate sine and cosine of roll angle Phi -----------------------
 	Phi= atan2f(accel_DY_f, accel_DZ_f) ;
@@ -1079,9 +1107,38 @@
 	sinPhi = sinf(Phi);
 	cosPhi = cosf(Phi);
 
-	//---- calculate sin and cosine of pitch angle Theta ---------------------
 	Teta = atanf(-(float)accel_DX_f/(accel_DY_f * sinPhi + accel_DZ_f * cosPhi));
-	compass_pitch = Teta * 180.0f /PI;
+	compass_pitch = Teta * (180.0 / PI);
+
+	sinTeta = sinf(Teta);
+	cosTeta = cosf(Teta);
+
+	offsetX = (compass_DX_max + compass_DX_min) / 2.0;
+	offsetY = (compass_DY_max + compass_DY_min) / 2.0;
+	offsetZ = (compass_DZ_max + compass_DZ_min) / 2.0;
+
+	scaleX = 2.0 / (compass_DX_max - compass_DX_min);
+	scaleY = 2.0 / (compass_DY_max - compass_DY_min);
+	scaleZ = 2.0 / (compass_DZ_max - compass_DZ_min);
+
+	local_DX -= offsetX;
+	local_DX *= scaleX;
+
+	local_DY -= offsetY;
+	local_DY *= scaleY;
+
+	local_DZ -= offsetZ;
+	local_DZ *= scaleZ;
+
+	mx_corr = local_DX * cosTeta + local_DZ * sinTeta;
+	my_corr = local_DX * sinPhi * sinTeta + local_DY * cosPhi - local_DZ * sinPhi * cosTeta;
+
+	compass_heading = atan2(my_corr, mx_corr) * (180.0 / PI);
+
+
+    if (compass_heading < 0) {
+    	compass_heading += 360.0;
+    }
 }
 
 
@@ -1172,6 +1229,14 @@
     g->Suuu = g->Svvv = g->Swww = 0.0;
     g->Suuv = g->Suuw = g->Svvu = g->Svvw = g->Swwu = g->Swwv = 0.0;
     compass_CX_f = compass_CY_f = compass_CZ_f = 0.0;
+
+    compass_DX_min = 10000;
+    compass_DY_min = 10000;
+    compass_DZ_min = 10000;
+
+    compass_DX_max = -10000;
+    compass_DY_max = -10000;
+    compass_DZ_max = -10000;
 }
 
 
--- a/Small_CPU/Src/externalInterface.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/externalInterface.c	Sat Nov 15 19:29:44 2025 +0100
@@ -401,7 +401,7 @@
 #ifdef ENABLE_CO2_SUPPORT
 					|| ((externalAutoDetect >= DETECTION_CO2_0) && (externalAutoDetect <= DETECTION_CO2_3))
 #endif
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 					|| ((externalAutoDetect >= DETECTION_GNSS_0) && (externalAutoDetect <= DETECTION_GNSS_3))
 #endif
 
@@ -672,7 +672,7 @@
 {
 	static uint8_t sensorIndex = 0;
 	static uint8_t uartMuxChannel = 0;
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 static	uint8_t detectionDelayCnt = 0;
 #endif
 	uint8_t index = 0;
@@ -829,7 +829,7 @@
 			case DETECTION_CO2_3:	if(uartCo2_isSensorConnected())
 									{
 										foundSensorMap[EXT_INTERFACE_MUX_OFFSET + activeUartChannel] = SENSOR_CO2;
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 										externalAutoDetect = DETECTION_GNSS_0;	/* only one CO2 sensor supported */
 #else
 										externalAutoDetect = DETECTION_DONE;	/* only one CO2 sensor supported */
@@ -852,8 +852,8 @@
 									{
 
 
-#if defined ENABLE_SENTINEL_MODE || defined ENABLE_GNSS_SUPPORT
-#ifdef ENABLE_GNSS_SUPPORT
+#if defined ENABLE_SENTINEL_MODE || defined ENABLE_GNSS_EXTERN
+#ifdef ENABLE_GNSS_EXTERN
 										externalAutoDetect = DETECTION_GNSS_0;
 										externalInterface_SwitchUART(EXT_INTERFACE_UART_GNSS);
 #else
@@ -867,7 +867,7 @@
 									}
 #endif
 
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 									if(externalAutoDetect == DETECTION_GNSS_0)
 									{
 										tmpSensorMap[uartMuxChannel + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
@@ -1251,7 +1251,7 @@
 				case SENSOR_CO2:	uartCo2_Control();
 					break;
 #endif
-#ifdef ENABLE_GNSS_SUPPORT
+#ifdef ENABLE_GNSS_EXTERN
 				case SENSOR_GNSS:	uartGnss_Control();
 						break;
 #endif
--- a/Small_CPU/Src/gpio.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/gpio.c	Sat Nov 15 19:29:44 2025 +0100
@@ -25,10 +25,12 @@
 #include "gpio.h"
 #include "data_exchange.h"
 #include "scheduler.h"
+#include "uart_Internal.h"
+#include "GNSS.h"
 
 /* Exported variables --------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-
+static uint8_t GPIO_Version = 0;
 /* Private types -------------------------------------------------------------*/
 
 /* Private function prototypes -----------------------------------------------*/
@@ -91,7 +93,6 @@
 	HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_RESET);
 }
 
-#ifdef ENABLE_GPIO_V2
 void GPIO_HandleBuzzer()
 {
 	static uint32_t buzzerOnTick = 0;
@@ -124,7 +125,7 @@
 		buzzerWasOn = 0;
 	}
 }
-#endif
+
 void GPIO_Power_MainCPU_ON(void) {
 	HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_RESET);
 }
@@ -133,7 +134,6 @@
 	HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_SET);
 }
 
-#ifdef ENABLE_GPIO_V2
 void GPIO_LED_GREEN_ON(void) {
 	HAL_GPIO_WritePin( GPIOA, LED_CONTROL_PIN_GREEN, GPIO_PIN_RESET);
 }
@@ -173,8 +173,34 @@
 void GPIO_GPS_BCKP_OFF(void) {
 	HAL_GPIO_WritePin( GPIOB, GPS_BCKP_CONTROL_PIN, GPIO_PIN_RESET);
 }
+
+uint8_t GPIO_GetVersion()
+{
+	return GPIO_Version;
+}
+
+void GPIO_Activate_V2(void)
+{
+	if(GPIO_Version == 0)
+	{
+		GPIO_Version = 1;
+	}
+}
+
+void GPIO_Init_V2(void)
+{
+	if(GPIO_Version == 1)
+	{
+		GPIO_LEDs_VIBRATION_Init();
+#ifdef ENABLE_GNSS_INTERN
+		GNSS_IO_init();
+		GPIO_GPS_ON();
+		GPIO_GPS_BCKP_ON();
+		MX_USART6_UART_Init();
+		GNSS_Init(&GNSS_Handle, &huart6);
 #endif
-
+	}
+}
 /* Private functions ---------------------------------------------------------*/
 
 
--- a/Small_CPU/Src/rtc.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/rtc.c	Sat Nov 15 19:29:44 2025 +0100
@@ -35,6 +35,11 @@
 	HAL_RTC_GetTime(&RTCHandle, pstimestructure, RTC_FORMAT_BIN);
 }
 
+void RTC_GetDate(RTC_DateTypeDef* psdatestructure)
+{
+	HAL_RTC_GetDate(&RTCHandle, psdatestructure, RTC_FORMAT_BIN);
+}
+
 void RTC_SetTime(RTC_TimeTypeDef stimestructure)
 {
 
--- a/Small_CPU/Src/scheduler.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/scheduler.c	Sat Nov 15 19:29:44 2025 +0100
@@ -342,9 +342,17 @@
 	{
 		externalInterface_ExecuteCmd(global.dataSendToSlave.data.externalInterface_Cmd);
 	}
-#ifdef ENABLE_GPIO_V2
-	GPIO_HandleBuzzer();
-#endif
+
+	if(GPIO_GetVersion() < global.dataSendToSlave.displayVersion)
+	{
+		GPIO_Activate_V2();
+		GPIO_Init_V2();
+	}
+
+	if(GPIO_GetVersion() > 0)
+	{
+		GPIO_HandleBuzzer();
+	}
 
 
 #if 0
@@ -533,8 +541,11 @@
 		ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick);
 
 		externalInterface_HandleUART();
-#ifdef ENABLE_GPIO_V2
-		UART6_HandleUART();
+#ifdef ENABLE_GNSS_INTERN
+		if(GPIO_GetVersion() > 0)
+		{
+			UART6_HandleUART();
+		}
 #endif
 		if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10)
 		{
@@ -838,8 +849,11 @@
 		}
 
 		externalInterface_HandleUART();
-#ifdef ENABLE_GPIO_V2
-		UART6_HandleUART();
+#ifdef ENABLE_GNSS_INTERN
+		if(GPIO_GetVersion() > 0)
+		{
+			UART6_HandleUART();
+		}
 #endif
 
 		/* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */
@@ -893,7 +907,7 @@
 			adc_ambient_light_sensor_get_data();
 			copyAmbientLightData();
 
-#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 			copyGNSSdata();
 #endif
 			Scheduler.counterAmbientLight100msec++;
@@ -1110,7 +1124,7 @@
 	global.dataSendToMaster.mode = 0;
 	global.deviceDataSendToMaster.mode = 0;
 	secondsCount = 0;
-#ifdef ENABLE_GPIO_V2
+#ifdef ENABLE_GNSS_INTERN
 	uint16_t deepSleepCntDwn = 21600; 	/* 12 hours in 2 second steps */
 	uint8_t deepSleep = 0;
 	GPIO_InitTypeDef GPIO_InitStruct;
@@ -1191,31 +1205,34 @@
 			global.mode = MODE_BOOT;
 		}
 		scheduleUpdateLifeData(2000);
-#ifdef ENABLE_GPIO_V2
-		if(deepSleepCntDwn)
+#ifdef ENABLE_GNSS_INTERN
+		if(GPIO_GetVersion() > 0)
 		{
-			deepSleepCntDwn--;
-			if(deepSleepCntDwn == 0)
+			if(deepSleepCntDwn)
 			{
-				deepSleep = 1;
-				GPIO_GPS_OFF();
-				GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-				GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-				GPIO_InitStruct.Pull = GPIO_NOPULL;
-				GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_POWER_CONTROL_PIN);
-				HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
-				uartGnss_SetState(UART_GNSS_INIT);
+				deepSleepCntDwn--;
+				if(deepSleepCntDwn == 0)
+				{
+					deepSleep = 1;
+					GPIO_GPS_OFF();
+					GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+					GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+					GPIO_InitStruct.Pull = GPIO_NOPULL;
+					GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_POWER_CONTROL_PIN);
+					HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
+					uartGnss_SetState(UART_GNSS_INIT);
+				}
 			}
-		}
-		else
-		{
-			if((deepSleep = 1) && (global.lifeData.battery_voltage < 3.5))	/* switch off backup voltage if battery gets low */
+			else
 			{
-				deepSleep = 2;
-				GPIO_GPS_BCKP_OFF();
-				GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_BCKP_CONTROL_PIN);
-				HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
-				__HAL_RCC_GPIOB_CLK_DISABLE();
+				if((deepSleep = 1) && (global.lifeData.battery_voltage < 3.5))	/* switch off backup voltage if battery gets low */
+				{
+					deepSleep = 2;
+					GPIO_GPS_BCKP_OFF();
+					GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_BCKP_CONTROL_PIN);
+					HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
+					__HAL_RCC_GPIOB_CLK_DISABLE();
+				}
 			}
 		}
 #endif
@@ -1227,10 +1244,17 @@
 	setButtonsNow = 0;
 	reinitGlobals();
 	ReInit_battery_charger_status_pins();
-#ifdef ENABLE_GPIO_V2
-	if(deepSleep != 0)
+#ifdef ENABLE_GNSS_INTERN
+	if(GPIO_GetVersion() > 0)
 	{
-		GPIO_GNSS_Init();
+		if(deepSleep != 0)
+		{
+			GPIO_GNSS_Init();
+		}
+		else
+		{
+			GNSS_IO_init();
+		}
 	}
 #endif
 }
--- a/Small_CPU/Src/stm32f4xx_it_v3.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/stm32f4xx_it_v3.c	Sat Nov 15 19:29:44 2025 +0100
@@ -61,9 +61,11 @@
 extern UART_HandleTypeDef huart1;
 extern DMA_HandleTypeDef  hdma_usart1_rx;
 extern DMA_HandleTypeDef  hdma_usart1_tx;
+#ifdef ENABLE_GNSS_INTERN
 extern UART_HandleTypeDef huart6;
 extern DMA_HandleTypeDef  hdma_usart6_rx;
 extern DMA_HandleTypeDef  hdma_usart6_tx;
+#endif
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
@@ -249,7 +251,7 @@
   HAL_DMA_IRQHandler(&hdma_usart1_tx);
 }
 
-#ifdef ENABLE_GPIO_V2
+#ifdef ENABLE_GNSS_INTERN
 void DMA2_Stream2_IRQHandler(void)
 {
   HAL_DMA_IRQHandler(&hdma_usart6_rx);
@@ -327,7 +329,7 @@
   HAL_UART_IRQHandler(&huart1);
 }
 
-#ifdef ENABLE_GPIO_V2
+#ifdef ENABLE_GNSS_INTERN
 void USART6_IRQHandler(void)
 {
   HAL_UART_IRQHandler(&huart6);
--- a/Small_CPU/Src/uart.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/uart.c	Sat Nov 15 19:29:44 2025 +0100
@@ -26,9 +26,10 @@
 #include "uartProtocol_GNSS.h"
 #include "externalInterface.h"
 #include "data_exchange.h"
+#include "gpio.h"
 #include <string.h>	/* memset */
 
-#ifdef ENABLE_GPIO_V2
+#ifdef ENABLE_GNSS_INTERN
 extern UART_HandleTypeDef huart6;
 extern sUartComCtrl Uart6Ctrl;
 #endif
@@ -104,9 +105,11 @@
   Uart1Ctrl.pTxBuffer = txBuffer;
   Uart1Ctrl.txBufferQueLen = 0;
 
-#ifndef ENABLE_GPIO_V2
+#ifndef ENABLE_GNSS_INTERN
+#ifdef ENABLE_GNSS_EXTERN
   UART_SetGnssCtrl(&Uart1Ctrl);
 #endif
+#endif
 }
 
 
@@ -337,10 +340,13 @@
 	{
 		UART_HandleRxComplete(&Uart1Ctrl);
 	}
-#ifdef ENABLE_GPIO_V2
-	if(huart == &huart6)
+#ifdef ENABLE_GNSS_INTERN
+	if(GPIO_GetVersion() > 0)
 	{
-		UART_HandleRxComplete(&Uart6Ctrl);
+		if(huart == &huart6)
+		{
+			UART_HandleRxComplete(&Uart6Ctrl);
+		}
 	}
 #endif
 }
@@ -363,10 +369,13 @@
 	{
 		UART_HandleTxComplete(&Uart1Ctrl);
 	}
-#ifdef ENABLE_GPIO_V2
-	if(huart == &huart6)
+#ifdef ENABLE_GNSS_INTERN
+	if(GPIO_GetVersion() > 0)
 	{
-		UART_HandleTxComplete(&Uart6Ctrl);
+		if(huart == &huart6)
+		{
+			UART_HandleTxComplete(&Uart6Ctrl);
+		}
 	}
 #endif
 }
@@ -401,11 +410,13 @@
 
 	if(sensorType == SENSOR_GNSS)
 	{
-#ifdef ENABLE_GPIO_V2
+#ifdef ENABLE_GNSS_INTERN
 		pUartCtrl = &Uart6Ctrl;
 #else
+#ifdef ENABLE_GNSS_EXTERN
 		pUartCtrl = &Uart1Ctrl;
 #endif
+#endif
 	}
 	else
 	{
@@ -438,7 +449,7 @@
 				case SENSOR_CO2:	uartCo2_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 					break;
 	#endif
-	#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+	#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 					case SENSOR_GNSS:	uartGnss_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 							break;
 	#endif
--- a/Small_CPU/Src/uartProtocol_GNSS.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/uartProtocol_GNSS.c	Sat Nov 15 19:29:44 2025 +0100
@@ -26,9 +26,10 @@
 #include "GNSS.h"
 #include "configuration.h"
 #include "externalInterface.h"
+#include "rtc.h"
 
 
-#if defined ENABLE_GNSS || defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+#if defined ENABLE_GNSS_INTERN || defined ENABLE_GNSS_EXTERN
 
 static uartGnssStatus_t gnssState = UART_GNSS_INIT;
 static gnssRequest_s activeRequest = {0,0};
@@ -88,6 +89,11 @@
 {
 	const uint8_t* pData;
 	uint8_t txLength = 0;
+	RTC_TimeTypeDef time;
+	RTC_DateTypeDef date;
+
+	UBX_MGA_INI_TIME_UTC_t msg_DateTime;
+	UBX_MGA_INI_POS_LLH_t msg_Position;
 
 	switch (GnssCmd)
 	{
@@ -121,6 +127,51 @@
 		case GNSSCMD_SET_CONFIG:	pData = setConfig;
 						  	  	  	txLength = sizeof(setConfig) / sizeof(uint8_t);
 				     break;
+		case GNSSCMD_SETDATETIME:
+		  							RTC_GetDate(&date);
+		  							RTC_GetTime(&time);
+
+									memset(&msg_DateTime, 0, sizeof(UBX_MGA_INI_TIME_UTC_t));
+									msg_DateTime.header1 = 0xB5;
+									msg_DateTime.header2 = 0x62;
+									msg_DateTime.msgClass = 0x13;
+									msg_DateTime.msgID = 0x40;
+									msg_DateTime.length = sizeof(UBX_MGA_INI_TIME_UTC_t) - 6;
+									msg_DateTime.type = 0x00;
+									msg_DateTime.version = 0x00;
+									msg_DateTime.year = date.Year + 2000;
+									msg_DateTime.month = date.Month;
+									msg_DateTime.day = date.Date;
+									if((time.Hours - 2) < 0)
+									{
+										msg_DateTime.hour = time.Hours + 24 - 2;
+									}
+									else
+									{
+										msg_DateTime.hour = time.Hours - 2;
+									}
+									msg_DateTime.minute = time.Minutes;
+									msg_DateTime.second =  time.Seconds;
+									msg_DateTime.accuracy_seconds = 60;
+									msg_DateTime.accuracy_nano = 0x0;
+									msg_DateTime.flags = 0x00;
+									msg_DateTime.leapsec = 0x80;
+
+									pData = (uint8_t*)&msg_DateTime;
+								  	txLength = sizeof(msg_DateTime) / sizeof(uint8_t);
+						     break;
+			case GNSSCMD_SET_POSITION:  msg_Position.header1 = 0xB5;
+										msg_Position.header2 = 0x62;
+										msg_Position.class_id = 0x13;
+										msg_Position.msg_id = 0x40;
+										msg_Position.length = sizeof(UBX_MGA_INI_POS_LLH_t) - 6;
+										msg_Position.latitude = (int32_t) (8.98647 * 1e7);
+										msg_Position.longitude = (int32_t) (47.77147 * 1e7);
+										msg_Position.altitude = (int32_t) 40000;
+										msg_Position.accuracy = 100000;
+										pData = (uint8_t*)&msg_Position;
+										txLength = sizeof(msg_Position) / sizeof(uint8_t);
+							break;
 		default:
 			break;
 	}
@@ -165,9 +216,17 @@
 		case UART_GNSS_LOADCONF_2:	UART_Gnss_SendCmd(GNSSCMD_LOADCONF_2);
 									rxState = GNSSRX_DETECT_ACK_0;
 				break;
-		case UART_GNSS_SETMODE_MOBILE: UART_Gnss_SendCmd(GNSSCMD_LOADCONF_2);
+		case UART_GNSS_SETMODE_MOBILE: UART_Gnss_SendCmd(GNSSCMD_SETMOBILE);
 									   rxState = GNSSRX_DETECT_ACK_0;
 				break;
+		case UART_GNSS_SETDATE_TIME: UART_Gnss_SendCmd(GNSSCMD_SETDATETIME);
+		   	   	   	   	   	   	   	// rxState = GNSSRX_DETECT_ACK_0;	/* aiding function will not acknoledge receiption (until config to do so) */
+									gnssState = UART_GNSS_SET_POSITION;
+				break;
+		case UART_GNSS_SET_POSITION:  UART_Gnss_SendCmd(GNSSCMD_SET_POSITION);
+	   	   	   	   					 //  rxState = GNSSRX_DETECT_ACK_0;	/* aiding function will not acknoledge receiption (until config to do so) */
+										gnssState = UART_GNSS_IDLE;
+				break;
 		case UART_GNSS_PWRDOWN:		UART_Gnss_SendCmd(GNSSCMD_MODE_PWS);
 									rxState = GNSSRX_DETECT_ACK_0;
 				break;
@@ -287,12 +346,29 @@
 												case UART_GNSS_LOADCONF_0:
 												case UART_GNSS_LOADCONF_1:	gnssState++;
 													break;
-												case UART_GNSS_LOADCONF_2:	gnssState = UART_GNSS_SETMODE_MOBILE;
+												case UART_GNSS_LOADCONF_2:
+#ifdef ENABLE_GNSS_TIME_INIT
+													gnssState = UART_GNSS_SETMODE_MOBILE;
+#else
+													gnssState = UART_GNSS_SET_POSITION;
+#endif
 													break;
-												case UART_GNSS_SETMODE_MOBILE:	rxState = GNSSRX_DETECT_ACK_0;
+												case UART_GNSS_SETMODE_MOBILE:
+#ifdef ENABLE_GNSS_TIME_INIT
+																				gnssState = UART_GNSS_SETDATE_TIME;
+#else
+																				rxState = GNSSRX_DETECT_ACK_0;
+																				UART_Gnss_SendCmd(GNSSCMD_MODE_NORMAL);
+																				gnssState = UART_GNSS_PWRUP;
+#endif
+													break;
+												case UART_GNSS_SET_POSITION:			rxState = GNSSRX_DETECT_ACK_0;
 																				UART_Gnss_SendCmd(GNSSCMD_MODE_NORMAL);
 																				gnssState = UART_GNSS_PWRUP;
 													break;
+												case UART_GNSS_SETDATE_TIME: rxState = GNSSRX_DETECT_ACK_0;
+																				UART_Gnss_SendCmd(GNSSCMD_MODE_NORMAL);
+																				gnssState = UART_GNSS_PWRUP;
 												default:
 													break;
 											}
--- a/Small_CPU/Src/uart_Internal.c	Sun Nov 02 19:30:58 2025 +0100
+++ b/Small_CPU/Src/uart_Internal.c	Sat Nov 15 19:29:44 2025 +0100
@@ -64,6 +64,56 @@
 	GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
 	GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
 	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+}
+
+void MX_USART6_DMA_Init() {
+	  /* DMA controller clock enable */
+	  __HAL_RCC_DMA2_CLK_ENABLE();
+
+	  /* DMA interrupt init */
+	  /* DMA2_Stream2_IRQn interrupt configuration */
+	  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
+	  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
+	  /* DMA2_Stream6_IRQn interrupt configuration */
+	  HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0);
+	  HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
+}
+
+
+void MX_USART6_UART_DeInit(void)
+{
+	HAL_DMA_Abort(&hdma_usart6_rx);
+	HAL_DMA_DeInit(&hdma_usart6_rx);
+	HAL_DMA_Abort(&hdma_usart6_tx);
+	HAL_DMA_DeInit(&hdma_usart6_tx);
+	HAL_UART_DeInit(&huart6);
+	//HAL_UART_DeInit(&huart6);
+	Uart6Ctrl.dmaRxActive = 0;
+	Uart6Ctrl.dmaTxActive = 0;
+}
+
+void MX_USART6_UART_Init(void) {
+	huart6.Instance = USART6;
+	huart6.Init.BaudRate = 9600;
+	huart6.Init.WordLength = UART_WORDLENGTH_8B;
+	huart6.Init.StopBits = UART_STOPBITS_1;
+	huart6.Init.Parity = UART_PARITY_NONE;
+	huart6.Init.Mode = UART_MODE_TX_RX;
+	huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+	huart6.Init.OverSampling = UART_OVERSAMPLING_16;
+	HAL_UART_Init(&huart6);
+
+	Uart6Ctrl.pHandle = &huart6;
+	Uart6Ctrl.dmaRxActive = 0;
+	Uart6Ctrl.dmaTxActive = 0;
+	Uart6Ctrl.pRxBuffer = rxBufferUart6;
+	Uart6Ctrl.pTxBuffer = txBufferUart6;
+	Uart6Ctrl.rxReadIndex = 0;
+	Uart6Ctrl.rxWriteIndex = 0;
+	Uart6Ctrl.txBufferQueLen = 0;
+
+	UART_clearRxBuffer(&Uart6Ctrl);
+	UART_SetGnssCtrl(&Uart6Ctrl);
 
 	/* USART6 DMA Init */
 	/* USART6_RX Init */
@@ -101,56 +151,6 @@
 	HAL_NVIC_EnableIRQ(USART6_IRQn);
 
 	MX_USART6_DMA_Init();
-
-}
-
-void MX_USART6_DMA_Init() {
-	  /* DMA controller clock enable */
-	  __HAL_RCC_DMA2_CLK_ENABLE();
-
-	  /* DMA interrupt init */
-	  /* DMA2_Stream2_IRQn interrupt configuration */
-	  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
-	  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
-	  /* DMA2_Stream6_IRQn interrupt configuration */
-	  HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0);
-	  HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
-}
-
-
-void MX_USART6_UART_DeInit(void)
-{
-	HAL_DMA_Abort(&hdma_usart6_rx);
-	HAL_DMA_DeInit(&hdma_usart6_rx);
-	HAL_DMA_Abort(&hdma_usart6_tx);
-	HAL_DMA_DeInit(&hdma_usart6_tx);
-	HAL_UART_DeInit(&huart6);
-	HAL_UART_DeInit(&huart6);
-}
-
-void MX_USART6_UART_Init(void) {
-	huart6.Instance = USART6;
-	huart6.Init.BaudRate = 9600;
-	huart6.Init.WordLength = UART_WORDLENGTH_8B;
-	huart6.Init.StopBits = UART_STOPBITS_1;
-	huart6.Init.Parity = UART_PARITY_NONE;
-	huart6.Init.Mode = UART_MODE_TX_RX;
-	huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-	huart6.Init.OverSampling = UART_OVERSAMPLING_16;
-	HAL_UART_Init(&huart6);
-
-	UART_clearRxBuffer(&Uart6Ctrl);
-
-	Uart6Ctrl.pHandle = &huart6;
-	Uart6Ctrl.dmaRxActive = 0;
-	Uart6Ctrl.dmaTxActive = 0;
-	Uart6Ctrl.pRxBuffer = rxBufferUart6;
-	Uart6Ctrl.pTxBuffer = txBufferUart6;
-	Uart6Ctrl.rxReadIndex = 0;
-	Uart6Ctrl.rxWriteIndex = 0;
-	Uart6Ctrl.txBufferQueLen = 0;
-
-	UART_SetGnssCtrl(&Uart6Ctrl);
 }
 
 void UART6_HandleUART()
@@ -163,7 +163,9 @@
 
 	uartGnssStatus_t gnssState = uartGnss_GetState();
 
-		if(gnssState != UART_GNSS_INIT)
+	if(Uart6Ctrl.pHandle != 0)
+	{
+		if((gnssState != UART_GNSS_INIT) && (gnssState != UART_GNSS_PWRUP))
 		{
 			UART_ReadData(SENSOR_GNSS, 0);
 			UART_WriteData(&Uart6Ctrl);
@@ -186,7 +188,7 @@
 			uartGnss_SetState(gnssState);
 		}
 		else if(((retryRequest == 0)		/* timeout or error */
-				&& (((time_elapsed_ms(lastRequestTick,tick) > (TIMEOUT_SENSOR_ANSWER)) && (gnssState != UART_GNSS_IDLE))	/* retry if no answer after half request interval */
+				&& (((time_elapsed_ms(lastRequestTick,tick) > (TIMEOUT_SENSOR_ANSWER)) && (gnssState != UART_GNSS_IDLE) && (gnssState != UART_GNSS_PWRUP))	/* retry if no answer after half request interval */
 					|| (gnssState == UART_GNSS_ERROR))))
 		{
 			/* The channel switch will cause the sensor to respond with an error message. */
@@ -216,7 +218,7 @@
 			timeToTrigger = 0;
 			uartGnss_Control();
 		}
-
+	}
 }