Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /* | |||
2 | * @file logicdata.cpp | |||
3 | * | |||
4 | * Based on LogicdataStreamFile.java by andreika | |||
5 | * | |||
6 | * Created on: Jul 19, 2020 | |||
7 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
8 | */ | |||
9 | ||||
10 | #include "logicdata.h" | |||
11 | #include <stdio.h> | |||
12 | #include <stdlib.h> | |||
13 | #include <cstdint> | |||
14 | #include <string.h> | |||
15 | ||||
16 | #define frequency 1000000 | |||
17 | #define frequencyDiv 10 | |||
18 | #define magic 0x7f | |||
19 | ||||
20 | #define BLOCK 0x15 | |||
21 | #define CHANNEL_BLOCK 0x16 | |||
22 | #define SUB 0x54 | |||
23 | ||||
24 | #define title "Data save2" | |||
25 | ||||
26 | #define FLAG_NOTEMPTY 2 | |||
27 | #define FLAG_NOTEMPTY_LONG 3 | |||
28 | #define FLAG_EMPTY 5 | |||
29 | ||||
30 | #define LOGIC4 0x40FD | |||
31 | #define LOGIC8 0x673B | |||
32 | ||||
33 | #define SIGN_FLAG 0x80000000L | |||
34 | ||||
35 | // todo: numChannels 7 or numChannels 8 does not work? :( | |||
36 | #define numChannels 6 | |||
37 | #define reservedDurationInSamples 10 | |||
38 | ||||
39 | static const char *channelNames[] = { "Primary", "Secondary", "TDC", | |||
40 | "Sync", "Coil", "Injector", "Channel 6", "Channel 7" }; | |||
41 | ||||
42 | static int CHANNEL_FLAGS[] = { 0x13458b, 0x0000ff, 0x00a0f9, 0x00ffff, 0x00ff00, | |||
43 | 0xff0000, 0xf020a0, }; | |||
44 | ||||
45 | static FILE *ptr; | |||
46 | ||||
47 | static uint32_t realDurationInSamples; | |||
48 | static uint32_t scaledDurationInSamples; | |||
49 | ||||
50 | 418920 | static void writeByte(uint8_t value) { | ||
51 | 418920 | fwrite(&value, 1, sizeof(value), ptr); | ||
52 | 418920 | } | ||
53 | ||||
54 | 27963 | static void writeAs(int64_t value, int numBytes) { | ||
55 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27963 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 27963 times.
|
27963 | if (value == 0) { |
56 | ✗ | writeByte(0); | ||
57 | } else { | |||
58 | 27963 | writeByte(numBytes); | ||
59 |
2/2✓ Branch 0 taken 40183 times.
✓ Branch 1 taken 27963 times.
|
2/2✓ Decision 'true' taken 40183 times.
✓ Decision 'false' taken 27963 times.
|
68146 | for (int i = 0; i < numBytes; i++) { |
60 | 40183 | writeByte((uint8_t) ((value >> (i * 8)) & 0xff)); | ||
61 | } | |||
62 | } | |||
63 | 27963 | } | ||
64 | ||||
65 | // This is the main secret of this format! :) | |||
66 | 68442 | static void write(int64_t value) { | ||
67 |
3/4✓ Branch 0 taken 68294 times.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 68294 times.
|
2/2✓ Decision 'true' taken 148 times.
✓ Decision 'false' taken 68294 times.
|
68442 | if (value < 0 || value > 0xFFFFFFFFL) { |
68 | 148 | writeAs(value, 8); | ||
69 |
2/2✓ Branch 0 taken 40479 times.
✓ Branch 1 taken 27815 times.
|
2/2✓ Decision 'true' taken 40479 times.
✓ Decision 'false' taken 27815 times.
|
68294 | } else if (value == 0) { |
70 | 40479 | writeByte(0); | ||
71 |
2/2✓ Branch 0 taken 21611 times.
✓ Branch 1 taken 6204 times.
|
2/2✓ Decision 'true' taken 21611 times.
✓ Decision 'false' taken 6204 times.
|
27815 | } else if (value <= 0xff) { |
72 | 21611 | writeAs(value, 1); | ||
73 |
2/2✓ Branch 0 taken 3247 times.
✓ Branch 1 taken 2957 times.
|
2/2✓ Decision 'true' taken 3247 times.
✓ Decision 'false' taken 2957 times.
|
6204 | } else if (value <= 0xffff) { |
74 | 3247 | writeAs(value, 2); | ||
75 |
2/2✓ Branch 0 taken 934 times.
✓ Branch 1 taken 2023 times.
|
2/2✓ Decision 'true' taken 934 times.
✓ Decision 'false' taken 2023 times.
|
2957 | } else if (value <= 0xffffff) { |
76 | 934 | writeAs(value, 3); | ||
77 | } else { | |||
78 | 2023 | writeAs(value, 4); | ||
79 | } | |||
80 | 68442 | } | ||
81 | ||||
82 | 1110 | static void writeString(const char *value) { | ||
83 | 1110 | int len = strlen(value); | ||
84 | 1110 | write(len); | ||
85 |
2/2✓ Branch 0 taken 7437 times.
✓ Branch 1 taken 1110 times.
|
2/2✓ Decision 'true' taken 7437 times.
✓ Decision 'false' taken 1110 times.
|
8547 | for (int i = 0; i < len; i++) { |
86 | 7437 | writeByte(value[i]); | ||
87 | } | |||
88 | 1110 | } | ||
89 | ||||
90 | // todo: some C++ magic would allow us to drop 'count' parameter | |||
91 | // todo: Look at efi::size in util | |||
92 | 444 | static void write(int values[], int count) { | ||
93 |
2/2✓ Branch 0 taken 1998 times.
✓ Branch 1 taken 444 times.
|
2/2✓ Decision 'true' taken 1998 times.
✓ Decision 'false' taken 444 times.
|
2442 | for (int i = 0; i < count; i++) { |
94 | 1998 | write(values[i]); | ||
95 | } | |||
96 | 444 | } | ||
97 | ||||
98 | 5661 | static void write(int value, int num) { | ||
99 |
2/2✓ Branch 0 taken 31278 times.
✓ Branch 1 taken 5661 times.
|
2/2✓ Decision 'true' taken 31278 times.
✓ Decision 'false' taken 5661 times.
|
36939 | for (int i = 0; i < num; i++) |
100 | 31278 | write(value); | ||
101 | 5661 | } | ||
102 | ||||
103 | 3108 | static void writeId(int i1, int i2) { | ||
104 | 3108 | write((numChannels == 4) ? LOGIC4 : LOGIC8); | ||
105 | 3108 | write(i1); | ||
106 | 3108 | write(i2); | ||
107 | 3108 | } | ||
108 | ||||
109 | 111 | static void writeHeader() { | ||
110 | 111 | writeByte(magic); | ||
111 | 111 | write(strlen(title)); | ||
112 | 111 | writeString(title); | ||
113 | ||||
114 | 111 | write(BLOCK); | ||
115 | 111 | write(SUB); | ||
116 | 111 | write(frequency); | ||
117 | 111 | write(0); | ||
118 | 111 | write(reservedDurationInSamples); | ||
119 | 111 | write(frequency / frequencyDiv); | ||
120 | 111 | write(0, 2); | ||
121 | 111 | write(numChannels); | ||
122 | ||||
123 | 111 | write(BLOCK); | ||
124 | 111 | write(0); | ||
125 | ||||
126 | 111 | write(BLOCK); | ||
127 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 111 times.
|
777 | for (int i = 0; i < numChannels; i++) { |
128 | 666 | writeId(i, 1); | ||
129 | } | |||
130 | 111 | write(0); | ||
131 | ||||
132 | 111 | write(BLOCK); | ||
133 | ||||
134 | 111 | writeId(0, 0); | ||
135 | 111 | write(0); | ||
136 | 111 | write(0); | ||
137 | ||||
138 | 111 | } | ||
139 | ||||
140 | 2109 | static void writeDouble(double value) { | ||
141 | static_assert(sizeof(double) == 8); | |||
142 | ||||
143 |
2/2✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 777 times.
|
2/2✓ Decision 'true' taken 1332 times.
✓ Decision 'false' taken 777 times.
|
2109 | if (value == 0.0) { |
144 | 1332 | writeByte(0); | ||
145 | } else { | |||
146 | 777 | writeByte(8); | ||
147 | 777 | char *ptr = (char*) (void*) &value; | ||
148 | ||||
149 |
2/2✓ Branch 0 taken 6216 times.
✓ Branch 1 taken 777 times.
|
2/2✓ Decision 'true' taken 6216 times.
✓ Decision 'false' taken 777 times.
|
6993 | for (int i = 0; i < 8; i++) { |
150 | 6216 | writeByte(ptr[i]); | ||
151 | } | |||
152 | } | |||
153 | 2109 | } | ||
154 | ||||
155 | 666 | static void writeChannelHeader(int ch) { | ||
156 | 666 | write(0xff); | ||
157 | 666 | write(ch); | ||
158 | 666 | writeString(channelNames[ch]); | ||
159 | 666 | write(0, 2); | ||
160 | 666 | writeDouble(1.0); | ||
161 | 666 | write(0); | ||
162 | 666 | writeDouble(0.0); | ||
163 | 666 | write(1); // or 2 | ||
164 | 666 | writeDouble(0.0); // or 1.0 | ||
165 | ||||
166 | // this part sounds like the 'next' pointer? | |||
167 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 555 times.
|
2/2✓ Decision 'true' taken 111 times.
✓ Decision 'false' taken 555 times.
|
666 | if (ch == numChannels - 1) { |
168 | 111 | write(0); | ||
169 | } else { | |||
170 | 555 | writeId(1 + ch, 1); | ||
171 |
2/2✓ Branch 0 taken 1665 times.
✓ Branch 1 taken 555 times.
|
2/2✓ Decision 'true' taken 1665 times.
✓ Decision 'false' taken 555 times.
|
2220 | for (int i = 0; i < 3; i++) { |
172 | 1665 | write((CHANNEL_FLAGS[ch] >> (i * 8)) & 0xff); | ||
173 | } | |||
174 | } | |||
175 | 666 | } | ||
176 | ||||
177 | 666 | static void writeEdges(int64_t *chDeltas, bool useLongDeltas, int numEdges) { | ||
178 |
2/2✓ Branch 0 taken 72040 times.
✓ Branch 1 taken 666 times.
|
2/2✓ Decision 'true' taken 72040 times.
✓ Decision 'false' taken 666 times.
|
72706 | for (int i = 0; i < numEdges; i++) { |
179 | 72040 | uint64_t d = chDeltas[i]; | ||
180 | ||||
181 | // set 16-bit 'sign' flag | |||
182 |
4/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 72030 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 72035 times.
|
72040 | if (!useLongDeltas && (d & SIGN_FLAG) == SIGN_FLAG) |
183 | 5 | d = (d & 0x7fff) | (SIGN_FLAG >> 16); | ||
184 | 72040 | writeByte((uint8_t) (d & 0xff)); | ||
185 | 72040 | writeByte((uint8_t) ((d >> 8) & 0xff)); | ||
186 |
2/2✓ Branch 0 taken 72030 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 72030 times.
✓ Decision 'false' taken 10 times.
|
72040 | if (useLongDeltas) { |
187 | 72030 | writeByte((uint8_t) ((d >> 16) & 0xff)); | ||
188 | 72030 | writeByte((uint8_t) ((d >> 24) & 0xff)); | ||
189 | } | |||
190 | } | |||
191 | 666 | writeByte(0x00); | ||
192 | 666 | } | ||
193 | ||||
194 | 1053 | static void writeRaw(int value, int num) { | ||
195 |
2/2✓ Branch 0 taken 5616 times.
✓ Branch 1 taken 1053 times.
|
2/2✓ Decision 'true' taken 5616 times.
✓ Decision 'false' taken 1053 times.
|
6669 | for (int i = 0; i < num; i++) { |
196 | 5616 | writeByte(value); | ||
197 | } | |||
198 | 1053 | } | ||
199 | ||||
200 | 666 | static void writeChannelData(int ch, int64_t *chDeltas, int chLastState, | ||
201 | int lastRecord, bool useLongDeltas, int numEdges) { | |||
202 |
2/2✓ Branch 0 taken 315 times.
✓ Branch 1 taken 351 times.
|
2/2✓ Decision 'true' taken 315 times.
✓ Decision 'false' taken 351 times.
|
666 | if (numEdges == 0) |
203 | 315 | lastRecord = 0; | ||
204 | 666 | write(CHANNEL_BLOCK); | ||
205 | // channel#0 is somehow special... | |||
206 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 555 times.
|
2/2✓ Decision 'true' taken 111 times.
✓ Decision 'false' taken 555 times.
|
666 | if (ch == 0) { |
207 | 111 | write(SUB); | ||
208 | 111 | write(BLOCK); | ||
209 | } | |||
210 | ||||
211 | 666 | write(ch + 1); | ||
212 | 666 | write(0); | ||
213 | 666 | write(realDurationInSamples); | ||
214 | 666 | write(1); | ||
215 | 666 | write(lastRecord); | ||
216 | ||||
217 | 666 | uint32_t numSamplesLeft = realDurationInSamples - lastRecord; | ||
218 | 666 | write(numSamplesLeft); | ||
219 | ||||
220 | 666 | write(chLastState); | ||
221 | ||||
222 | 666 | int chFlag = | ||
223 |
2/2✓ Branch 0 taken 351 times.
✓ Branch 1 taken 315 times.
|
1017 | (numEdges == 0) ? | |
224 | FLAG_EMPTY : | |||
225 |
2/2✓ Branch 0 taken 349 times.
✓ Branch 1 taken 2 times.
|
351 | (useLongDeltas ? FLAG_NOTEMPTY_LONG : FLAG_NOTEMPTY); | |
226 | 666 | write(chFlag); | ||
227 | ||||
228 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 555 times.
|
2/2✓ Decision 'true' taken 111 times.
✓ Decision 'false' taken 555 times.
|
666 | if (ch == 0) { |
229 | 111 | write(0); | ||
230 | 111 | write(BLOCK); | ||
231 | 111 | write(0, 11); | ||
232 |
2/2✓ Branch 0 taken 109 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 109 times.
✓ Decision 'false' taken 2 times.
|
111 | if (useLongDeltas) { |
233 | 109 | write(BLOCK); | ||
234 | 109 | write(0, 6); | ||
235 | } | |||
236 | 111 | write(BLOCK); | ||
237 | } else { | |||
238 | 555 | write(0, 10); | ||
239 |
2/2✓ Branch 0 taken 548 times.
✓ Branch 1 taken 7 times.
|
2/2✓ Decision 'true' taken 548 times.
✓ Decision 'false' taken 7 times.
|
555 | if (useLongDeltas) { |
240 | 548 | write(0, 5); | ||
241 | } | |||
242 | } | |||
243 | ||||
244 | 666 | write(numEdges); | ||
245 | 666 | write(0); | ||
246 | 666 | write(numEdges); | ||
247 | 666 | write(0); | ||
248 | 666 | write(numEdges); | ||
249 | ||||
250 | 666 | writeEdges(chDeltas, useLongDeltas, numEdges); | ||
251 | ||||
252 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 555 times.
|
2/2✓ Decision 'true' taken 111 times.
✓ Decision 'false' taken 555 times.
|
666 | if (ch == 0) { |
253 | 111 | write(BLOCK); | ||
254 | 111 | write(0, 6); | ||
255 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 109 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 109 times.
|
111 | if (!useLongDeltas) { |
256 | 2 | write(BLOCK); | ||
257 | 2 | write(0, 6); | ||
258 | } | |||
259 | 111 | write(BLOCK); | ||
260 | } else { | |||
261 | 555 | write(0, 4); | ||
262 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 548 times.
|
2/2✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 548 times.
|
555 | if (!useLongDeltas) { |
263 | 7 | write(0, 5); | ||
264 | } | |||
265 | } | |||
266 | ||||
267 |
2/2✓ Branch 0 taken 315 times.
✓ Branch 1 taken 351 times.
|
2/2✓ Decision 'true' taken 315 times.
✓ Decision 'false' taken 351 times.
|
666 | if (numEdges == 0) { |
268 | 315 | write(0, 5); | ||
269 | 315 | return; | ||
270 | } | |||
271 | ||||
272 | 351 | write(1); | ||
273 | 351 | write(0); | ||
274 | 351 | write(1); | ||
275 | 351 | write(0); | ||
276 | 351 | write(1); | ||
277 | 351 | write(0, 16); | ||
278 | ||||
279 | 351 | writeRaw(0xFF, 8); | ||
280 | 351 | writeRaw(chFlag, 1); | ||
281 | 351 | writeRaw(0x00, 7); | ||
282 | } | |||
283 | ||||
284 | 111 | static void writeChannelDataHeader() { | ||
285 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
286 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(scaledDurationInSamples); | |
287 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 5); | |
288 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(numChannels); | |
289 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 3); | |
290 |
1/1✓ Branch 1 taken 111 times.
|
111 | writeId(0, 1); | |
291 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
292 | ||||
293 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
294 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 3); | |
295 | ||||
296 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 111 times.
|
777 | for (int i = 0; i < numChannels; i++) { |
297 |
1/1✓ Branch 1 taken 666 times.
|
666 | writeChannelHeader(i); | |
298 | } | |||
299 | ||||
300 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
301 | 111 | int SUB_ARRAY[] = { SUB, SUB, 0, SUB, 0, SUB }; | ||
302 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB_ARRAY, 6); | |
303 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 6); | |
304 | ||||
305 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
306 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 2); | |
307 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(realDurationInSamples); | |
308 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
309 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB); | |
310 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(reservedDurationInSamples); | |
311 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(frequency / frequencyDiv); | |
312 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 2); | |
313 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB); | |
314 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 2); | |
315 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(1); | |
316 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 3); | |
317 |
1/1✓ Branch 1 taken 111 times.
|
111 | writeId(0, 0); | |
318 | ||||
319 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
320 | 111 | int SAM_ARRAY[] = { (int)realDurationInSamples, (int)realDurationInSamples, | ||
321 | 111 | (int)realDurationInSamples }; | ||
322 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SAM_ARRAY, 3); | |
323 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
324 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB); | |
325 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
326 | ||||
327 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
328 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
329 | ||||
330 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
331 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB, 4); | |
332 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
333 | ||||
334 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
335 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(frequency); | |
336 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 3); | |
337 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(1); | |
338 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 3); | |
339 |
1/1✓ Branch 1 taken 111 times.
|
111 | writeId(0, 0); | |
340 | 111 | int ARR_6[] = { 0, 1, 1, 0, 1, 0x13 }; | ||
341 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(ARR_6, 6); | |
342 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(SUB); | |
343 | ||||
344 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(BLOCK); | |
345 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0); | |
346 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(realDurationInSamples); | |
347 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(0, 2); | |
348 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(numChannels); | |
349 | 111 | int ARR_3[] = { 1, 0, 1 }; | ||
350 |
1/1✓ Branch 1 taken 111 times.
|
111 | write(ARR_3, 3); | |
351 | 111 | } | ||
352 | ||||
353 | 111 | static void writeTimingMarker() { | ||
354 | 111 | write(BLOCK); | ||
355 | 111 | write(numChannels + 2); | ||
356 | 111 | write(0, 4); | ||
357 | 111 | writeString("Timing Marker Pair"); | ||
358 | 111 | writeString("A1"); | ||
359 | 111 | writeString("A2"); | ||
360 | 111 | write(0, 2); | ||
361 | 111 | write(SUB); | ||
362 | 111 | write(0, 9); | ||
363 | 111 | } | ||
364 | ||||
365 | 111 | static void writeChannelDataFooter() { | ||
366 | 111 | write(0, 3); | ||
367 | 111 | write(1); | ||
368 | 111 | write(1); | ||
369 | 111 | write(0); | ||
370 | 111 | write(numChannels); | ||
371 | 111 | } | ||
372 | ||||
373 | 935724 | int getChannelState(int ch, const CompositeEvent* event) { | ||
374 |
6/7✓ Branch 0 taken 155954 times.
✓ Branch 1 taken 155954 times.
✓ Branch 2 taken 155954 times.
✓ Branch 3 taken 155954 times.
✓ Branch 4 taken 155954 times.
✓ Branch 5 taken 155954 times.
✗ Branch 6 not taken.
|
935724 | switch (ch) { | |
375 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 0: | |
376 | 155954 | return event->primaryTrigger; | ||
377 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 1: | |
378 | 155954 | return event->secondaryTrigger; | ||
379 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 2: | |
380 | 155954 | return event->isTDC; | ||
381 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 3: | |
382 | 155954 | return event->sync; | ||
383 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 4: | |
384 | 155954 | return event->coil; | ||
385 |
1/1✓ Decision 'true' taken 155954 times.
|
155954 | case 5: | |
386 | 155954 | return event->injector; | ||
387 | } | |||
388 | ✗ | return -1; | ||
389 | } | |||
390 | ||||
391 | 111 | static void writeEvents(const std::vector<CompositeEvent>& events) { | ||
392 | 111 | size_t count = events.size(); | ||
393 | // we need at least 2 records | |||
394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 111 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 111 times.
|
111 | if (count < 2) |
395 | ✗ | return; | ||
396 | 111 | uint32_t firstRecordTs = events[1].timestamp; | ||
397 | 111 | uint32_t lastRecordTs = events[count - 1].timestamp; | ||
398 | // we don't know the total duration, so we create a margin after the last record which equals to the duration of the first event | |||
399 | 111 | realDurationInSamples = lastRecordTs + firstRecordTs; | ||
400 | 111 | scaledDurationInSamples = realDurationInSamples / 4; | ||
401 | ||||
402 | 111 | writeChannelDataHeader(); | ||
403 | ||||
404 | 111 | int64_t *chDeltas = (int64_t*) malloc(sizeof(int64_t) * count); | ||
405 | ||||
406 | 111 | bool useLongDeltas = false; | ||
407 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 111 times.
|
777 | for (int ch = 0; ch < numChannels; ch++) { |
408 | 666 | int chPrevState = -1; | ||
409 | 666 | uint32_t prevTs = 0; | ||
410 | 666 | int deltaCount = 0; | ||
411 | ||||
412 |
2/2✓ Branch 0 taken 467862 times.
✓ Branch 1 taken 666 times.
|
2/2✓ Decision 'true' taken 467862 times.
✓ Decision 'false' taken 666 times.
|
468528 | for (size_t i = 0; i < count; i++) { |
413 | 467862 | const CompositeEvent* event = &events[i]; | ||
414 | ||||
415 | 467862 | int chState = getChannelState(ch, event); | ||
416 | 467862 | uint32_t ts = event->timestamp; | ||
417 | ||||
418 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 467196 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 467196 times.
|
467862 | if (chPrevState == -1) { |
419 | 666 | chPrevState = chState; | ||
420 | } | |||
421 |
2/2✓ Branch 0 taken 72040 times.
✓ Branch 1 taken 395822 times.
|
2/2✓ Decision 'true' taken 72040 times.
✓ Decision 'false' taken 395822 times.
|
467862 | if (chState != chPrevState) { |
422 | 72040 | int64_t delta = ts - prevTs; | ||
423 |
2/2✓ Branch 0 taken 65951 times.
✓ Branch 1 taken 6089 times.
|
2/2✓ Decision 'true' taken 65951 times.
✓ Decision 'false' taken 6089 times.
|
72040 | if (delta > 0x7fff) { |
424 | 65951 | useLongDeltas = true; | ||
425 | } | |||
426 | // encode state | |||
427 |
2/2✓ Branch 0 taken 35999 times.
✓ Branch 1 taken 36041 times.
|
2/2✓ Decision 'true' taken 35999 times.
✓ Decision 'false' taken 36041 times.
|
72040 | if (chState == 0) |
428 | 35999 | delta |= SIGN_FLAG; | ||
429 | ||||
430 | 72040 | chDeltas[deltaCount++] = delta; | ||
431 | ||||
432 | 72040 | prevTs = ts; | ||
433 | 72040 | chPrevState = chState; | ||
434 | } | |||
435 | } | |||
436 | 666 | writeChannelData(ch, chDeltas, chPrevState, prevTs, useLongDeltas, | ||
437 | deltaCount); | |||
438 | } | |||
439 | ||||
440 | 111 | free(chDeltas); | ||
441 | ||||
442 | 111 | writeChannelDataFooter(); | ||
443 | } | |||
444 | ||||
445 | 111 | static void writeFooter() { | ||
446 | 111 | write(BLOCK); | ||
447 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 111 times.
|
777 | for (int i = 0; i < numChannels; i++) { |
448 | 666 | writeId(i, 1); | ||
449 | } | |||
450 | 111 | write(1); | ||
451 | 111 | writeId(numChannels, 0x15); | ||
452 |
2/2✓ Branch 0 taken 666 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 666 times.
✓ Decision 'false' taken 111 times.
|
777 | for (int i = 0; i < numChannels; i++) { |
453 | 666 | writeId(i, 1); | ||
454 | } | |||
455 | 111 | write(1); | ||
456 | 111 | write(0); | ||
457 | 111 | write(frequency); | ||
458 | 111 | write(0, 16); | ||
459 | 111 | write(0x01); | ||
460 | 111 | write(0x23); // ??? | ||
461 | 111 | write(SUB); | ||
462 | ||||
463 | 111 | write(BLOCK); | ||
464 | 111 | write(numChannels + 1); | ||
465 | 111 | write(0); | ||
466 | 111 | write(0xFFFFFFFFFFFFFFFFL); | ||
467 | 111 | write(0xFFFFFFFFL); | ||
468 | 111 | write(1); | ||
469 | 111 | write(0, 3); | ||
470 | ||||
471 | 111 | write(BLOCK); | ||
472 | 111 | write(0); | ||
473 | ||||
474 | 111 | write(BLOCK); | ||
475 | 111 | write(0); | ||
476 | 111 | writeDouble(1.0); | ||
477 | 111 | write(SUB); | ||
478 | 111 | write(0, 6); | ||
479 | 111 | write(1); | ||
480 | 111 | write(0, 4); | ||
481 | ||||
482 | 111 | write(1); | ||
483 | 111 | write(0x29); // ??? | ||
484 | 111 | write(SUB); | ||
485 | ||||
486 | 111 | writeTimingMarker(); | ||
487 | 111 | } | ||
488 | ||||
489 | 111 | void writeLogicDataFile(const char * fileName, const std::vector<CompositeEvent>& events) { | ||
490 | ||||
491 | 111 | ptr = fopen(fileName, "wb"); | ||
492 | ||||
493 | 111 | writeHeader(); | ||
494 | 111 | writeEvents(events); | ||
495 | 111 | writeFooter(); | ||
496 | ||||
497 | 111 | fclose(ptr); | ||
498 | ||||
499 | 111 | } | ||
500 |