changeset 461:b3f684cea9c0

Merged in Ideenmodellierer/ostc4/minor_improvments (pull request #41) Minor improvments
author heinrichsweikamp <bitbucket@heinrichsweikamp.com>
date Mon, 30 Mar 2020 13:16:11 +0000
parents 9a9e4908ce2e (current diff) 2effe85f1a9b (diff)
children dddfe7917131
files
diffstat 16 files changed, 905 insertions(+), 290 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Inc/configuration.h	Mon Mar 30 13:16:11 2020 +0000
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Inc/configuration.h
+/// \brief  Header file for variant specific firmware adaptations at compile time
+/// \author heinrichs weikamp gmbh
+/// \date   29-February-2020
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2020 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 CONFIGURATION_HEADER
+#define CONFIGURATION_HEADER
+
+/* Enable this to make the simulator write a logbook entry */
+/* #define SIM_WRITES_LOGBOOK 1 */
+
+/* Enable this for support of optical bottle pressure interface */
+/* #define ENABLE_BOTTLE_SENSOR */
+
+/* Enable this to show voltage in parallel to charge state */
+/* #define ALWAYS_SHOW_VOLTAGE */
+
+/* Enable this to skip coplete scan of dive log during startup */
+/* #define TRUST_LOG_CONSISTENCY */
+
+/* Enable this to reset the profile data by pressing enter within log info menu */
+/* #define ENABLE_PROFILE_RESET */
+
+#endif
--- a/Discovery/Inc/externLogbookFlash.h	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Inc/externLogbookFlash.h	Mon Mar 30 13:16:11 2020 +0000
@@ -149,7 +149,7 @@
 void ext_flash_enable_protection(void);
 
 void ext_flash_read_block_start(void);
-
+uint8_t ext_dive_log_consistent(void);
 void ext_flash_repair_dive_log(void);
 
 uint8_t ext_flash_erase_firmware_if_not_empty(void);
@@ -165,5 +165,6 @@
 
 uint32_t ext_flash_AnalyseSampleBuffer(char *pstrResult);
 void ext_flash_CloseSector(void);
+void ext_flash_invalidate_sample_index(uint32_t sectorStart);
 
 #endif /* EXTERN_LOGBOOK_FLASH_H */
--- a/Discovery/Inc/logbook.h	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Inc/logbook.h	Mon Mar 30 13:16:11 2020 +0000
@@ -30,6 +30,8 @@
 #include "data_central.h"
 #include "settings.h"
 
+#define NUM_GAS		(5)	/* number of selectable gases */
+
 typedef struct
 {
     uint8_t setpoint_cbar;
@@ -65,7 +67,7 @@
     int16_t  minTemp;
     uint16_t surfacePressure_mbar;
     uint16_t desaturationTime;
-    SGasListLog gasordil[5];
+    SGasListLog gasordil[NUM_GAS];
     uint8_t  firmwareVersionLow;
     uint8_t  firmwareVersionHigh;
     uint16_t batteryVoltage;
@@ -73,7 +75,7 @@
     uint8_t  gfAtBeginning;
     uint8_t  gfAtEnd;
     uint16_t personalDiveCount;
-    SSetpointLog setpoint[5];
+    SSetpointLog setpoint[NUM_GAS];
     uint16_t maxCNS;
     uint16_t averageDepth_mbar;
     uint16_t total_diveTime_seconds;
@@ -114,7 +116,7 @@
     uint8_t minTemp[2];
     uint8_t surfacePressure_mbar[2];
     uint8_t desaturationTime[2];
-    uint8_t gasordil[5*4];
+    uint8_t gasordil[NUM_GAS*4];
     uint8_t firmwareVersionLow;
     uint8_t firmwareVersionHigh;
     uint8_t batteryVoltage[2];
@@ -209,11 +211,15 @@
 
 uint8_t logbook_getNumberOfHeaders(void);
 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 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);
 void logbook_test(void);
 void logbook_InitAndWrite(const SDiveState* pStateReal);
 void logbook_recover_brokenlog(uint8_t headerId);
 
 uint16_t logbook_lastDive_diveNumber(void);
+uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader);
+void logbook_readDummySamples(uint8_t* pTarget, uint16_t length);
 
 #endif /* LOGBOOK_H */
--- a/Discovery/Inc/t7.h	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Inc/t7.h	Mon Mar 30 13:16:11 2020 +0000
@@ -31,6 +31,26 @@
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f4xx_hal.h"
 #include "gfx_engine.h"
+#include "configuration.h"
+
+
+typedef enum
+{
+		LLC_Empty = 0,
+		LLC_Temperature,
+		LLC_AverageDepth,
+		LLC_ppO2,
+		LLC_Stopwatch,
+		LLC_Ceiling,
+		LLC_FutureTTS,
+		LLC_CNS,
+		LLC_GF,
+#ifdef ENABLE_BOTTLE_SENSOR
+		LCC_BottleBar,
+#endif
+		LLC_END
+
+} customview_llc_t;
 
 /* Exported functions --------------------------------------------------------*/
 void t7_init(void);
--- a/Discovery/Src/base.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/base.c	Mon Mar 30 13:16:11 2020 +0000
@@ -199,6 +199,7 @@
 /* Includes ------------------------------------------------------------------*/
 #include "stdio.h"
 #include <string.h> // for memcopy
+#include "configuration.h"
 
 #include "stm32f4xx_hal.h"
 #include "ostc.h"
@@ -327,12 +328,6 @@
     return(ch);
 }
 */
-/* #define DEBUG_RUNTIME TRUE */
-#ifdef DEBUG_RUNTIME
-#define MEASURECNT 60	/* number of measuremets to be stored */
-static uint32_t loopcnt[MEASURECNT];
-#endif
-
 static uint8_t ButtonAction = ACTION_END;
 
 static void StoreButtonAction(uint8_t action)
@@ -350,11 +345,6 @@
 {
     uint32_t pLayerInvisible;
     uint16_t totalDiveCounterFound;
-#ifdef DEBUG_RUNTIME
-    RTC_TimeTypeDef Stime;
-    uint8_t measurementindex = 0;
-    uint8_t lastsecond = 0xFF;
-#endif
 
 	SStateList status;
     detectionState_t pitchstate;
@@ -445,9 +435,16 @@
     GFX_logoAutoOff();
     EXTILine_Buttons_Config();
 
+#ifdef TRUST_LOG_CONSISTENCY
+    if(!ext_dive_log_consistent())	/* only repair log if an invalid entry was detected */
+    {
+    	ext_flash_repair_dive_log();
+    }
+
+#else	/* always check and repair log */
     ext_flash_repair_dive_log();
     //ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(1);
-
+#endif
     totalDiveCounterFound = logbook_lastDive_diveNumber();
     if( settingsGetPointer()->totalDiveCounter < totalDiveCounterFound )
             settingsGetPointer()->totalDiveCounter = totalDiveCounterFound;
@@ -527,9 +524,6 @@
         	}
 
 
-// Enable this to make the simulator write a logbook entry
-// #define SIM_WRITES_LOGBOOK 1
-
 #ifdef SIM_WRITES_LOGBOOK
         if(stateUsed == stateSimGetPointer())
             logbook_InitAndWrite(stateUsed);
@@ -537,27 +531,6 @@
         	if(stateUsed == stateRealGetPointer())	/* Handle log entries while in dive mode*/
                 logbook_InitAndWrite(stateUsed);
         }
-
-#ifdef DEBUG_RUNTIME
-        translateTime(stateUsed->lifeData.timeBinaryFormat, &Stime);
-        if(lastsecond == 0xFF)
-        {
-        	measurementindex = 0;
-        	loopcnt[measurementindex] = 0;
-        	lastsecond = Stime.Seconds;
-        }
-        loopcnt[measurementindex]++;
-
-        if(lastsecond != Stime.Seconds)
-        {
-        	measurementindex++;
-        	if (measurementindex == MEASURECNT) measurementindex = 0;
-        	loopcnt[measurementindex] = 0;
-        	lastsecond = Stime.Seconds;
-        	if(measurementindex +1 < MEASURECNT) loopcnt[measurementindex +1] = 0xffff;	/* helps to identify the latest value */
-        }
-#endif
-
     }
 }
 
