changeset 620:bf574fb3efa0

Added minilog functions to allow marker synchronisation: To keep the live data in the background a second buffer had to be added which stored the live data modified to match a specific marker. To archive this stretching and compression functions have been added. In addition a type has been solved "life"=>"live"
author Ideenmodellierer
date Wed, 27 Jan 2021 22:12:44 +0100
parents 8fa2de4414a8
children 6826731ff2be
files Discovery/Inc/logbook_miniLive.h Discovery/Src/logbook_miniLive.c
diffstat 2 files changed, 183 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/Discovery/Inc/logbook_miniLive.h	Wed Jan 27 22:10:11 2021 +0100
+++ b/Discovery/Inc/logbook_miniLive.h	Wed Jan 27 22:12:44 2021 +0100
@@ -43,5 +43,7 @@
 uint8_t getReplayInfo(uint16_t** pReplayData, uint8_t** pReplayMarker, uint16_t* DataLength, uint16_t* MaxDepth, uint16_t* diveMinutes);
 uint16_t getReplayDataResolution(void);
 uint16_t getReplayOffset(void);
+uint16_t MiniLiveLogbook_getNextMarkerIndex(uint16_t curIndex);
+void MiniLiveLogbook_checkMarker(void);
 
 #endif /* LOGBOOK_MINI_LIVE_H */
--- a/Discovery/Src/logbook_miniLive.c	Wed Jan 27 22:10:11 2021 +0100
+++ b/Discovery/Src/logbook_miniLive.c	Wed Jan 27 22:12:44 2021 +0100
@@ -46,14 +46,18 @@
 uint16_t ReplayDepthData[DEPTH_DATA_LENGTH];
 uint8_t ReplayMarkerData[DEPTH_DATA_LENGTH];
 uint16_t liveDepthData[DEPTH_DATA_LENGTH];
+uint16_t liveDepthDataMod[DEPTH_DATA_LENGTH];	/* live data modified to fit to marker checks */
 uint16_t liveDecoData[DEPTH_DATA_LENGTH];
-static uint16_t lifeDataIndex = 0;
+uint16_t liveDecoDataMod[DEPTH_DATA_LENGTH];
+static uint16_t liveDataIndex = 0;
+static uint16_t liveDataIndexMod = 0;
 
 static uint8_t	ReplayDataResolution = 2;		/* Time represented by one sample (second) */
 static uint16_t ReplayDataLength = 0;			/* Number of data entries */
 static uint16_t ReplayDataMaxDepth = 0;
 static uint16_t ReplayDataMinutes = 0;
 static uint16_t ReplayDataOffset = 0xFFFF;		/* Stepbackwards format used by log functions */
