@@ -69,9 +69,9 @@ static Recording g_dlogFile;
69
69
static uint32_t g_refreshCounter;
70
70
71
71
static uint8_t *g_rowDataStart = FILE_VIEW_BUFFER;
72
- static const uint32_t ROW_VALUES_BUFFER_SIZE = 65536 ;
72
+ static const uint32_t ROW_DATA_BUFFER_SIZE = 65536 ;
73
73
74
- static uint8_t *g_bookmarksDataStart = g_rowDataStart + ROW_VALUES_BUFFER_SIZE ;
74
+ static uint8_t *g_bookmarksDataStart = g_rowDataStart + ROW_DATA_BUFFER_SIZE ;
75
75
struct Bookmark {
76
76
uint32_t position;
77
77
const char *text;
@@ -98,6 +98,11 @@ static double g_loadScale;
98
98
static uint32_t g_loadedRowIndex;
99
99
static void loadBlockElements ();
100
100
101
+ static bool g_fileIsOpen;
102
+ File g_file;
103
+ uint32_t g_cacheRowIndexStart;
104
+ uint32_t g_cacheRowIndexEnd;
105
+
101
106
static bool g_isLoading;
102
107
static bool g_refreshed;
103
108
static bool g_wasExecuting;
@@ -125,41 +130,45 @@ static void loadVisibleBookmarks(uint32_t positionStart, uint32_t positionEnd);
125
130
126
131
void tick () {
127
132
if (g_state == STATE_READY) {
128
- uint32_t rowIndexStart = dlog_view::getPosition (getRecording ());
129
- uint32_t rowIndexEnd = rowIndexStart + VIEW_WIDTH;
130
- if (rowIndexStart > 0 ) {
131
- rowIndexStart = rowIndexStart - 1 ;
132
- }
133
- auto loadScale = g_dlogFile.xAxisDiv / g_dlogFile.xAxisDivMin ;
134
-
135
- uint32_t numRows = rowIndexEnd - rowIndexStart;
136
-
137
- if (rowIndexStart != g_rowIndexStart || rowIndexEnd != g_rowIndexEnd || loadScale != g_loadScale) {
138
- uint32_t n = numRows * g_dlogFile.parameters .numYAxes ;
139
- for (unsigned i = 0 ; i < n; i++) {
140
- g_blockElements[i].min = NAN;
141
- g_blockElements[i].max = NAN;
142
- }
143
- g_rowIndexStart = rowIndexStart;
144
- g_rowIndexEnd = rowIndexEnd;
145
- g_loadScale = loadScale;
146
- g_loadedRowIndex = 0 ;
147
-
148
- auto positionStart = (uint32_t )floorf (rowIndexStart * loadScale);
149
- auto positionEnd = (uint32_t )ceilf (rowIndexEnd * loadScale);
150
- loadVisibleBookmarks (positionStart, positionEnd);
151
- }
152
-
153
- if (g_loadedRowIndex < numRows) {
154
- loadBlockElements ();
155
- }
133
+ loadSamples ();
156
134
157
135
if (g_bookmarksScrollPosition != g_loadedBookmarksScrollPosition) {
158
136
loadBookmarks ();
159
137
}
160
138
}
161
139
}
162
140
141
+ void loadSamples () {
142
+ uint32_t rowIndexStart = dlog_view::getPosition (getRecording ());
143
+ uint32_t rowIndexEnd = rowIndexStart + VIEW_WIDTH;
144
+ if (rowIndexStart > 0 ) {
145
+ rowIndexStart = rowIndexStart - 1 ;
146
+ }
147
+ auto loadScale = g_dlogFile.xAxisDiv / g_dlogFile.xAxisDivMin ;
148
+
149
+ uint32_t numRows = rowIndexEnd - rowIndexStart;
150
+
151
+ if (rowIndexStart != g_rowIndexStart || rowIndexEnd != g_rowIndexEnd || loadScale != g_loadScale) {
152
+ uint32_t n = numRows * g_dlogFile.parameters .numYAxes ;
153
+ for (unsigned i = 0 ; i < n; i++) {
154
+ g_blockElements[i].min = NAN;
155
+ g_blockElements[i].max = NAN;
156
+ }
157
+ g_rowIndexStart = rowIndexStart;
158
+ g_rowIndexEnd = rowIndexEnd;
159
+ g_loadScale = loadScale;
160
+ g_loadedRowIndex = 0 ;
161
+
162
+ auto positionStart = (uint32_t )floorf (rowIndexStart * loadScale);
163
+ auto positionEnd = (uint32_t )ceilf (rowIndexEnd * loadScale);
164
+ loadVisibleBookmarks (positionStart, positionEnd);
165
+ }
166
+
167
+ if (g_loadedRowIndex < numRows) {
168
+ loadBlockElements ();
169
+ }
170
+ }
171
+
163
172
State getState () {
164
173
if (g_showLatest) {
165
174
if (g_wasExecuting) {
@@ -202,80 +211,105 @@ void stateManagment() {
202
211
}
203
212
}
204
213
214
+ #define IS_VALID_SAMPLE (recording, rowData ) !recording.parameters.dataContainsSampleValidityBit || *rowData & 0x80
215
+
205
216
bool isValidSample (Recording &recording, uint8_t *rowData) {
206
- return !recording.parameters .dataContainsSampleValidityBit || rowData[0 ] & 0x80 ;
207
- }
217
+ return IS_VALID_SAMPLE (recording, rowData);
218
+ }
219
+
220
+ #define GET_SAMPLE (recording, rowData, columnIndex ) \
221
+ float value; \
222
+ auto &yAxis = recording.parameters.yAxes[columnIndex]; \
223
+ auto dataType = yAxis.dataType; \
224
+ uint32_t columnDataIndex = recording.columnDataIndexes[columnIndex]; \
225
+ auto columnData = rowData + columnDataIndex; \
226
+ if (dataType == dlog_file::DATA_TYPE_BIT) { \
227
+ value = *columnData & recording.columnBitMask [columnIndex] ? 1 .0f : 0 .0f ; \
228
+ } else if (dataType == dlog_file::DATA_TYPE_INT16_BE) { \
229
+ auto iValue = int16_t ((columnData[0 ] << 8 ) | columnData[1 ]); \
230
+ value = float (yAxis.transformOffset + yAxis.transformScale * iValue); \
231
+ } else if (dataType == dlog_file::DATA_TYPE_INT24_BE) { \
232
+ auto iValue = ((int32_t )((columnData[0 ] << 24 ) | (columnData[1 ] << 16 ) | (columnData[2 ] << 8 ))) >> 8 ; \
233
+ value = float (yAxis.transformOffset + yAxis.transformScale * iValue); \
234
+ } else if (yAxis.dataType == dlog_file::DATA_TYPE_FLOAT) { \
235
+ uint8_t *p = (uint8_t *)&value; \
236
+ *p++ = *columnData++; \
237
+ *p++ = *columnData++; \
238
+ *p++ = *columnData++; \
239
+ *p = *columnData; \
240
+ } else { \
241
+ assert (false ); \
242
+ value = NAN; \
243
+ } \
208
244
209
245
float getSample (Recording &recording, uint8_t *rowData, unsigned columnIndex) {
210
- float value;
211
- auto &yAxis = recording.parameters .yAxes [columnIndex];
212
- auto dataType = yAxis.dataType ;
213
- uint32_t columnDataIndex = recording.columnDataIndexes [columnIndex];
214
- auto columnData = rowData + columnDataIndex;
215
- if (dataType == dlog_file::DATA_TYPE_BIT) {
216
- value = *columnData & recording.columnBitMask [columnIndex] ? 1 .0f : 0 .0f ;
217
- } else if (dataType == dlog_file::DATA_TYPE_INT16_BE) {
218
- auto iValue = int16_t ((columnData[0 ] << 8 ) | columnData[1 ]);
219
- value = float (yAxis.transformOffset + yAxis.transformScale * iValue);
220
- } else if (dataType == dlog_file::DATA_TYPE_INT24_BE) {
221
- auto iValue = ((int32_t )((columnData[0 ] << 24 ) | (columnData[1 ] << 16 ) | (columnData[2 ] << 8 ))) >> 8 ;
222
- value = float (yAxis.transformOffset + yAxis.transformScale * iValue);
223
- } else if (yAxis.dataType == dlog_file::DATA_TYPE_FLOAT) {
224
- uint8_t *p = (uint8_t *)&value;
225
- *p++ = *columnData++;
226
- *p++ = *columnData++;
227
- *p++ = *columnData++;
228
- *p = *columnData;
229
- } else {
230
- assert (false );
231
- value = NAN;
232
- }
233
- return value;
246
+ GET_SAMPLE (recording, rowData, columnIndex);
247
+ return value;
234
248
}
235
249
236
- static void loadBlockElements () {
237
- File file;
238
- if (!file.open (g_filePath, FILE_OPEN_EXISTING | FILE_READ)) {
239
- return ;
250
+ static uint8_t *readMoreSamples (uint32_t rowIndex) {
251
+ if (!g_fileIsOpen) {
252
+ if (!g_file.open (g_filePath, FILE_OPEN_EXISTING | FILE_READ)) {
253
+ return nullptr ;
254
+ }
255
+ g_fileIsOpen = true ;
240
256
}
241
257
258
+ auto filePosition = g_dlogFile.dataOffset + rowIndex * g_dlogFile.numBytesPerRow ;
259
+
260
+ if (!g_file.seek (filePosition)) {
261
+ return nullptr ;
262
+ }
263
+
242
264
auto numSamplesPerValue = (unsigned )round (g_loadScale);
265
+ auto remaining = g_file.size () - filePosition;
266
+ auto maxRequiredPerView = (g_rowIndexEnd - g_rowIndexStart) * numSamplesPerValue * g_dlogFile.numBytesPerRow ;
267
+ uint32_t bytesToRead = MIN (MIN (ROW_DATA_BUFFER_SIZE, remaining), maxRequiredPerView);
268
+ bytesToRead = (bytesToRead / g_dlogFile.numBytesPerRow ) * g_dlogFile.numBytesPerRow ;
269
+
270
+ uint32_t bytesRead = g_file.read (g_rowDataStart, bytesToRead);
271
+ if (bytesRead != bytesToRead) {
272
+ return nullptr ;
273
+ }
274
+
275
+ g_cacheRowIndexStart = rowIndex;
276
+ g_cacheRowIndexEnd = rowIndex + bytesRead / g_dlogFile.numBytesPerRow ;
277
+
278
+ return g_rowDataStart;
279
+ }
280
+
281
+ static void loadBlockElements () {
282
+ auto numSamplesPerBlock = (unsigned )round (g_loadScale);
243
283
244
284
uint32_t startTime = millis ();
245
285
246
- auto filePosition = g_dlogFile.dataOffset + (uint32_t )round (g_rowIndexStart * g_loadScale) * g_dlogFile.numBytesPerRow ;
247
- uint8_t *rowDataStart = g_rowDataStart;
248
- uint8_t *rowDataEnd = g_rowDataStart;
286
+ if (g_loadedRowIndex == 0 ) {
287
+ g_cacheRowIndexStart = 0 ;
288
+ g_cacheRowIndexEnd = 0 ;
289
+ }
249
290
250
291
uint32_t n = g_rowIndexEnd - g_rowIndexStart;
251
292
while (g_loadedRowIndex < n) {
252
293
BlockElement *blockElementStart = g_blockElements + g_loadedRowIndex * g_dlogFile.parameters .numYAxes ;
253
294
254
- for (unsigned sampleIndex = 0 ; sampleIndex < numSamplesPerValue; sampleIndex++) {
255
- if (rowDataStart >= rowDataEnd) {
256
- if (!file.seek (filePosition)) {
257
- goto Exit;
258
- }
295
+ auto rowIndex = (uint32_t )round ((g_rowIndexStart + g_loadedRowIndex) * g_loadScale);
259
296
260
- uint32_t bytesToRead = ((numSamplesPerValue - sampleIndex) + (n - (g_loadedRowIndex + 1 )) * numSamplesPerValue) * g_dlogFile.numBytesPerRow ;
261
- if (bytesToRead > ROW_VALUES_BUFFER_SIZE) {
262
- bytesToRead = ROW_VALUES_BUFFER_SIZE;
263
- }
297
+ uint8_t *rowData = g_rowDataStart + (rowIndex - g_cacheRowIndexStart) * g_dlogFile.numBytesPerRow ;
264
298
265
- uint32_t bytesRead = file.read (g_rowDataStart, bytesToRead);
266
- if (bytesRead != bytesToRead) {
299
+ for (unsigned blockSampleIndex = 0 ; blockSampleIndex < numSamplesPerBlock; blockSampleIndex++) {
300
+ if (rowIndex < g_cacheRowIndexStart || rowIndex >= g_cacheRowIndexEnd) {
301
+ rowData = readMoreSamples (rowIndex);
302
+ if (!rowData) {
267
303
goto Exit;
268
304
}
269
- rowDataStart = g_rowDataStart;
270
- rowDataEnd = rowDataStart + bytesToRead;
271
305
}
272
306
273
- if (isValidSample (g_dlogFile, rowDataStart )) {
307
+ if (IS_VALID_SAMPLE (g_dlogFile, rowData )) {
274
308
BlockElement *blockElement = blockElementStart;
275
309
276
310
for (uint32_t columnIndex = 0 ; columnIndex < g_dlogFile.parameters .numYAxes ; columnIndex++, blockElement++) {
277
- float value = getSample (g_dlogFile, rowDataStart , columnIndex);
278
- if (sampleIndex == 0 ) {
311
+ GET_SAMPLE (g_dlogFile, rowData , columnIndex);
312
+ if (blockSampleIndex == 0 ) {
279
313
blockElement->min = blockElement->max = value;
280
314
} else if (value < blockElement->min ) {
281
315
blockElement->min = value;
@@ -285,25 +319,23 @@ static void loadBlockElements() {
285
319
}
286
320
}
287
321
288
- rowDataStart += g_dlogFile. numBytesPerRow ;
289
- filePosition += g_dlogFile.numBytesPerRow ;
322
+ rowIndex++ ;
323
+ rowData += g_dlogFile.numBytesPerRow ;
290
324
}
291
325
292
326
g_loadedRowIndex++;
293
327
g_refreshed = true ;
294
328
295
329
if (millis () - startTime > 50 ) {
296
- break ;
330
+ break ;
297
331
}
298
-
299
- auto nextFilePosition = g_dlogFile.dataOffset + (uint32_t )round ((g_rowIndexStart + g_loadedRowIndex) * g_loadScale) * g_dlogFile.numBytesPerRow ;
300
- auto diff = nextFilePosition - filePosition;
301
- rowDataStart += diff;
302
- filePosition = nextFilePosition;
303
332
}
304
333
305
334
Exit:
306
- file.close ();
335
+ if (g_fileIsOpen) {
336
+ g_file.close ();
337
+ g_fileIsOpen = false ;
338
+ }
307
339
}
308
340
309
341
static float getValue (uint32_t rowIndex, uint8_t columnIndex, float *max) {
@@ -341,6 +373,7 @@ static void adjustXAxisOffset(Recording &recording) {
341
373
if (recording.xAxisOffset < 0 ) {
342
374
recording.xAxisOffset = 0 ;
343
375
}
376
+ sendMessageToLowPriorityThread (THREAD_MESSAGE_DLOG_LOAD_SAMPLES);
344
377
}
345
378
346
379
static Unit getXAxisUnit (Recording& recording) {
0 commit comments