--- a/Discovery/Src/data_exchange_main.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/data_exchange_main.c	Mon Mar 30 13:16:11 2020 +0000
@@ -764,6 +764,7 @@
 
 	
 	// wireless - �ltere daten aufr�umen
+#if 0
 	for(int i=0;i<(2*NUM_GASES+1);i++)
 	{
 		if(pStateReal->lifeData.bottle_bar[i])
@@ -777,7 +778,12 @@
 				pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] +=  100;
 		}
 	}
-	
+#else
+   	if(stateRealGetPointer()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings] < 6000)  /* max age after ten minutes */
+   	{
+   		stateRealGetPointerWrite()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings]++;
+   	}
+#endif
 	if(!DataEX_check_header_and_footer_ok())
 	{
 		if(DataEX_check_header_and_footer_devicedata())
--- a/Discovery/Src/externLogbookFlash.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/externLogbookFlash.c	Mon Mar 30 13:16:11 2020 +0000
@@ -787,6 +787,7 @@
 				actualAddress = SAMPLESTART;
 			}
 			preparedPageAddress = actualAddress;
+			ext_flash_invalidate_sample_index(preparedPageAddress);
 			ext_flash_erase64kB();
 			actualAddress = actualAdressBackup;
 		}
@@ -1353,6 +1354,40 @@
 }
 */
 
+uint8_t ext_dive_log_consistent(void)
+{
+	uint8_t ret = 0;
+	uint8_t  header1, header2;
+	uint8_t id;
+	convert_Type dataStart;
+
+	SSettings *settings = settingsGetPointer();
+	id = settings->lastDiveLogId;
+
+    actualAddress = HEADERSTART + (0x800 * id);
+    ext_flash_read_block_start();
+    ext_flash_read_block(&header1, EF_HEADER);
+    ext_flash_read_block(&header2, EF_HEADER);
+    dataStart.u8bit.byteHigh = 0;
+    ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);
+    ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);
+    ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);
+    ext_flash_read_block_stop();
+    if((header1 == 0xFA) && (header2 == 0xFA))						/* Header is indicating the start of a dive */
+    {
+      actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;
+      ext_flash_read_block_start();
+      ext_flash_read_block(&header1, EF_HEADER);
+      ext_flash_read_block(&header2, EF_HEADER);
+      ext_flash_read_block_stop();
+      if((header1 == 0xFA) && (header2 == 0xFA))					/* Secondary header was written at the end of a dive */
+      {
+    	  ret = 1;													/* => lastDiveLogID points to a valid dive entry */
+      }
+    }
+    return ret;
+}
+
 //  ===============================================================================
 //	ext_flash_repair_dive_log
 /// @brief	This function 
@@ -1361,6 +1396,7 @@
 ///					and
 ///						lastDiveLogId
 ///
+
 void ext_flash_repair_dive_log(void)
 {
 	uint8_t  header1, header2;
@@ -1760,7 +1796,12 @@
 		actualAddress = ringStart;
 
 	if(do_not_erase == 0)
-		ext_flash_erase_if_on_page_start();
+	{
+		if((ext_flash_erase_if_on_page_start()) && (type == EF_SAMPLE))		/* invalidate header sample information if needed */
+		{
+			ext_flash_invalidate_sample_index(actualAddress);
+		}
+	}
 	
 	while( i<length)
 	{
@@ -2240,6 +2281,55 @@
 	return startedSectors;
 }
 
+/* In case of a sample ring overrun the headers of the dive which will no longer have sample data needs to be updated */
+void ext_flash_invalidate_sample_index(uint32_t sectorStart)
+{
+	uint8_t emptySamples[] = {0,0,0, 0,0,0, 0,0,0};	/* entry of start, stop and length */
+	uint8_t diveidx;
+
+	uint8_t  header1, header2;
+
+  	SSettings *settings = settingsGetPointer();
+  	diveidx = settings->lastDiveLogId + 1;
+  	convert_Type dataStart, dataEnd;
+
+  	uint32_t HeaderAddrBackup = actualPointerHeader;
+
+	while(diveidx != settings->lastDiveLogId)
+	{
+		actualAddress = HEADERSTART + (0x800 * diveidx) + HEADER2OFFSET;
+		ext_flash_read_block_start();
+		ext_flash_read_block(&header1, EF_HEADER);
+		ext_flash_read_block(&header2, EF_HEADER);
+		dataStart.u8bit.byteHigh = 0;
+		ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);
+		ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);
+		ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);
+		dataEnd.u8bit.byteHigh = 0;
+		ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER);
+		ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER);
+		ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER);
+		ext_flash_read_block_stop();
+
+		if((header1 == 0xFA) && (header2 == 0xFA))					/* Dive ID is in use */
+		{
+			if(((dataStart.u32bit >= sectorStart) && (dataStart.u32bit <= sectorStart+0xFFFF))	/* Sample start is within erased sector */
+			  || ((dataEnd.u32bit >= sectorStart) && (dataEnd.u32bit <= sectorStart+0xFFFF))) /* End of sample data is within erased sector */
+			{
+				  actualAddress = HEADERSTART + (0x800 * diveidx) + HEADER2OFFSET;
+				  ext_flash_incf_address(EF_HEADER);					/* skip header bytes */
+				  ext_flash_incf_address(EF_HEADER);
+				  actualPointerHeader = actualAddress;
+				  ef_write_block(emptySamples,9,EF_HEADER,1);			/* clear start, stop and length data */
+				  actualPointerHeader = HeaderAddrBackup;
+			}
+	   }
+	   diveidx++;
+	}
+}
+
+
+
 /*
 uint8_t ext_flash_erase_firmware_if_not_empty(void)
 {
--- a/Discovery/Src/logbook.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/logbook.c	Mon Mar 30 13:16:11 2020 +0000
@@ -56,15 +56,16 @@
 #include "data_exchange.h"
 #include "decom.h"
 #include "tHome.h" // for  tHome_findNextStop()
+#include "settings.h"
+#include "configuration.h"
  
 /* Private types -------------------------------------------------------------*/
 
-#define NUM_GASES 5
-
 #define LOGBOOK_VERSION (0x30)
 #define LOGBOOK_VERSION_OSTC3 (0x24)
 
 #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 */
 
 typedef struct /* don't forget to adjust void clear_divisor(void) */
 {
@@ -87,6 +88,12 @@
 static SDivisor divisor;
 static SDivisor divisorBackup;
 
+static SSmallHeader smallDummyHeader;
+static uint16_t	dummyWriteIdx;
+static uint16_t	dummyReadIdx;
+static uint8_t dummyMemoryBuffer[1000*4];
+
+
 /* Private function prototypes -----------------------------------------------*/
 static void clear_divisor(void);
 static void logbook_SetAverageDepth(float average_depth_meter);
@@ -96,6 +103,7 @@
 static void logbook_SetLastStop(float last_stop_depth_bar);
 static void logbook_writedata(void * data, int length_byte);
 static void logbook_UpdateHeader(const SDiveState * pStateReal);
+static void logbook_createDummyProfile(SLogbookHeader* pHeader, uint16_t length, uint16_t* depth, int16_t* temperature, uint16_t* ppo2);
 
 /* Exported functions --------------------------------------------------------*/
 
@@ -308,9 +316,13 @@
 	smallHeader.cnsDivisor = 12;
 
 	smallHeader.tankType = 6;
+#ifdef ENABLE_BOTTLE_SENSOR
+	smallHeader.tankLength = 2;
+	smallHeader.tankDivisor = 30;	/* log tank data once a minute */
+#else
 	smallHeader.tankLength = 0;
 	smallHeader.tankDivisor = 0;
-
+#endif
 	logbook_writedata((void *) &smallHeader,sizeof(smallHeader));
 
 	clear_divisor();
@@ -516,6 +528,7 @@
 					length += 1;
 					sample[length] = 0;
 					length += 1;
+					pDecoinfo = &stateUsed->decolistBuehlmann;	/* use GF per default if something went wrong */
 				}
 					
 				if(pDecoinfo->output_ndl_seconds > 0)