+static uint16_t  ReplayMarkerIndex = 0;
 
 uint16_t *getMiniLiveLogbookPointerToData(void)
 {
@@ -65,13 +69,151 @@
 {
 	return MLLpointer;
 }
+
+uint16_t MiniLiveLogbook_getNextMarkerIndex(uint16_t curIndex)
+{
+	uint16_t index = 0;
 	
+	if((ReplayMarkerData[0] != 0xFF) && (curIndex < ReplayDataLength))
+	{
+		index = curIndex;
+		do
+		{
+			index++;
+			if (index == ReplayDataLength)
+			{
+				index = 0;
+			}
+			if(ReplayMarkerData[index] != 0)
+			{
+				break;
+			}
+		}while (index != curIndex);
+	}
+	return index;
+}
+
+static uint16_t workdata[DEPTH_DATA_LENGTH];
+static void compressMarkerData(uint16_t* pSource, uint16_t* pTarget, float step, uint16_t startIndex, uint16_t stopIndex)
+{
+	uint16_t workIndex = startIndex;
+	float nextStep = (float)workIndex;
+
+	while (workIndex <= ReplayMarkerIndex)
+	{
+		workdata[workIndex] = *pSource++;
+		nextStep += step;
+		while(nextStep < workIndex + 1)
+		{
+			if(*pSource != 0xFFFF)					/* do not average "ignore" value */
+			{
+				if(workdata[workIndex] == 0xFFFF)	/* first value to be shown */
+				{
+					workdata[workIndex] = *pSource;
+				}
+				else
+				{
+					workdata[workIndex] += *pSource;
+					workdata[workIndex] /= 2;
+				}
+			}
+			pSource++;
+			nextStep += step;
+		}
+		workIndex++;
+	}
+	memcpy(&pTarget[startIndex],&workdata[startIndex],(workIndex - startIndex -1) * 2);
+	while(workIndex < DEPTH_DATA_LENGTH)
+	{
+		pTarget[workIndex] = 0xFFFF;
+		workIndex++;
+	}
+}
+static void stretchMarkerData(uint16_t* pSource, uint16_t* pTarget, float step, uint16_t startIndex, uint16_t stopIndex)
+{
+	uint16_t workIndex = startIndex;
+	float nextStep = (float)workIndex;
+
+	while (workIndex <= stopIndex)
+	{
+		nextStep += step;
+		if(nextStep > stopIndex)
+		{
+			nextStep = stopIndex;
+		}
+		while(workIndex <= (uint16_t)nextStep)
+		{
+			workdata[workIndex++] = *pSource;
+		}
+		pSource++;
+	}
+	memcpy(&pTarget[startIndex],&workdata[startIndex],(workIndex - startIndex) * 2);
+	while(workIndex < DEPTH_DATA_LENGTH)
+	{
+		pTarget[workIndex] = 0xFFFF;
+		workIndex++;
+	}
+}
+
+void MiniLiveLogbook_checkMarker(void)
+{
+	static uint16_t lastLifeIndex = 0;
+	uint16_t* pDepthData;
+	uint16_t* pDecoData;
+	float step;
+	uint16_t lastMarkerIndex = ReplayMarkerIndex;
+
+	ReplayMarkerIndex = MiniLiveLogbook_getNextMarkerIndex(ReplayMarkerIndex);
+	if(ReplayMarkerIndex <= lastMarkerIndex)		/* no other marker found or last marker checked => reset marker to 0 to deactivate check function */
+	{
+		ReplayMarkerIndex = 0;
+		lastLifeIndex = 0;
+		liveDataIndexMod = liveDataIndex;
+	}
+	else
+	{
+		if(lastMarkerIndex == 0)	/* use real live data */
+		{
+			pDepthData = &liveDepthData[0];
+			pDecoData = &liveDecoData[0];
+			lastLifeIndex = 0;
+		}
+		else
+		{
+			pDepthData = &liveDepthDataMod[lastMarkerIndex];  /* work with already modified data */
+			pDecoData = &liveDecoDataMod[lastMarkerIndex];
+		}
+		if(lastLifeIndex == liveDataIndex)					/* repeated button press before new data was generated => draw straight line */
+		{
+			step = ReplayMarkerIndex-lastMarkerIndex;
+		}
+		else
+		{
+			step = (ReplayMarkerIndex-lastMarkerIndex) / (float)(liveDataIndex - lastLifeIndex); /* the live data shall be modified to match the history data */
+		}
+
+		lastLifeIndex = liveDataIndex;
+
+		if(step < 1)		/* compression needed */
+		{
+			compressMarkerData(pDepthData, liveDepthDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
+			compressMarkerData(pDecoData, liveDecoDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
+		}
+		else				/* stretch data */
+		{
+			stretchMarkerData(pDepthData, liveDepthDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
+			stretchMarkerData(pDecoData, liveDecoDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
+		}
+		liveDataIndexMod = ReplayMarkerIndex;
+	}
+}
+
+
 void compressBuffer_uint16(uint16_t* pdata, uint16_t size)
 {
 	uint16_t* pTarget = pdata;
 	uint16_t* pSource = pdata;
 	uint16_t  result = 0;
-	
 	uint16_t index = 0;
 	
 	for(index = 0; index < size/2; index++)
@@ -123,14 +265,15 @@
 			for(int i=0;i<MLLsize;i++)
 				MLLdataDepth[i] = 0;
 
-			for(lifeDataIndex = 0; lifeDataIndex < DEPTH_DATA_LENGTH; lifeDataIndex++)
+			for(liveDataIndex = 0; liveDataIndex < DEPTH_DATA_LENGTH; liveDataIndex++)
 			{
-				liveDepthData[lifeDataIndex] = 0xFFFF;
-				liveDecoData[lifeDataIndex] = 0xFFFF;
+				liveDepthData[liveDataIndex] = 0xFFFF;
+				liveDecoData[liveDataIndex] = 0xFFFF;
 			}
 			lifesecondsCount = 0;
-			lifeDataIndex = 0;
-			liveDepthData[lifeDataIndex++] = 0;	/* start at 0 */
+			liveDataIndex = 0;
+			liveDataIndexMod = 0;
+			liveDepthData[liveDataIndex++] = 0;	/* start at 0 */
 		}
 	}
 	else if(stateUsed->mode == MODE_DIVE)
@@ -156,14 +299,18 @@
 		{
 			lifesecondsCount = 0;
 
-			if(lifeDataIndex >= DEPTH_DATA_LENGTH)		/* compress data */
+			if(liveDataIndex >= DEPTH_DATA_LENGTH)		/* compress data */
 			{
 				ReplayDataResolution *= 2;
 				compressBuffer_uint16(liveDepthData,DEPTH_DATA_LENGTH);
-				compressBuffer_uint16(ReplayDepthData,DEPTH_DATA_LENGTH);		/* also compress Replay data to siplify mapping between live and replay data */
-				lifeDataIndex = DEPTH_DATA_LENGTH / 2;
+				compressBuffer_uint16(liveDepthDataMod, DEPTH_DATA_LENGTH);
+				compressBuffer_uint16(ReplayDepthData,DEPTH_DATA_LENGTH);		/* also compress Replay data to simplify mapping between live and replay data */
+				liveDataIndex = DEPTH_DATA_LENGTH / 2;
+				liveDataIndexMod /= 2;
 			}
-			liveDepthData[lifeDataIndex] = (int)(stateUsed->lifeData.depth_meter * 100);
+			liveDepthData[liveDataIndex] = (int)(stateUsed->lifeData.depth_meter * 100);
+			liveDepthDataMod[liveDataIndexMod] = liveDepthData[liveDataIndex];
+
 			if(stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE)
 			{
 				pDecoinfo = &stateUsed->decolistVPM;
@@ -175,13 +322,16 @@
 			tHome_findNextStop(pDecoinfo->output_stop_length_seconds, &stopDepth, &stopTime);
 			if(stopDepth)
 			{
-				liveDecoData[lifeDataIndex] = stopDepth * 100;
+				liveDecoData[liveDataIndex] = stopDepth * 100;
+				liveDecoDataMod[liveDataIndexMod] = stopDepth * 100;
 			}
 			else
 			{
-				liveDecoData[lifeDataIndex] = 0xFFFF;
+				liveDecoData[liveDataIndex] = 0xFFFF;
+				liveDecoDataMod[liveDataIndexMod] = 0xFFFF;
 			}
-			lifeDataIndex++;
+			liveDataIndex++;
+			liveDataIndexMod++;
 		}
 	}
 	else if(bDiveMode == 3)
@@ -271,15 +421,29 @@
 
 uint16_t *getMiniLiveReplayPointerToData(void)
 {
-	return liveDepthData;
+	if(ReplayMarkerIndex == 0)
+	{
+		return liveDepthData;
+	}
+	else
+	{
+		return liveDepthDataMod;
+	}
 }
 uint16_t *getMiniLiveDecoPointerToData(void)
 {
-	return liveDecoData;
+	if(ReplayMarkerIndex == 0)
+	{
+		return liveDecoData;
+	}
+	else
+	{
+		return liveDecoDataMod;
+	}
 }
 uint16_t getMiniLiveReplayLength(void)
 {
-	return lifeDataIndex;
+	return liveDataIndex;
 }
 
 uint16_t getReplayOffset(void)