comparison Discovery/Src/logbook_miniLive.c @ 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 ae7f8333c900
children
comparison
equal deleted inserted replaced
619:8fa2de4414a8 620:bf574fb3efa0
44 /* Replay Block data storage */ 44 /* Replay Block data storage */
45 #define DEPTH_DATA_LENGTH (1800u) /* Resolution: 1 hours dive, sampling every 2 seconds */ 45 #define DEPTH_DATA_LENGTH (1800u) /* Resolution: 1 hours dive, sampling every 2 seconds */
46 uint16_t ReplayDepthData[DEPTH_DATA_LENGTH]; 46 uint16_t ReplayDepthData[DEPTH_DATA_LENGTH];
47 uint8_t ReplayMarkerData[DEPTH_DATA_LENGTH]; 47 uint8_t ReplayMarkerData[DEPTH_DATA_LENGTH];
48 uint16_t liveDepthData[DEPTH_DATA_LENGTH]; 48 uint16_t liveDepthData[DEPTH_DATA_LENGTH];
49 uint16_t liveDepthDataMod[DEPTH_DATA_LENGTH]; /* live data modified to fit to marker checks */
49 uint16_t liveDecoData[DEPTH_DATA_LENGTH]; 50 uint16_t liveDecoData[DEPTH_DATA_LENGTH];
50 static uint16_t lifeDataIndex = 0; 51 uint16_t liveDecoDataMod[DEPTH_DATA_LENGTH];
52 static uint16_t liveDataIndex = 0;
53 static uint16_t liveDataIndexMod = 0;
51 54
52 static uint8_t ReplayDataResolution = 2; /* Time represented by one sample (second) */ 55 static uint8_t ReplayDataResolution = 2; /* Time represented by one sample (second) */
53 static uint16_t ReplayDataLength = 0; /* Number of data entries */ 56 static uint16_t ReplayDataLength = 0; /* Number of data entries */
54 static uint16_t ReplayDataMaxDepth = 0; 57 static uint16_t ReplayDataMaxDepth = 0;
55 static uint16_t ReplayDataMinutes = 0; 58 static uint16_t ReplayDataMinutes = 0;
56 static uint16_t ReplayDataOffset = 0xFFFF; /* Stepbackwards format used by log functions */ 59 static uint16_t ReplayDataOffset = 0xFFFF; /* Stepbackwards format used by log functions */
60 static uint16_t ReplayMarkerIndex = 0;
57 61
58 uint16_t *getMiniLiveLogbookPointerToData(void) 62 uint16_t *getMiniLiveLogbookPointerToData(void)
59 { 63 {
60 return MLLdataDepth; 64 return MLLdataDepth;
61 } 65 }
63 67
64 uint16_t getMiniLiveLogbookActualDataLength(void) 68 uint16_t getMiniLiveLogbookActualDataLength(void)
65 { 69 {
66 return MLLpointer; 70 return MLLpointer;
67 } 71 }
72
73 uint16_t MiniLiveLogbook_getNextMarkerIndex(uint16_t curIndex)
74 {
75 uint16_t index = 0;
68 76
77 if((ReplayMarkerData[0] != 0xFF) && (curIndex < ReplayDataLength))
78 {
79 index = curIndex;
80 do
81 {
82 index++;
83 if (index == ReplayDataLength)
84 {
85 index = 0;
86 }
87 if(ReplayMarkerData[index] != 0)
88 {
89 break;
90 }
91 }while (index != curIndex);
92 }
93 return index;
94 }
95
96 static uint16_t workdata[DEPTH_DATA_LENGTH];
97 static void compressMarkerData(uint16_t* pSource, uint16_t* pTarget, float step, uint16_t startIndex, uint16_t stopIndex)
98 {
99 uint16_t workIndex = startIndex;
100 float nextStep = (float)workIndex;
101
102 while (workIndex <= ReplayMarkerIndex)
103 {
104 workdata[workIndex] = *pSource++;
105 nextStep += step;
106 while(nextStep < workIndex + 1)
107 {
108 if(*pSource != 0xFFFF) /* do not average "ignore" value */
109 {
110 if(workdata[workIndex] == 0xFFFF) /* first value to be shown */
111 {
112 workdata[workIndex] = *pSource;
113 }
114 else
115 {
116 workdata[workIndex] += *pSource;
117 workdata[workIndex] /= 2;
118 }
119 }
120 pSource++;
121 nextStep += step;
122 }
123 workIndex++;
124 }
125 memcpy(&pTarget[startIndex],&workdata[startIndex],(workIndex - startIndex -1) * 2);
126 while(workIndex < DEPTH_DATA_LENGTH)
127 {
128 pTarget[workIndex] = 0xFFFF;
129 workIndex++;
130 }
131 }
132 static void stretchMarkerData(uint16_t* pSource, uint16_t* pTarget, float step, uint16_t startIndex, uint16_t stopIndex)
133 {
134 uint16_t workIndex = startIndex;
135 float nextStep = (float)workIndex;
136
137 while (workIndex <= stopIndex)
138 {
139 nextStep += step;
140 if(nextStep > stopIndex)
141 {
142 nextStep = stopIndex;
143 }
144 while(workIndex <= (uint16_t)nextStep)
145 {
146 workdata[workIndex++] = *pSource;
147 }
148 pSource++;
149 }
150 memcpy(&pTarget[startIndex],&workdata[startIndex],(workIndex - startIndex) * 2);
151 while(workIndex < DEPTH_DATA_LENGTH)
152 {
153 pTarget[workIndex] = 0xFFFF;
154 workIndex++;
155 }
156 }
157
158 void MiniLiveLogbook_checkMarker(void)
159 {
160 static uint16_t lastLifeIndex = 0;
161 uint16_t* pDepthData;
162 uint16_t* pDecoData;
163 float step;
164 uint16_t lastMarkerIndex = ReplayMarkerIndex;
165
166 ReplayMarkerIndex = MiniLiveLogbook_getNextMarkerIndex(ReplayMarkerIndex);
167 if(ReplayMarkerIndex <= lastMarkerIndex) /* no other marker found or last marker checked => reset marker to 0 to deactivate check function */
168 {
169 ReplayMarkerIndex = 0;
170 lastLifeIndex = 0;
171 liveDataIndexMod = liveDataIndex;
172 }
173 else
174 {
175 if(lastMarkerIndex == 0) /* use real live data */
176 {
177 pDepthData = &liveDepthData[0];
178 pDecoData = &liveDecoData[0];
179 lastLifeIndex = 0;
180 }
181 else
182 {
183 pDepthData = &liveDepthDataMod[lastMarkerIndex]; /* work with already modified data */
184 pDecoData = &liveDecoDataMod[lastMarkerIndex];
185 }
186 if(lastLifeIndex == liveDataIndex) /* repeated button press before new data was generated => draw straight line */
187 {
188 step = ReplayMarkerIndex-lastMarkerIndex;
189 }
190 else
191 {
192 step = (ReplayMarkerIndex-lastMarkerIndex) / (float)(liveDataIndex - lastLifeIndex); /* the live data shall be modified to match the history data */
193 }
194
195 lastLifeIndex = liveDataIndex;
196
197 if(step < 1) /* compression needed */
198 {
199 compressMarkerData(pDepthData, liveDepthDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
200 compressMarkerData(pDecoData, liveDecoDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
201 }
202 else /* stretch data */
203 {
204 stretchMarkerData(pDepthData, liveDepthDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
205 stretchMarkerData(pDecoData, liveDecoDataMod, step, lastMarkerIndex, ReplayMarkerIndex);
206 }
207 liveDataIndexMod = ReplayMarkerIndex;
208 }
209 }
210
211
69 void compressBuffer_uint16(uint16_t* pdata, uint16_t size) 212 void compressBuffer_uint16(uint16_t* pdata, uint16_t size)
70 { 213 {
71 uint16_t* pTarget = pdata; 214 uint16_t* pTarget = pdata;
72 uint16_t* pSource = pdata; 215 uint16_t* pSource = pdata;
73 uint16_t result = 0; 216 uint16_t result = 0;
74
75 uint16_t index = 0; 217 uint16_t index = 0;
76 218
77 for(index = 0; index < size/2; index++) 219 for(index = 0; index < size/2; index++)
78 { 220 {
79 *pTarget = *pSource++; 221 *pTarget = *pSource++;
121 bDiveMode = 1; 263 bDiveMode = 1;
122 MLLpointer = 1; 264 MLLpointer = 1;
123 for(int i=0;i<MLLsize;i++) 265 for(int i=0;i<MLLsize;i++)
124 MLLdataDepth[i] = 0; 266 MLLdataDepth[i] = 0;
125 267
126 for(lifeDataIndex = 0; lifeDataIndex < DEPTH_DATA_LENGTH; lifeDataIndex++) 268 for(liveDataIndex = 0; liveDataIndex < DEPTH_DATA_LENGTH; liveDataIndex++)
127 { 269 {
128 liveDepthData[lifeDataIndex] = 0xFFFF; 270 liveDepthData[liveDataIndex] = 0xFFFF;
129 liveDecoData[lifeDataIndex] = 0xFFFF; 271 liveDecoData[liveDataIndex] = 0xFFFF;
130 } 272 }
131 lifesecondsCount = 0; 273 lifesecondsCount = 0;
132 lifeDataIndex = 0; 274 liveDataIndex = 0;
133 liveDepthData[lifeDataIndex++] = 0; /* start at 0 */ 275 liveDataIndexMod = 0;
276 liveDepthData[liveDataIndex++] = 0; /* start at 0 */
134 } 277 }
135 } 278 }
136 else if(stateUsed->mode == MODE_DIVE) 279 else if(stateUsed->mode == MODE_DIVE)
137 { 280 {
138 bDiveMode = 3; 281 bDiveMode = 3;
154 } 297 }
155 if(lifesecondsCount >= ReplayDataResolution) 298 if(lifesecondsCount >= ReplayDataResolution)
156 { 299 {
157 lifesecondsCount = 0; 300 lifesecondsCount = 0;
158 301
159 if(lifeDataIndex >= DEPTH_DATA_LENGTH) /* compress data */ 302 if(liveDataIndex >= DEPTH_DATA_LENGTH) /* compress data */
160 { 303 {
161 ReplayDataResolution *= 2; 304 ReplayDataResolution *= 2;
162 compressBuffer_uint16(liveDepthData,DEPTH_DATA_LENGTH); 305 compressBuffer_uint16(liveDepthData,DEPTH_DATA_LENGTH);
163 compressBuffer_uint16(ReplayDepthData,DEPTH_DATA_LENGTH); /* also compress Replay data to siplify mapping between live and replay data */ 306 compressBuffer_uint16(liveDepthDataMod, DEPTH_DATA_LENGTH);
164 lifeDataIndex = DEPTH_DATA_LENGTH / 2; 307 compressBuffer_uint16(ReplayDepthData,DEPTH_DATA_LENGTH); /* also compress Replay data to simplify mapping between live and replay data */
165 } 308 liveDataIndex = DEPTH_DATA_LENGTH / 2;
166 liveDepthData[lifeDataIndex] = (int)(stateUsed->lifeData.depth_meter * 100); 309 liveDataIndexMod /= 2;
310 }
311 liveDepthData[liveDataIndex] = (int)(stateUsed->lifeData.depth_meter * 100);
312 liveDepthDataMod[liveDataIndexMod] = liveDepthData[liveDataIndex];
313
167 if(stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE) 314 if(stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE)
168 { 315 {
169 pDecoinfo = &stateUsed->decolistVPM; 316 pDecoinfo = &stateUsed->decolistVPM;
170 } 317 }
171 else 318 else
173 pDecoinfo = &stateUsed->decolistBuehlmann; 320 pDecoinfo = &stateUsed->decolistBuehlmann;
174 } 321 }
175 tHome_findNextStop(pDecoinfo->output_stop_length_seconds, &stopDepth, &stopTime); 322 tHome_findNextStop(pDecoinfo->output_stop_length_seconds, &stopDepth, &stopTime);
176 if(stopDepth) 323 if(stopDepth)
177 { 324 {
178 liveDecoData[lifeDataIndex] = stopDepth * 100; 325 liveDecoData[liveDataIndex] = stopDepth * 100;
326 liveDecoDataMod[liveDataIndexMod] = stopDepth * 100;
179 } 327 }
180 else 328 else
181 { 329 {
182 liveDecoData[lifeDataIndex] = 0xFFFF; 330 liveDecoData[liveDataIndex] = 0xFFFF;
183 } 331 liveDecoDataMod[liveDataIndexMod] = 0xFFFF;
184 lifeDataIndex++; 332 }
333 liveDataIndex++;
334 liveDataIndexMod++;
185 } 335 }
186 } 336 }
187 else if(bDiveMode == 3) 337 else if(bDiveMode == 3)
188 { 338 {
189 //End of Dive 339 //End of Dive
269 return retVal; 419 return retVal;
270 } 420 }
271 421
272 uint16_t *getMiniLiveReplayPointerToData(void) 422 uint16_t *getMiniLiveReplayPointerToData(void)
273 { 423 {
274 return liveDepthData; 424 if(ReplayMarkerIndex == 0)
425 {
426 return liveDepthData;
427 }
428 else
429 {
430 return liveDepthDataMod;
431 }
275 } 432 }
276 uint16_t *getMiniLiveDecoPointerToData(void) 433 uint16_t *getMiniLiveDecoPointerToData(void)
277 { 434 {
278 return liveDecoData; 435 if(ReplayMarkerIndex == 0)
436 {
437 return liveDecoData;
438 }
439 else
440 {
441 return liveDecoDataMod;
442 }
279 } 443 }
280 uint16_t getMiniLiveReplayLength(void) 444 uint16_t getMiniLiveReplayLength(void)
281 { 445 {
282 return lifeDataIndex; 446 return liveDataIndex;
283 } 447 }
284 448
285 uint16_t getReplayOffset(void) 449 uint16_t getReplayOffset(void)
286 { 450 {
287 return ReplayDataOffset; 451 return ReplayDataOffset;