@@ -624,6 +637,22 @@
         divisor.cns--;
     }
 
+#ifdef ENABLE_BOTTLE_SENSOR
+    if(smallHeader.tankDivisor)
+    {
+      if(divisor.tank == 0)
+      {
+          divisor.tank = smallHeader.tankDivisor - 1;
+  		  addS16(&sample[length], ((state->lifeData.bottle_bar[state->lifeData.actualGas.GasIdInSettings])));
+  		  length += smallHeader.tankLength;
+      }
+      else
+      {
+          divisor.tank--;
+      }
+    }
+#endif
+
     profileByteFlag.uw = length - 3;
     if(eventByte1.uw)
     {
@@ -649,7 +678,8 @@
   * @param  int32_t* cns: output Value
   * @return bytes read / 0 = reading Error
   */
-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)
+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)
 {
 	int length = 0;
 	_Bool bEvent = 0;
@@ -678,6 +708,9 @@
     *setpoint_cbar = -1;
   if(bailout)
     *bailout = -1;
+  if(tank)
+	  *tank = 0;
+
   if(manualGas)
   {
     manualGas->percentageO2 =-1;
@@ -868,6 +901,27 @@
 			divisor.cns--;
 	}
 
+#ifdef ENABLE_BOTTLE_SENSOR
+	if(smallHeader.tankDivisor)
+	{
+		if(divisor.tank == 0)
+		{
+				divisor.tank = smallHeader.tankDivisor - 1;
+				ext_flash_read_next_sample_part( (uint8_t*)&temp, 2);
+				bytesRead +=2;
+				length -= 2;
+				if(tank)
+				{
+						*tank = (uint16_t)temp;
+				}
+		}
+		else
+		{
+				divisor.tank--;
+		}
+	}
+#endif
+
 	if (length != 0)
 			return 0;
 
@@ -890,18 +944,20 @@
   * @param  int32_t* cns : output  array
   * @return length of output
   */
-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 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)
 {
      //Test read
     //SLogbookHeader header;
 
     //logbook_getHeader(&header);
     SLogbookHeader header;
-    int iNum;
-    int firstgasid = 0;
-    int retVal = 0;
-    int compression = 0;
-     int i;
+    int16_t iNum;
+    int16_t firstgasid = 0;
+    uint16_t retVal = 0;
+    int16_t compression = 0;
+    int16_t i;
    // uint32_t diveTime_seconds;
     int32_t depthVal = 0;
     int16_t  gasidVal = 0;
@@ -922,13 +978,15 @@
     int32_t temperatureLast = 0;
     int32_t temperatureFirst = 0;
     int32_t cnsLast = 0;
-		int16_t decostepDepthVal = 0;
-		int16_t decostepDepthLast = 0;
+	int16_t decostepDepthVal = 0;
+	int16_t decostepDepthLast = 0;
+	uint16_t tankVal = 0;
 
      SManualGas manualGasVal;
      SManualGas manualGasLast;
      manualGasLast.percentageO2 = 0;
      manualGasLast.percentageHe = 0;
+     uint16_t numSamples = 0;
 
      float ambiant_pressure_bar = 0;
      float ppO2 = 0;
@@ -946,8 +1004,11 @@
     //diveTime_seconds = header.diveTime_seconds ;
     for(compression = 1; compression < 100; compression ++)
     {
-        if((header.total_diveTime_seconds / header.samplingRate)/compression <= length)
-            break;
+    	numSamples = (header.total_diveTime_seconds / header.samplingRate)/compression;
+        if(numSamples <= length)
+        {
+        	break;
+        }
     }
 
 
@@ -971,6 +1032,8 @@
             sensor3[i] = 0;
         if(cns)
             cns[i] = 0;
+        if(tank)
+        	tank[i] = 0;
     }
     //We start with fist gasid
     gasidLast = firstgasid;
@@ -988,135 +1051,149 @@
     iNum = 0;
     int counter = 0;
 		temperatureLast = -1000;
-    while ((bytesRead < totalNumberOfBytes) && (iNum < length))
-    {
-			ext_flash_set_entry_point();
-			divisorBackup = divisor;
-			retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, &decostepDepthVal);
-
-			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);
-
-					if(retVal == 0)
-							break;
-			}
-			bytesRead +=retVal;
-
-			//if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value
-			if(depthVal == -1)
-					depthVal = depthLast;
-			else
-					depthLast = depthVal;
+	if(totalNumberOfBytes > 2)	/* read real data */
+	{
+		while ((bytesRead < totalNumberOfBytes) && (iNum < length))
+		{
+				ext_flash_set_entry_point();
+				divisorBackup = divisor;
+				retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
+									&bailoutVal, &decostepDepthVal, &tankVal);
 
-			if(gasidVal == -1)
-					gasidVal = gasidLast;
-			else
-					gasidLast = gasidVal;
-
-			if(temperatureVal == -1000)
-					temperatureVal = temperatureLast;
-			else
-			{	
-				if(temperatureLast == -1000)
-					temperatureFirst = temperatureVal;
-				temperatureLast = temperatureVal;
-			}
-
-			if(setPointVal == -1)
-				setPointVal = setPointLast;
-			else
-				setPointLast = setPointVal;
-
-			if(sensor1Val == -1)
-					sensor1Val = sensor1Last;
-			else
-					sensor1Last = sensor1Val;
-
-			if(sensor2Val == -1)
-					sensor2Val = sensor2Last;
-			else
-					sensor2Last = sensor2Val;
+				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);
 
-			if(sensor3Val == -1)
-					sensor3Val = sensor3Last;
-			else
-					sensor3Last = sensor3Val;
-
-			if(cnsVal == -1)
-					cnsVal = cnsLast;
-			else
-					cnsLast = cnsVal;
+						if(retVal == 0)
+								break;
+				}
+				bytesRead +=retVal;
 
-			if(manualGasVal.percentageO2 == -1)
-				manualGasVal = manualGasLast;
-			else
-				manualGasLast = manualGasVal;
-
-			if(bailoutVal == -1)
-				bailoutVal = bailoutLast;
-			else
-				bailoutLast = bailoutVal;
+				//if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value
+				if(depthVal == -1)
+						depthVal = depthLast;
+				else
+						depthLast = depthVal;
 
-			if(decostepDepthVal == -1)
-					decostepDepthVal = decostepDepthLast;
-			else
-					decostepDepthLast = decostepDepthVal;
-			
-			counter++;
-			// Heed compression
-			// Write here to arrays
-			if(counter == compression)
-			{
-				if(depth)
-					depth[iNum] = depthVal;
-				if(gasid)
-					gasid[iNum] = gasidVal;
-				if(temperature)
-					temperature[iNum] = temperatureVal;
-				if(cns)
-					cns[iNum] = cnsVal;
-				if(bailout)
-					bailout[iNum] = bailoutVal;
-				if(decostopDepth)
-					decostopDepth[iNum] = decostepDepthVal;
-					
-				if(ppo2)
+				if(gasidVal == -1)
+						gasidVal = gasidLast;
+				else
+						gasidLast = gasidVal;
+
+				if(temperatureVal == -1000)
+						temperatureVal = temperatureLast;
+				else
 				{
-					//Calc ppo2 - Values
-					SGas gas;
-					gas.setPoint_cbar = setPointVal;
-					if(gasidVal > 0)
-					{
-						gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage;
-						gas.nitrogen_percentage = 100 -  gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage;
-					}
-					else
-					{
-						gas.helium_percentage = manualGasVal.percentageHe;
-						gas.nitrogen_percentage = 100 -  gas.helium_percentage - manualGasVal.percentageO2;
-					}
-					ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000;
-					ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas );
-					ppo2[iNum] = (uint16_t) ( ppO2 * 100);
+					if(temperatureLast == -1000)
+						temperatureFirst = temperatureVal;
+					temperatureLast = temperatureVal;
 				}
 
