# HG changeset patch # User Ideenmodellierer # Date 1611781964 -3600 # Node ID bf574fb3efa0d6e8648acdbd4d102f6cea40b22e # Parent 8fa2de4414a8bd5e702a5850fa9805e0040fec3f 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" diff -r 8fa2de4414a8 -r bf574fb3efa0 Discovery/Inc/logbook_miniLive.h --- 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 */ diff -r 8fa2de4414a8 -r bf574fb3efa0 Discovery/Src/logbook_miniLive.c --- 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;imode == 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)