-				if(setpoint)
-					setpoint[iNum] = setPointVal;
+				if(setPointVal == -1)
+					setPointVal = setPointLast;
+				else
+					setPointLast = setPointVal;
+
+				if(sensor1Val == -1)
+						sensor1Val = sensor1Last;
+				else
+						sensor1Last = sensor1Val;
+
+				if(sensor2Val == -1)
+						sensor2Val = sensor2Last;
+				else
+						sensor2Last = sensor2Val;
+
+				if(sensor3Val == -1)
+						sensor3Val = sensor3Last;
+				else
+						sensor3Last = sensor3Val;
+
+				if(cnsVal == -1)
+						cnsVal = cnsLast;
+				else
+						cnsLast = cnsVal;
+
+				if(manualGasVal.percentageO2 == -1)
+					manualGasVal = manualGasLast;
+				else
+					manualGasLast = manualGasVal;
+
+				if(bailoutVal == -1)
+					bailoutVal = bailoutLast;
+				else
+					bailoutLast = bailoutVal;
+
+				if(decostepDepthVal == -1)
+						decostepDepthVal = decostepDepthLast;
+				else
+						decostepDepthLast = decostepDepthVal;
 
-				if(sensor1)
-					sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF;
-				if(sensor2)
-					sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF;
-				if(sensor3)
-					sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF;
-				iNum++;
-				counter = 0;
-			}
-    }
+				counter++;
+				// Heed compression
+				// Write here to arrays
+				if(counter == compression)
+				{
+					if(depth)
+						depth[iNum] = depthVal;
+					if(gasid)
+						gasid[iNum] = gasidVal;
+					if(temperature)
+						temperature[iNum] = temperatureVal;
+					if(cns)
+						cns[iNum] = cnsVal;
+					if(bailout)
+						bailout[iNum] = bailoutVal;
+					if(decostopDepth)
+						decostopDepth[iNum] = decostepDepthVal;
+
+					if(ppo2)
+					{
+						//Calc ppo2 - Values
+						SGas gas;
+						gas.setPoint_cbar = setPointVal;
+						if(gasidVal > 0)
+						{
+							gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage;
+							gas.nitrogen_percentage = 100 -  gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage;
+						}
+						else
+						{
+							gas.helium_percentage = manualGasVal.percentageHe;
+							gas.nitrogen_percentage = 100 -  gas.helium_percentage - manualGasVal.percentageO2;
+						}
+						ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000;
+						ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas );
+						ppo2[iNum] = (uint16_t) ( ppO2 * 100);
+					}
+
+					if(tank)
+					{
+						tank[iNum] = tankVal;
+					}
+					if(setpoint)
+						setpoint[iNum] = setPointVal;
+
+					if(sensor1)
+						sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF;
+					if(sensor2)
+						sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF;
+					if(sensor3)
+						sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF;
+					iNum++;
+					counter = 0;
+				}
+		}
+	}
+	else
+	{
+		logbook_createDummyProfile(&header, numSamples, depth, temperature, ppo2);
+		iNum = numSamples;
+	}
 		
 		// Fix first Temperature Entries 150930 hw
 		if(temperature)
@@ -1382,6 +1459,7 @@
 SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead)
 {
 	convert_Type data,data2;
+	uint16_t dummyLength = 0;
 
 	memcpy(headerOSTC3.diveHeaderStart,			&pHead->diveHeaderStart,					2);
 	memcpy(headerOSTC3.pBeginProfileData,		&pHead->pBeginProfileData,				3);
@@ -1398,22 +1476,34 @@
 	data2.u8bit.byteMidLow 	= pHead->pEndProfileData[1];
 	data2.u8bit.byteMidHigh 	= pHead->pEndProfileData[2];
 
-	/* check if sample address information are corrupted by address range. */
-	/* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
-	if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
+	if( (pHead->pBeginProfileData[0] == 0)			/* no sample data available => use dummy */
+		&&(pHead->pBeginProfileData[1] == 0)
+		&&(pHead->pBeginProfileData[2] == 0))
 	{
-		data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
-		pHead->pEndProfileData[0] = data2.u8bit.byteLow;
-		pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
-		pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
-		data.u32bit = DEFAULT_SAMPLES;
+		dummyLength = logbook_fillDummySampleBuffer(pHead);
+
+		data2.u32bit = data.u32bit + dummyLength;	/* calc new end address (which is equal to dummyLength) */
+		data.u32bit = data2.u32bit;				    /* data is used below to represent the length */
 	}
 	else
 	{
-		data.u8bit.byteHigh = 0;
-		data.u8bit.byteLow 			= pHead->profileLength[0];
-		data.u8bit.byteMidLow 	= pHead->profileLength[1];
-		data.u8bit.byteMidHigh 	= pHead->profileLength[2];
+		/* check if sample address information are corrupted by address range. */
+		/* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
+		if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
+		{
+			data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
+			pHead->pEndProfileData[0] = data2.u8bit.byteLow;
+			pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
+			pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
+			data.u32bit = DEFAULT_SAMPLES;
+		}
+		else
+		{
+			data.u8bit.byteHigh = 0;
+			data.u8bit.byteLow 			= pHead->profileLength[0];
+			data.u8bit.byteMidLow 	= pHead->profileLength[1];
+			data.u8bit.byteMidHigh 	= pHead->profileLength[2];
+		}
 	}
 	if(data.u32bit != 0xFFFFFF)
 		data.u32bit += 3;
@@ -1529,6 +1619,7 @@
 SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead)
 {
 	convert_Type data, data2;
+	uint32_t dummyLength = 0;
 
 
 	data.u8bit.byteHigh = 0;
@@ -1541,24 +1632,35 @@
 	data2.u8bit.byteMidLow 	= pHead->pEndProfileData[1];
 	data2.u8bit.byteMidHigh 	= pHead->pEndProfileData[2];
 
-	/* check if sample address information are corrupted by address range. */
-	/* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
-	if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
+	if( (pHead->pBeginProfileData[0] == 0)			/* no sample data available => use dummy */
+		&&(pHead->pBeginProfileData[1] == 0)
+		&&(pHead->pBeginProfileData[2] == 0))
 	{
-		data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
-		pHead->pEndProfileData[0] = data2.u8bit.byteLow;
-		pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
-		pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
-		data.u32bit = DEFAULT_SAMPLES;
+		dummyLength = logbook_fillDummySampleBuffer(pHead);
+
+		data2.u32bit = data.u32bit + dummyLength;	/* calc new end address (which is equal to dummyLength) */
+		data.u32bit = data2.u32bit;				    /* data is used below to represent the length */
 	}
 	else
 	{
-		data.u8bit.byteHigh = 0;
-		data.u8bit.byteLow 			= pHead->profileLength[0];
-		data.u8bit.byteMidLow 	= pHead->profileLength[1];
-		data.u8bit.byteMidHigh 	= pHead->profileLength[2];
+		/* check if sample address information are corrupted by address range. */
+		/* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
+		if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
+		{
+			data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
+			pHead->pEndProfileData[0] = data2.u8bit.byteLow;
+			pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
+			pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
+			data.u32bit = DEFAULT_SAMPLES;
+		}
+		else
+		{
+			data.u8bit.byteHigh = 0;
+			data.u8bit.byteLow 		= pHead->profileLength[0];
+			data.u8bit.byteMidLow 	= pHead->profileLength[1];
+			data.u8bit.byteMidHigh 	= pHead->profileLength[2];
+		}
 	}
-
 	if(data.u32bit != 0xFFFFFF)
 	{
 		data.u32bit += 3;
@@ -1640,20 +1742,20 @@
 
         ext_flash_set_entry_point();
         divisorBackup = divisor;
-				retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL);
+				retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
         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, NULL);
+					retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
 
           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, NULL);
+							retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
 
               if(retVal == 0)
               {
@@ -1684,4 +1786,213 @@
     ext_flash_close_new_dive_log((uint8_t *)&header);
 }
 
+void logbook_createDummyProfile(SLogbookHeader* pHeader, uint16_t length, uint16_t* depth, int16_t* temperature, uint16_t* ppo2)
+{
+	uint8_t	 drawDeco = 1;
+	uint16_t index = 0;
+	uint16_t indexDescenStop = 0;
+	uint16_t indexAscendStart = 0;
+	uint16_t simDecentDepth = 0;
+	uint16_t simDecentStep = 0;
+	uint16_t simAcentDepth = 0;
+	uint16_t simAcentStep = 0;
+	float ambiant_pressure_bar = 0;
+
+	simDecentStep = pHeader->maxDepth / (length / 6);							/* first 1/6 for descend */
+	simAcentStep = pHeader->maxDepth / (length / 3);							/* first 1/3 for ascend */
+
+	SGas gas;
+
+
+	if(ppo2)
+	{
+		/* find first gas ID */
+		for(index = 0; index < NUM_GAS; index++)
+		{
+			if(pHeader->gasordil[index].note.ub.first)
+				break;
+		}
+		if(index != NUM_GAS)
+		{
+			gas.helium_percentage = pHeader->gasordil[index].helium_percentage;
+			gas.nitrogen_percentage = 100 -  gas.helium_percentage - pHeader->gasordil[index].oxygen_percentage;
+		}
+	}
+
+	while((index < length) && (simDecentDepth < pHeader->maxDepth))			/* draw decent */
+	{
+		depth[index] = simDecentDepth;
+		temperature[index] = pHeader->minTemp;
+		if(ppo2)
+		{
+			ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000;
+			ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100);
+		}
+		index++;
+		simDecentDepth += simDecentStep;
+	}
+	indexDescenStop = index;
+	index = length -1;
+	while((index > indexDescenStop) && (simAcentDepth < pHeader->maxDepth))				/* draw ascend including max deco stop */
+	{
+		depth[index] = simAcentDepth;
+		temperature[index] = pHeader->minTemp;
+		if(ppo2)
+		{
+			ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000;
+			ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100);
+		}
+		if((drawDeco) && (simAcentDepth < pHeader->lastDecostop_m))						/* draw deco step */
+		{
+			drawDeco = length / 10;
+			while(drawDeco)
+			{
+				index--;
+				depth[index] = simAcentDepth;
+				temperature[index] = pHeader->minTemp;
+				if(ppo2)
+				{
+					ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000;
+					ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100);
+				}
+				drawDeco--;
+			}
+		}
+		index--;
+		simAcentDepth += simAcentStep;
+	}
+	indexAscendStart = index;
+	index = indexDescenStop;
+	while(index <= indexAscendStart)												/* draw isobar dive phase */
+	{
+		depth[index] = pHeader->maxDepth;
+		temperature[index] = pHeader->minTemp;
+		if(ppo2)
+		{
+			ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000;
+			ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100);
+		}
+		index++;
+	}
+}
+
+void logbook_resetDummy()
+{
+	dummyWriteIdx = 0;
+	dummyReadIdx = 0;
+}
+
+void logbook_writeDummy(void* data, uint16_t length)
+{
+	memcpy(&dummyMemoryBuffer[dummyWriteIdx],(uint8_t *)data, length);
+	dummyWriteIdx += length;
+}
+void logbook_writeDummySample(uint16_t depth, int16_t temperature)
+{
+    uint8_t sample[10];
+    int length = 0;
+
+    int i = 0;
+    for(i = 0; i <10 ;i++)  sample[i] = 0;
+    addU16(sample, depth);
+    length += 2;
+    sample[2] = 0;
+    length++;
+
+    if(divisor.temperature == 0)
+    {
+			divisor.temperature = smallHeader.tempDivisor - 1;
+			addS16(&sample[length], temperature);
+			length += 2;
+    }
+    else
+    {
+        divisor.temperature--;
+    }
+
+    logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader));
+}
+
+
+uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader)
+{
+	uint16_t depthArray[DUMMY_SAMPLES];
+	int16_t temperatureArray[DUMMY_SAMPLES];
+	uint16_t ppo2Array[DUMMY_SAMPLES];
+
+	uint16_t index = 0;
+	uint16_t dummyBufferSize = 0;
+	uint16_t dummyProfileLength = 0;
+	uint32_t overallSecond = pHeader->diveTimeMinutes * 60 + pHeader->diveTimeSeconds;
+
+	logbook_resetDummy();
+	clear_divisor();
+
+	smallDummyHeader.profileLength[0] = 0xFF;
+	smallDummyHeader.profileLength[1] = 0xFF;
+	smallDummyHeader.profileLength[2] = 0xFF;
+	smallDummyHeader.samplingRate_seconds = 2;
+	smallDummyHeader.numDivisors = 7;
+
+	smallDummyHeader.tempType = 0;
+	smallDummyHeader.tempLength = 2;
+	smallDummyHeader.tempDivisor = 6;
+
+	smallDummyHeader.deco_ndlType = 1;
+	smallDummyHeader.deco_ndlLength = 2;
+	smallDummyHeader.deco_ndlDivisor = 0;
+
+	/* GF in % at actual position */
+	smallDummyHeader.gfType =  2;
+	smallDummyHeader.gfLength = 1;
+	smallDummyHeader.gfDivisor = 0;
+
+	/* 3 Sensors: 8bit ppO2 in 0.01bar, 16bit voltage in 0,1mV */
+	smallDummyHeader.ppo2Type = 3;
+	smallDummyHeader.ppo2Length = 9;
+	smallDummyHeader.ppo2Divisor = 0;
+
+	/* last 15 stops in minutes (last, second_to_last, ... */
+	/* last stop depth is defined in header */
+	smallDummyHeader.decoplanType = 4;
+	smallDummyHeader.decoplanLength = 15;
+	smallDummyHeader.decoplanDivisor = 0;
+
+	smallDummyHeader.cnsType = 5;
+	smallDummyHeader.cnsLength = 2;
+	smallDummyHeader.cnsDivisor = 0;
+
+	smallDummyHeader.tankType = 6;
+	smallDummyHeader.tankLength = 2;
+	smallDummyHeader.tankDivisor = 0;
+
+	if((overallSecond / smallDummyHeader.samplingRate_seconds) > DUMMY_SAMPLES)		/* reduce sample interval to keep buffer size */
+	{
+		smallDummyHeader.samplingRate_seconds = overallSecond / DUMMY_SAMPLES;
+		dummyProfileLength = DUMMY_SAMPLES;
+	}
+	else
+	{
+		dummyProfileLength = overallSecond / smallDummyHeader.samplingRate_seconds;
+	}
+	logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader));
+	logbook_createDummyProfile(pHeader,dummyProfileLength, depthArray, temperatureArray, ppo2Array );
+
+	for (index = 0; index < dummyProfileLength; index++)
+	{
+		logbook_writeDummySample(depthArray[index], temperatureArray[index]);
+	}
+
+	dummyBufferSize = dummyWriteIdx;
+
+	return dummyBufferSize;		/* return size of dummy buffer */
+}
+
+void logbook_readDummySamples(uint8_t* pTarget, uint16_t length)
+{
+	memcpy(pTarget,&dummyMemoryBuffer[dummyReadIdx],length);
+	dummyReadIdx += length;
+}
+
+
 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- a/Discovery/Src/settings.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/settings.c	Mon Mar 30 13:16:11 2020 +0000
@@ -33,6 +33,7 @@
 #include "text_multilanguage.h" // for LANGUAGE_END
 #include "tHome.h" // for CVIEW_END
 #include "motion.h"
+#include "t7.h"
 
 SSettings Settings;
 
@@ -275,7 +276,7 @@
     .scooterSPARE2[0] = 0,
     .ppo2sensors_deactivated = 0,
     .tX_colorscheme  = 0,
-    .tX_userselectedLeftLowerCornerPrimary = 1,
+    .tX_userselectedLeftLowerCornerPrimary = LLC_Temperature,
     .tX_userselectedLeftLowerCornerTimeout = 0,
     .tX_customViewPrimary = 1,
     .tX_customViewTimeout = 0,
@@ -1161,9 +1162,9 @@
 
 /*	uint8_t tX_userselectedLeftLowerCornerPrimary;
  */
-    if(Settings.tX_userselectedLeftLowerCornerPrimary > 8)
+    if(Settings.tX_userselectedLeftLowerCornerPrimary >= LLC_END)
     {
-        Settings.tX_userselectedLeftLowerCornerPrimary = 1;
+        Settings.tX_userselectedLeftLowerCornerPrimary = LLC_Temperature;
         corrections++;
     }
 
--- a/Discovery/Src/show_logbook.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/show_logbook.c	Mon Mar 30 13:16:11 2020 +0000
@@ -33,6 +33,7 @@
 #include "gfx_fonts.h"
 #include "show_logbook.h"
 #include "unit.h"
+#include "configuration.h"
 
 #include <stdint.h>
 #include <stdio.h>
@@ -425,9 +426,16 @@
     uint16_t depthdata[1000] = { 0 };
     uint8_t  gasdata[1000] = { 0 };
     int16_t tempdata[1000] = { 0 };
+    uint16_t tankdata[1000] = { 0 };
+
+#ifdef ENABLE_BOTTLE_SENSOR
+    uint16_t bottlePressureStart = 0;
+    uint16_t bottlePressureEnd = 0;
+    uint16_t loop = 0;
+#endif
 
     uint16_t dataLength = 0;
-    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tankdata);
 
     //Print Date
     uint8_t year = logbookHeader.dateYear;
@@ -450,7 +458,7 @@
         if(logNumber > 9999)
             logNumber = 9999;
 
-        snprintf(text,20,"#%i",logNumber);
+        snprintf(text,20,"#%ld",logNumber);
         Gfx_write_label_var(hgfx, 300, 590,10, &FontT42,CLUT_GasSensor1,text);
     }
 
@@ -620,7 +628,25 @@
     snprintf(text,40,"%i\016\016 hPa\017",logbookHeader.surfacePressure_mbar);
     Gfx_write_label_var(hgfx,320,600,440, &FontT42,CLUT_GasSensor1,text);
 
-
+/* Show tank info */
+#ifdef ENABLE_BOTTLE_SENSOR
+    for(loop = 0; loop < dataLength; loop++)
+    {
+    	if((bottlePressureStart == 0) && (tankdata[loop] != 0))	/* find first pressure value */
+    	{
+    		bottlePressureStart = tankdata[loop];
+    	}
+    	if((tankdata[loop] != 0))								/* store last pressure value */
+    	{
+    		bottlePressureEnd = tankdata[loop];
+    	}
+    }
+    if(bottlePressureStart != 0)
+    {
+    	snprintf(text,40,"%i | %i\016\016 Bar\017",bottlePressureStart,bottlePressureEnd);
+        Gfx_write_label_var(hgfx,600,800,440, &FontT42,CLUT_GasSensor1,text);
+    }
+#endif
     //--- print coordinate system & depth graph with gaschanges ---
     wintemp.left 	= 330;
     wintemp.top	=  160;
@@ -651,7 +677,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);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, decoDepthdata, NULL);
 
         for(int i = 0; i<dataLength; i++)
         {
@@ -802,7 +828,7 @@
     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);
+    dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 
     //--- print coordinate system & depth graph with gaschanges ---
     show_logbook_draw_depth_graph(hgfx, StepBackwards, &wintemp, 1, dataLength, depthdata, gasdata, NULL);
@@ -860,13 +886,13 @@
 
 
         if(logbookHeader.diveMode != DIVEMODE_CCR)
-            dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+            dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
         else
         {
             if(logbookHeader.CCRmode == CCRMODE_FixedSetpoint)
-                dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL);
+                dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
             else
-                dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL);
+                dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL, NULL);
         }
 
 
--- a/Discovery/Src/simulation.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/simulation.c	Mon Mar 30 13:16:11 2020 +0000
@@ -44,6 +44,8 @@
 #include "buehlmann.h"
 #include "logbook_miniLive.h"
 
+#include "configuration.h"
+
 //Private state variables
 static float sim_aim_depth_meter;
 static _Bool sim_heed_decostops = 1;
@@ -128,7 +130,10 @@
         pDiveState->lifeData.temperature_celsius = stateRealGetPointer()->lifeData.temperature_celsius;
         pDiveState->lifeData.compass_heading = stateRealGetPointer()->lifeData.compass_heading;
         pDiveState->lifeData.battery_charge = stateRealGetPointer()->lifeData.battery_charge;
-
+#ifdef ENABLE_BOTTLE_SENSOR
+        pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = stateRealGetPointer()->lifeData.bottle_bar[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings];
+        pDiveState->lifeData.bottle_bar_age_MilliSeconds[pDiveState->lifeData.actualGas.GasIdInSettings] = stateRealGetPointer()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings];
+#endif
         int now =  current_second();
         if( last_second == now)
                 return;
--- a/Discovery/Src/t7.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/t7.c	Mon Mar 30 13:16:11 2020 +0000
@@ -91,8 +91,7 @@
 GFX_DrawCfgWindow	t7pCompass;
 GFX_DrawCfgWindow	t7surfaceL, t7surfaceR;
 
-uint8_t selection_custom_field = 1;
-uint8_t selection_customview = 1;
+uint8_t selection_customview = LLC_Temperature;
 
 uint8_t updateNecessary = 0;
 
@@ -139,6 +138,9 @@
     CVIEW_END
 };
 
+
+static uint8_t selection_custom_field = LLC_Temperature;
+
 const uint8_t *customviewsDive		= customviewsDiveStandard;
 const uint8_t *customviewsSurface	= customviewsSurfaceStandard;
 
@@ -171,7 +173,7 @@
 	SSettings* pSettings;
 	pSettings = settingsGetPointer();
 
-    selection_custom_field = 1;
+    selection_custom_field = LLC_Temperature;
     selection_customview = customviewsSurface[0];
 
     t7screen.FBStartAdress = 0;
@@ -682,7 +684,9 @@
     uint8_t dateNotSet = 0;
 
     uint8_t oxygen_percentage, gasOffset, actualGasID;
-//	uint16_t bottleFirstGas_bar;
+#ifdef ENABLE_BOTTLE_SENSOR
+	uint16_t bottleFirstGas_bar;
+#endif
     point_t start, stop;//, other;
 
 	SSettings* pSettings;
@@ -1005,14 +1009,15 @@
         GFX_write_string(&FontT48,&t7surfaceL,text,7);
 
         actualGasID = stateUsed->lifeData.actualGas.GasIdInSettings;
-    /*
+
+#ifdef ENABLE_BOTTLE_SENSOR
         bottleFirstGas_bar = stateUsed->lifeData.bottle_bar[actualGasID];
         if(bottleFirstGas_bar)
         {
             snprintf(text,255,"%3u\022\016\016 bar",bottleFirstGas_bar);
             GFX_write_string(&FontT48,&t7surfaceL,text,8);
         }
-    */
+#endif
         // after gas name :-)
         if(actualGasID > gasOffset) // security
         {
@@ -1089,8 +1094,12 @@
             GFX_write_string_color(&Batt24,&t7batt,text,0,CLUT_WarningRed);
             if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140))
             {
+#ifdef ALWAYS_SHOW_VOLTAGE
             	// show battery percent and voltage
                 snprintf(text,16,"\f\002%u%% \f%.1fV",(uint8_t)stateUsed->lifeData.battery_charge,stateUsed->lifeData.battery_voltage);
+#else
+                snprintf(text,16,"\004\025\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge);
+#endif
                 if(warning_count_high_time)
                     text[0] = '\a';
                 GFX_write_string(&FontT24,&t7voltage,text,0);
@@ -1107,9 +1116,12 @@
 
             if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140))
             {
+#ifdef ALWAYS_SHOW_VOLTAGE
             	// show battery percent and voltage
                 snprintf(text,16,"\f\002%u%% \f%.1fV",(uint8_t)stateUsed->lifeData.battery_charge,stateUsed->lifeData.battery_voltage);
-        //        GFX_write_string(&FontT24,&t7batt,text,0);
+#else
+                 snprintf(text,16,"\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge);
+#endif
                 GFX_write_string(&FontT24,&t7voltage,text,0);
             }
             else
@@ -2521,18 +2533,17 @@
 
 void t7_change_field(void)
 {
-    const uint8_t minVal = 0;
-    const uint8_t maxValGF 	= 8;
-    const uint8_t maxValVPM = 7;
-    uint8_t maxNow = maxValGF;
-
     selection_custom_field++;
 
-    if(stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE)
-        maxNow = maxValVPM;
-
-    if(selection_custom_field > maxNow)
-        selection_custom_field = minVal;
+    if((stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE) && (selection_custom_field == LLC_GF)) /* no GF if in VPM mode */
+    {
+    	selection_custom_field++;
+    }
+
+    if(selection_custom_field >= LLC_END)
+    {
+        selection_custom_field = LLC_Empty;
+    }
 }
 
 
@@ -2546,6 +2557,9 @@
     uint8_t textpointer = 0;
     _Bool tinyHeaderFont = 0;
     uint8_t line = 0;
+#ifdef ENABLE_BOTTLE_SENSOR
+    uint16_t agedColor = 0;
+#endif
 
     SDivetime Stopwatch = {0,0,0,0};
     float fAverageDepth, fAverageDepthAbsolute;
@@ -2577,7 +2591,7 @@
     switch(selection_custom_field)
     {
     /* Temperature */
-    case 1:
+    case LLC_Temperature:
     default:
     	temperature = unit_temperature_float(stateUsed->lifeData.temperature_celsius);
         headerText[2] = TXT_Temperature;
@@ -2591,7 +2605,7 @@
         break;
 
     /* Average Depth */
-    case 2:
+    case LLC_AverageDepth:
         headerText[2] = TXT_AvgDepth;
         if(settingsGetPointer()->nonMetricalSystem)
             snprintf(text,TEXTSIZE,"\020%01.0f",unit_depth_float(fAverageDepthAbsolute));
@@ -2600,13 +2614,13 @@
         break;
 
     /* ppO2 */
-    case 3:
+    case LLC_ppO2:
         headerText[2] = TXT_ppO2;
         snprintf(text,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2);
         break;
 
     /* Stop Uhr */
-    case 4:
+    case LLC_Stopwatch:
         headerText[2] = TXT_Stopwatch;
         if(settingsGetPointer()->nonMetricalSystem)
             snprintf(text,TEXTSIZE,"\020\016\016%u:%02u\n\r%01.0f",Stopwatch.Minutes, Stopwatch.Seconds,unit_depth_float(fAverageDepth));
@@ -2617,7 +2631,7 @@
         break;
 
     /* Ceiling */
-    case 5:
+    case LLC_Ceiling:
         headerText[2] = TXT_Ceiling;
         if((pDecoinfoStandard->output_ceiling_meter > 99.9f) || (settingsGetPointer()->nonMetricalSystem))
             snprintf(text,TEXTSIZE,"\020%01.0f",unit_depth_float(pDecoinfoStandard->output_ceiling_meter));
@@ -2626,7 +2640,7 @@
         break;
 
     /* Future TTS */
-    case 6:
+    case LLC_FutureTTS:
         headerText[2] = TXT_FutureTTS;
         if (pDecoinfoFuture->output_time_to_surface_seconds < 1000 * 60)
         	snprintf(text,TEXTSIZE,"\020\016\016@+%u'\n\r" "%i' TTS",settingsGetPointer()->future_TTS, (pDecoinfoFuture->output_time_to_surface_seconds + 59) / 60);
@@ -2637,7 +2651,7 @@
         break;
 
     /* CNS */
-    case 7:
+    case LLC_CNS:
         headerText[2] = TXT_CNS;
         fCNS = stateUsed->lifeData .cns;
         if(fCNS > 999)
@@ -2646,10 +2660,17 @@
         break;
 
     /* actual GF */
-    case 8:
+    case LLC_GF:
         headerText[2] = TXT_ActualGradient;
         snprintf(text,TEXTSIZE,"\020%.0f\016\016%%\017",100 * pDecoinfoStandard->super_saturation);
         break;
+#ifdef ENABLE_BOTTLE_SENSOR
+    case LCC_BottleBar:
+        headerText[2] = TXT_AtemGasVorrat;
+        tinyHeaderFont = 1;
+        snprintf(text,TEXTSIZE,"%d\016\016\017", stateUsed->lifeData.bottle_bar[stateUsed->lifeData.actualGas.GasIdInSettings]);
+        break;
+#endif
     }
     headerText[3] = 0;
 
@@ -2659,7 +2680,38 @@
         GFX_write_string(&FontT42,&t7l3,headerText,0);
 
     t7_colorscheme_mod(text);
-    GFX_write_string(&FontT105,&t7l3,text,line);
+#ifndef ENABLE_BOTTLE_SENSOR
+   	GFX_write_string(&FontT105,&t7l3,text,line);
+#else
+    if(selection_custom_field != LCC_BottleBar)			/* a changing color set is used for bar display */
+    {
+    	GFX_write_string(&FontT105,&t7l3,text,line);
+    }
+    else
+    {
+    	agedColor = stateUsed->lifeData.bottle_bar_age_MilliSeconds[stateUsed->lifeData.actualGas.GasIdInSettings];
+    	if(agedColor > 1200)
+    	{
+    		agedColor = CLUT_WarningRed;
+    	}
+    	else
+    	if(agedColor > 600)
+        {
+        	agedColor = CLUT_MenuLineUnselected;
+        }
+        else
+    	if(agedColor > 20)
+    	{
+    		agedColor = CLUT_Font031;
+    	}
+    	else
+    	{
+    		agedColor = CLUT_Font020;
+    	}
+
+    	GFX_write_string_color(&FontT105,&t7l3,text,line,agedColor);
+    }
+#endif
 }
 
 /* Private functions ---------------------------------------------------------*/
--- a/Discovery/Src/tCCR.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/tCCR.c	Mon Mar 30 13:16:11 2020 +0000
@@ -33,6 +33,7 @@
 #include "data_central.h"
 #include "data_exchange.h"
 #include "check_warning.h"
+#include "configuration.h"
 
 /* Private types -------------------------------------------------------------*/
 typedef struct
@@ -52,6 +53,8 @@
 #define HUD_RX_START_DELAY_MS		(500u)		/* Delay for start of RX function to avoid start of reception while a transmission is ongoing. */
 												/* Based on an assumed cycle time by the sensor of 1 second. Started at time of last RX */
 
+#define BOTTLE_SENSOR_TIMEOUT		(6000u)     /* signal pressure budget as not received after 10 minutes (6000 * 100ms) */
+
 /* Private variables ---------------------------------------------------------*/
 static SIrLink receiveHUD[2];
 static uint8_t boolHUDdata = 0;
@@ -289,7 +292,15 @@
 
 void tCCR_init(void)
 {
+	uint8_t loop;
+
     StartListeningToUART_HUD = 1;
+
+    SDiveState* pDiveData = stateRealGetPointerWrite();
+    for(loop=0;loop<(2*NUM_GASES+1);loop++)
+    {
+    	pDiveData->lifeData.bottle_bar_age_MilliSeconds[loop] =  BOTTLE_SENSOR_TIMEOUT;
+    }
 }
 
 
@@ -350,6 +361,10 @@
 
 void tCCR_control(void)
 {
+	uint16_t checksum = 0;
+#ifdef ENABLE_BOTTLE_SENSOR
+	SDiveState *pLivedata = stateRealGetPointerWrite();
+#endif
 
 	if((UartReadyHUD == RESET) && StartListeningToUART_HUD && (time_elapsed_ms(LastReceivedTick_HUD, HAL_GetTick()) > HUD_RX_START_DELAY_MS))
 	{
@@ -362,31 +377,41 @@
             UartReadyHUD = RESET;
             StartListeningToUART_HUD = 1;
 
-            memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11);
-            receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]);
-            receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]);
-
-            uint16_t checksum = 0;
+    /* check if received package is valid */
+			for(int i=0;i<13;i++)
+			{
+				checksum += receiveHUDraw[i];
+			}
+			receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]);
+			if(checksum == receiveHUD[!boolHUDdata].checksum)
+			{
+#ifdef ENABLE_BOTTLE_SENSOR
+		        if(receiveHUDraw[0] == 0xA5)				/* code for pressure sensor */
+		        {
+		        	pLivedata->lifeData.bottle_bar[pLivedata->lifeData.actualGas.GasIdInSettings] = receiveHUDraw[10];
+		        	pLivedata->lifeData.bottle_bar_age_MilliSeconds[pLivedata->lifeData.actualGas.GasIdInSettings] = 0;
+		        }
+		        else
+#endif
+		        											/* handle O2 sensor data */
+		        {
+		        	memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11);
+					receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]);
+		        }
 
-            for(int i=0;i<13;i++)
-            {
-                checksum += receiveHUDraw[i];
-            }
-            if(checksum == receiveHUD[!boolHUDdata].checksum)
-            {
-                boolHUDdata = !boolHUDdata;
-                HUDTimeoutCount = 0;
-                data_old__lost_connection_to_HUD = 0;
-            }
-            else
-            {
-            	if(data_old__lost_connection_to_HUD)	/* we lost connection, maybe due to RX shift => start single byte read to resynchronize */
-            	{
-            		HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1);
-            		StartListeningToUART_HUD = 0;
-            	}
-            }
-            memset(receiveHUDraw,0,sizeof(receiveHUDraw));
+				boolHUDdata = !boolHUDdata;
+				HUDTimeoutCount = 0;
+				data_old__lost_connection_to_HUD = 0;
+			}
+			else
+			{
+				if(data_old__lost_connection_to_HUD)	/* we lost connection, maybe due to RX shift => start single byte read to resynchronize */
+				{
+					HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1);
+					StartListeningToUART_HUD = 0;
+				}
+			}
+			memset(receiveHUDraw,0,sizeof(receiveHUDraw));
     }
 }
 
--- a/Discovery/Src/tComm.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/tComm.c	Mon Mar 30 13:16:11 2020 +0000
@@ -583,7 +583,6 @@
 #else
     uint8_t dummyForBootloader[256] = {0};
 #endif
-
     uint8_t count;
     uint8_t aTxBuffer[128];
     uint8_t aRxBuffer[68];
@@ -1182,21 +1181,45 @@
         plogbookHeaderOSTC3 = logbook_build_ostc3header(&logbookHeader);
         if(HAL_UART_Transmit(&UartHandle, (uint8_t*)plogbookHeaderOSTC3, 256,5000)!= HAL_OK)
             return 0;
-        ext_flash_open_read_sample(255 - aRxBuffer[0], &sampleTotalLength);
-        while(sampleTotalLength >= 128)
+
+        if((logbookHeader.pBeginProfileData[0]==0)	/* no sample information */
+        	&& (logbookHeader.pBeginProfileData[1]==0)
+			&& (logbookHeader.pBeginProfileData[2]==0))
         {
-            ext_flash_read_next_sample_part(aTxBuffer,128);
-            sampleTotalLength -= 128;
-            if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK)
-                return 0;
+        	sampleTotalLength = logbook_fillDummySampleBuffer(&logbookHeader);
+			while(sampleTotalLength >= 128)
+			{
+				logbook_readDummySamples(aTxBuffer,128);
+				sampleTotalLength -= 128;
+				if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK)
+					return 0;
+			}
+			if(sampleTotalLength)
+			{
+				logbook_readDummySamples(aTxBuffer,sampleTotalLength);
+				if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK)
+					return 0;
+			}
+
         }
-        if(sampleTotalLength)
+        else
         {
-            ext_flash_read_next_sample_part(aTxBuffer,sampleTotalLength);
-            if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK)
-                return 0;
+			ext_flash_open_read_sample(255 - aRxBuffer[0], &sampleTotalLength);
+			while(sampleTotalLength >= 128)
+			{
+				ext_flash_read_next_sample_part(aTxBuffer,128);
+				sampleTotalLength -= 128;
+				if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK)
+					return 0;
+			}
+			if(sampleTotalLength)
+			{
+				ext_flash_read_next_sample_part(aTxBuffer,sampleTotalLength);
+				if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK)
+					return 0;
+			}
         }
-        aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
+		aTxBuffer[count++] = prompt4D4C(receiveStartByteUart);
         break;
 
         // read min,default,max setting
--- a/Discovery/Src/tInfoLog.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/tInfoLog.c	Mon Mar 30 13:16:11 2020 +0000
@@ -36,6 +36,8 @@
 #include "tInfo.h"
 #include "tMenu.h"
 #include "unit.h"
+#include "externLogbookFlash.h"
+#include "configuration.h"
 
 /* Exported variables --------------------------------------------------------*/
 
@@ -64,6 +66,9 @@
 void stepBackInfo(void);
 void stepForwardInfo(void);
 void showLogExit(void);
+#ifdef ENABLE_PROFILE_RESET
+void resetDiveProfile(void);
+#endif
 
 /* Exported functions --------------------------------------------------------*/
 void tInfoLog_init(void)
@@ -176,6 +181,9 @@
     switch(sendAction)
     {
     case ACTION_BUTTON_ENTER:
+#ifdef ENABLE_PROFILE_RESET
+    	resetDiveProfile();
+#endif
         break;
     case ACTION_BUTTON_NEXT:
         showNextLogPage();
@@ -429,4 +437,21 @@
     show_logbook_test(0, stepBack);
 }
 
+#ifdef ENABLE_PROFILE_RESET
+void resetDiveProfile()
+{
+	uint8_t stepBack;
+	SLogbookHeader logbookHeader;
+	convert_Type dataStart;
+	stepBack = (6 * (infolog.page - 1)) + infolog.line - 1; /* calculate current dive ID */
+	logbook_getHeader(stepBack ,&logbookHeader);
 
+    dataStart.u8bit.byteHigh = 0;
+    dataStart.u8bit.byteLow = logbookHeader.pBeginProfileData[0];
+    dataStart.u8bit.byteMidLow = logbookHeader.pBeginProfileData[1];
+    dataStart.u8bit.byteMidHigh = logbookHeader.pBeginProfileData[2];
+
+    dataStart.u32bit &= 0xFFFF0000;		/* set to sector start */
+	ext_flash_invalidate_sample_index(dataStart.u32bit);
+}
+#endif
--- a/Discovery/Src/tMenuEditSystem.c	Sun Mar 01 10:06:45 2020 +0100
+++ b/Discovery/Src/tMenuEditSystem.c	Mon Mar 30 13:16:11 2020 +0000
@@ -876,38 +876,43 @@
     switch(settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary)
     {
     /* Temperature */
-    case 1:
+    case LLC_Temperature:
         text[4] = TXT_Temperature;
         break;
     /* Average Depth */
-    case 2:
+    case LLC_AverageDepth:
         text[4] = TXT_AvgDepth;
         break;
     /* ppO2 */
-    case 3:
+    case LLC_ppO2:
         text[4] = TXT_ppO2;
         break;
     /* Stop Uhr */
-    case 4:
+    case LLC_Stopwatch:
         text[4] = TXT_Stopwatch;
         break;
     /* Ceiling */
-    case 5:
+    case LLC_Ceiling:
         text[4] = TXT_Ceiling;
         break;
     /* Future TTS */
-    case 6:
+    case LLC_FutureTTS:
         text[4] = TXT_FutureTTS;
         break;
     /* CNS */
-    case 7:
+    case LLC_CNS:
         text[4] = TXT_CNS;
         break;
-    case 8:
+    case LLC_GF:
     	text[4] = TXT_ActualGradient;
     	break;
+#ifdef ENABLE_BOTTLE_SENSOR
+    case LCC_BottleBar:
+    	text[4] = TXT_AtemGasVorrat;
+    	    	break;
+#endif
     /* none */
-    case 0:
+    case LLC_Empty:
         text[4] = '-';
         break;
     default:
@@ -1080,7 +1085,7 @@
 
     value += 1;
 
-    if(value > 8)
+    if(value >= LLC_END)
         value = 0;
 
     settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary = value;