]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add SR_CONF_LOGIC_ANALYZER drvopt.
[libsigrok.git] / src / hardware / hameg-hmo / protocol.c
CommitLineData
06a3e78a
DJ
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
e131be0a 5 * Copyright (C) 2018 Guido Trentalancia <guido@trentalancia.com>
06a3e78a
DJ
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
6ec6c43b 21#include <config.h>
650847e7
UH
22#include <math.h>
23#include <stdlib.h>
5a1afc09 24#include "scpi.h"
06a3e78a
DJ
25#include "protocol.h"
26
e06875b2
GS
27SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
28 size_t group, GByteArray *pod_data);
29SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
30 struct dev_context *devc);
31SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc);
32
13f2b9d7 33static const char *hameg_scpi_dialect[] = {
e131be0a
GT
34 [SCPI_CMD_GET_DIG_DATA] = ":FORM UINT,8;:POD%d:DATA?",
35 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
36 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
37 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
38 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
39 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
e131be0a
GT
40 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
41 ":FORM REAL,32;:CHAN%d:DATA?",
42 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
43 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
44 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
45 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
46 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
c8ecfa6e 47 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:TYPE EDGE;:TRIG:A:EDGE:SLOP %s",
4fa4db2c
GT
48 [SCPI_CMD_GET_TRIGGER_PATTERN] = ":TRIG:A:PATT:SOUR?",
49 [SCPI_CMD_SET_TRIGGER_PATTERN] = ":TRIG:A:TYPE LOGIC;" \
50 ":TRIG:A:PATT:FUNC AND;" \
51 ":TRIG:A:PATT:COND TRUE;" \
52 ":TRIG:A:PATT:MODE OFF;" \
53 ":TRIG:A:PATT:SOUR \"%s\"",
e131be0a
GT
54 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
55 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
56 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
57 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
58 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
59 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
60 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
61 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
62 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
63 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
64 [SCPI_CMD_GET_DIG_POD_THRESHOLD] = ":POD%d:THR?",
65 [SCPI_CMD_SET_DIG_POD_THRESHOLD] = ":POD%d:THR %s",
66 [SCPI_CMD_GET_DIG_POD_USER_THRESHOLD] = ":POD%d:THR:UDL%d?",
67 [SCPI_CMD_SET_DIG_POD_USER_THRESHOLD] = ":POD%d:THR:UDL%d %s",
13f2b9d7
DJ
68};
69
4b25cbff 70static const uint32_t devopts[] = {
13f2b9d7 71 SR_CONF_OSCILLOSCOPE,
830e24b6
GT
72 SR_CONF_LIMIT_SAMPLES | SR_CONF_SET,
73 SR_CONF_LIMIT_FRAMES | SR_CONF_SET,
86621306 74 SR_CONF_SAMPLERATE | SR_CONF_GET,
5827f61b 75 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 76 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 77 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
86621306
UH
78 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
79 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
4fa4db2c 80 SR_CONF_TRIGGER_PATTERN | SR_CONF_GET | SR_CONF_SET,
13f2b9d7
DJ
81};
82
6b82c3e5 83static const uint32_t devopts_cg_analog[] = {
5827f61b 84 SR_CONF_NUM_VDIV | SR_CONF_GET,
5827f61b 85 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
86621306 86 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
87};
88
e131be0a
GT
89static const uint32_t devopts_cg_digital[] = {
90 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
91 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
92};
93
4b25cbff 94static const char *coupling_options[] = {
b05ab7d2
SB
95 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
96 "ACL", // AC with 1 MOhm termination
97 "DC", // DC with 50 Ohm termination
98 "DCL", // DC with 1 MOhm termination
13f2b9d7 99 "GND",
13f2b9d7
DJ
100};
101
102static const char *scope_trigger_slopes[] = {
103 "POS",
104 "NEG",
356f64f8 105 "EITH",
13f2b9d7
DJ
106};
107
e131be0a
GT
108/* Predefined logic thresholds. */
109static const char *logic_threshold[] = {
110 "TTL",
111 "ECL",
112 "CMOS",
113 "USER1",
114 "USER2", // overwritten by logic_threshold_custom, use USER1 for permanent setting
115};
116
4cf90b86 117/* RTC1002, HMO Compact2 and HMO1002/HMO1202 */
6d0f3508 118static const char *an2_dig8_trigger_sources[] = {
f8195cb2
UH
119 "CH1", "CH2",
120 "LINE", "EXT", "PATT", "BUS1", "BUS2",
121 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
122};
123
4cf90b86 124/* HMO3xx2 */
6d0f3508
GT
125static const char *an2_dig16_trigger_sources[] = {
126 "CH1", "CH2",
127 "LINE", "EXT", "PATT", "BUS1", "BUS2",
128 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
129 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
130};
131
4cf90b86 132/* HMO Compact4 */
6d0f3508 133static const char *an4_dig8_trigger_sources[] = {
f8195cb2
UH
134 "CH1", "CH2", "CH3", "CH4",
135 "LINE", "EXT", "PATT", "BUS1", "BUS2",
136 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
137};
138
4cf90b86 139/* HMO3xx4 and HMO2524 */
6d0f3508 140static const char *an4_dig16_trigger_sources[] = {
f8195cb2
UH
141 "CH1", "CH2", "CH3", "CH4",
142 "LINE", "EXT", "PATT", "BUS1", "BUS2",
143 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
144 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
74413faf
GS
145};
146
4b25cbff 147static const uint64_t timebases[][2] = {
13f2b9d7
DJ
148 /* nanoseconds */
149 { 2, 1000000000 },
150 { 5, 1000000000 },
151 { 10, 1000000000 },
152 { 20, 1000000000 },
153 { 50, 1000000000 },
154 { 100, 1000000000 },
155 { 200, 1000000000 },
156 { 500, 1000000000 },
157 /* microseconds */
158 { 1, 1000000 },
159 { 2, 1000000 },
160 { 5, 1000000 },
161 { 10, 1000000 },
162 { 20, 1000000 },
163 { 50, 1000000 },
164 { 100, 1000000 },
165 { 200, 1000000 },
166 { 500, 1000000 },
167 /* milliseconds */
168 { 1, 1000 },
169 { 2, 1000 },
170 { 5, 1000 },
171 { 10, 1000 },
172 { 20, 1000 },
173 { 50, 1000 },
174 { 100, 1000 },
175 { 200, 1000 },
176 { 500, 1000 },
177 /* seconds */
178 { 1, 1 },
179 { 2, 1 },
180 { 5, 1 },
181 { 10, 1 },
182 { 20, 1 },
183 { 50, 1 },
184};
185
4b25cbff 186static const uint64_t vdivs[][2] = {
13f2b9d7
DJ
187 /* millivolts */
188 { 1, 1000 },
189 { 2, 1000 },
190 { 5, 1000 },
191 { 10, 1000 },
192 { 20, 1000 },
193 { 50, 1000 },
194 { 100, 1000 },
195 { 200, 1000 },
196 { 500, 1000 },
197 /* volts */
198 { 1, 1 },
199 { 2, 1 },
200 { 5, 1 },
201 { 10, 1 },
202};
203
ba7dd8bb 204static const char *scope_analog_channel_names[] = {
f8195cb2 205 "CH1", "CH2", "CH3", "CH4",
13f2b9d7
DJ
206};
207
ba7dd8bb 208static const char *scope_digital_channel_names[] = {
f8195cb2
UH
209 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
210 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
13f2b9d7
DJ
211};
212
329733d9 213static const struct scope_config scope_models[] = {
13f2b9d7 214 {
4cf90b86
GT
215 /* RTC1002 and HMO722/1002/1022/1202/1522/2022 support only 8 digital channels. */
216 .name = {"RTC1002", "HMO722", "HMO1002", "HMO1022", "HMO1202", "HMO1522", "HMO2022", NULL},
13f2b9d7
DJ
217 .analog_channels = 2,
218 .digital_channels = 8,
219 .digital_pods = 1,
220
ba7dd8bb
UH
221 .analog_names = &scope_analog_channel_names,
222 .digital_names = &scope_digital_channel_names,
13f2b9d7 223
4b25cbff
UH
224 .devopts = &devopts,
225 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 226
6b82c3e5
UH
227 .devopts_cg_analog = &devopts_cg_analog,
228 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 229
e131be0a
GT
230 .devopts_cg_digital = &devopts_cg_digital,
231 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
232
4b25cbff 233 .coupling_options = &coupling_options,
692716f5
UH
234 .num_coupling_options = ARRAY_SIZE(coupling_options),
235
e131be0a
GT
236 .logic_threshold = &logic_threshold,
237 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
238
6d0f3508
GT
239 .trigger_sources = &an2_dig8_trigger_sources,
240 .num_trigger_sources = ARRAY_SIZE(an2_dig8_trigger_sources),
241
242 .trigger_slopes = &scope_trigger_slopes,
243 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
244
245 .timebases = &timebases,
246 .num_timebases = ARRAY_SIZE(timebases),
247
248 .vdivs = &vdivs,
249 .num_vdivs = ARRAY_SIZE(vdivs),
250
251 .num_xdivs = 12,
252 .num_ydivs = 8,
253
254 .scpi_dialect = &hameg_scpi_dialect,
255 },
256 {
257 /* HMO3032/3042/3052/3522 support 16 digital channels. */
258 .name = {"HMO3032", "HMO3042", "HMO3052", "HMO3522", NULL},
259 .analog_channels = 2,
260 .digital_channels = 16,
261 .digital_pods = 2,
262
263 .analog_names = &scope_analog_channel_names,
264 .digital_names = &scope_digital_channel_names,
265
266 .devopts = &devopts,
267 .num_devopts = ARRAY_SIZE(devopts),
268
269 .devopts_cg_analog = &devopts_cg_analog,
270 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
271
e131be0a
GT
272 .devopts_cg_digital = &devopts_cg_digital,
273 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
274
6d0f3508
GT
275 .coupling_options = &coupling_options,
276 .num_coupling_options = ARRAY_SIZE(coupling_options),
277
e131be0a
GT
278 .logic_threshold = &logic_threshold,
279 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
280
6d0f3508
GT
281 .trigger_sources = &an2_dig16_trigger_sources,
282 .num_trigger_sources = ARRAY_SIZE(an2_dig16_trigger_sources),
692716f5 283
13f2b9d7 284 .trigger_slopes = &scope_trigger_slopes,
692716f5 285 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 286
4b25cbff
UH
287 .timebases = &timebases,
288 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 289
4b25cbff
UH
290 .vdivs = &vdivs,
291 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
292
293 .num_xdivs = 12,
294 .num_ydivs = 8,
295
296 .scpi_dialect = &hameg_scpi_dialect,
297 },
298 {
74413faf 299 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
13f2b9d7
DJ
300 .analog_channels = 4,
301 .digital_channels = 8,
302 .digital_pods = 1,
303
ba7dd8bb
UH
304 .analog_names = &scope_analog_channel_names,
305 .digital_names = &scope_digital_channel_names,
13f2b9d7 306
4b25cbff
UH
307 .devopts = &devopts,
308 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 309
6b82c3e5
UH
310 .devopts_cg_analog = &devopts_cg_analog,
311 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 312
e131be0a
GT
313 .devopts_cg_digital = &devopts_cg_digital,
314 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
315
4b25cbff 316 .coupling_options = &coupling_options,
692716f5
UH
317 .num_coupling_options = ARRAY_SIZE(coupling_options),
318
e131be0a
GT
319 .logic_threshold = &logic_threshold,
320 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
321
6d0f3508
GT
322 .trigger_sources = &an4_dig8_trigger_sources,
323 .num_trigger_sources = ARRAY_SIZE(an4_dig8_trigger_sources),
692716f5 324
13f2b9d7 325 .trigger_slopes = &scope_trigger_slopes,
692716f5 326 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 327
4b25cbff
UH
328 .timebases = &timebases,
329 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 330
4b25cbff
UH
331 .vdivs = &vdivs,
332 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
333
334 .num_xdivs = 12,
335 .num_ydivs = 8,
336
74413faf
GS
337 .scpi_dialect = &hameg_scpi_dialect,
338 },
339 {
bf8a02b6 340 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", "HMO3524", NULL},
74413faf
GS
341 .analog_channels = 4,
342 .digital_channels = 16,
343 .digital_pods = 2,
344
345 .analog_names = &scope_analog_channel_names,
346 .digital_names = &scope_digital_channel_names,
347
4b25cbff
UH
348 .devopts = &devopts,
349 .num_devopts = ARRAY_SIZE(devopts),
74413faf 350
6b82c3e5
UH
351 .devopts_cg_analog = &devopts_cg_analog,
352 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
74413faf 353
e131be0a
GT
354 .devopts_cg_digital = &devopts_cg_digital,
355 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
356
4b25cbff 357 .coupling_options = &coupling_options,
692716f5
UH
358 .num_coupling_options = ARRAY_SIZE(coupling_options),
359
e131be0a
GT
360 .logic_threshold = &logic_threshold,
361 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
362
6d0f3508
GT
363 .trigger_sources = &an4_dig16_trigger_sources,
364 .num_trigger_sources = ARRAY_SIZE(an4_dig16_trigger_sources),
692716f5 365
74413faf 366 .trigger_slopes = &scope_trigger_slopes,
692716f5 367 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
74413faf 368
4b25cbff
UH
369 .timebases = &timebases,
370 .num_timebases = ARRAY_SIZE(timebases),
74413faf 371
4b25cbff
UH
372 .vdivs = &vdivs,
373 .num_vdivs = ARRAY_SIZE(vdivs),
74413faf
GS
374
375 .num_xdivs = 12,
376 .num_ydivs = 8,
377
13f2b9d7
DJ
378 .scpi_dialect = &hameg_scpi_dialect,
379 },
380};
381
329733d9 382static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
383 struct scope_state *state)
384{
385 unsigned int i;
8de2dc3b 386 char *tmp;
13f2b9d7 387
0a1f7b09 388 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
389 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
390 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
d9251a2c 391 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 392 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 393 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 394 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
395 }
396
0a1f7b09 397 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
398 sr_info("State of digital channel %d -> %s", i,
399 state->digital_channels[i] ? "On" : "Off");
400 }
401
0a1f7b09 402 for (i = 0; i < config->digital_pods; i++) {
e131be0a 403 if (strncmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold], 4))
262061ff 404 sr_info("State of digital POD %d -> %s : %s (threshold)", i + 1,
e131be0a
GT
405 state->digital_pods[i].state ? "On" : "Off",
406 (*config->logic_threshold)[state->digital_pods[i].threshold]);
407 else // user-defined or custom logic threshold
262061ff 408 sr_info("State of digital POD %d -> %s : %E (threshold)", i + 1,
e131be0a
GT
409 state->digital_pods[i].state ? "On" : "Off",
410 state->digital_pods[i].user_threshold);
13f2b9d7
DJ
411 }
412
6984cfb2
SA
413 tmp = sr_period_string((*config->timebases)[state->timebase][0],
414 (*config->timebases)[state->timebase][1]);
8de2dc3b
DJ
415 sr_info("Current timebase: %s", tmp);
416 g_free(tmp);
417
14a2f74d
DJ
418 tmp = sr_samplerate_string(state->sample_rate);
419 sr_info("Current samplerate: %s", tmp);
420 g_free(tmp);
421
4fa4db2c
GT
422 if (!strcmp("PATT", (*config->trigger_sources)[state->trigger_source]))
423 sr_info("Current trigger: %s (pattern), %.2f (offset)",
424 state->trigger_pattern,
425 state->horiz_triggerpos);
426 else // Edge (slope) trigger
427 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
428 (*config->trigger_sources)[state->trigger_source],
429 (*config->trigger_slopes)[state->trigger_slope],
430 state->horiz_triggerpos);
13f2b9d7
DJ
431}
432
23f43dff 433static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
692716f5 434 const char *command, const char *(*array)[], unsigned int n, int *result)
13f2b9d7
DJ
435{
436 char *tmp;
bd633efa 437 int idx;
13f2b9d7 438
67398969 439 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK)
13f2b9d7 440 return SR_ERR;
13f2b9d7 441
bd633efa 442 if ((idx = std_str_idx_s(tmp, *array, n)) < 0) {
13f2b9d7 443 g_free(tmp);
bd633efa 444 return SR_ERR_ARG;
13f2b9d7
DJ
445 }
446
bd633efa
UH
447 *result = idx;
448
449 g_free(tmp);
450
13f2b9d7
DJ
451 return SR_OK;
452}
453
8fff7519 454/**
a53acd7d
SB
455 * This function takes a value of the form "2.000E-03" and returns the index
456 * of an array where a matching pair was found.
8fff7519
SA
457 *
458 * @param value The string to be parsed.
459 * @param array The array of s/f pairs.
460 * @param array_len The number of pairs in the array.
461 * @param result The index at which a matching pair was found.
462 *
463 * @return SR_ERR on any parsing error, SR_OK otherwise.
464 */
465static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 466 int array_len, unsigned int *result)
8fff7519 467{
a53acd7d
SB
468 struct sr_rational rval;
469 struct sr_rational aval;
8cccbac8 470
a53acd7d 471 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
472 return SR_ERR;
473
a53acd7d
SB
474 for (int i = 0; i < array_len; i++) {
475 sr_rational_set(&aval, array[i][0], array[i][1]);
476 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
477 *result = i;
478 return SR_OK;
479 }
480 }
481
482 return SR_ERR;
483}
484
bd70ec4b
SB
485static struct sr_channel *get_channel_by_index_and_type(GSList *channel_lhead,
486 int index, int type)
487{
488 while (channel_lhead) {
489 struct sr_channel *ch = channel_lhead->data;
490 if (ch->index == index && ch->type == type)
491 return ch;
492
493 channel_lhead = channel_lhead->next;
494 }
495
496 return 0;
497}
498
499static int analog_channel_state_get(struct sr_dev_inst *sdi,
329733d9 500 const struct scope_config *config,
13f2b9d7
DJ
501 struct scope_state *state)
502{
8de2dc3b 503 unsigned int i, j;
13f2b9d7 504 char command[MAX_COMMAND_SIZE];
8fff7519 505 char *tmp_str;
bd70ec4b
SB
506 struct sr_channel *ch;
507 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 508
0a1f7b09 509 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
510 g_snprintf(command, sizeof(command),
511 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
512 i + 1);
513
23f43dff 514 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
515 &state->analog_channels[i].state) != SR_OK)
516 return SR_ERR;
517
bd70ec4b
SB
518 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_ANALOG);
519 if (ch)
520 ch->enabled = state->analog_channels[i].state;
521
13f2b9d7
DJ
522 g_snprintf(command, sizeof(command),
523 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
524 i + 1);
525
8fff7519 526 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 527 return SR_ERR;
8fff7519 528
53012da6 529 if (array_float_get(tmp_str, ARRAY_AND_SIZE(vdivs), &j) != SR_OK) {
8fff7519 530 g_free(tmp_str);
b4e31d2a 531 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 532 return SR_ERR;
b4e31d2a 533 }
13f2b9d7 534
8fff7519
SA
535 g_free(tmp_str);
536 state->analog_channels[i].vdiv = j;
537
13f2b9d7
DJ
538 g_snprintf(command, sizeof(command),
539 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
540 i + 1);
541
23f43dff 542 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
543 &state->analog_channels[i].vertical_offset) != SR_OK)
544 return SR_ERR;
545
546 g_snprintf(command, sizeof(command),
547 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
548 i + 1);
549
23f43dff 550 if (scope_state_get_array_option(scpi, command, config->coupling_options,
692716f5 551 config->num_coupling_options,
13f2b9d7
DJ
552 &state->analog_channels[i].coupling) != SR_OK)
553 return SR_ERR;
448e81b1
SB
554
555 g_snprintf(command, sizeof(command),
556 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
557 i + 1);
558
559 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
560 return SR_ERR;
561
562 if (tmp_str[0] == 'A')
563 state->analog_channels[i].probe_unit = 'A';
564 else
565 state->analog_channels[i].probe_unit = 'V';
566 g_free(tmp_str);
13f2b9d7
DJ
567 }
568
569 return SR_OK;
570}
571
bd70ec4b 572static int digital_channel_state_get(struct sr_dev_inst *sdi,
329733d9 573 const struct scope_config *config,
13f2b9d7
DJ
574 struct scope_state *state)
575{
576 unsigned int i;
e131be0a
GT
577 int result = SR_ERR;
578 static char *logic_threshold_short[] = {};
13f2b9d7 579 char command[MAX_COMMAND_SIZE];
bd70ec4b
SB
580 struct sr_channel *ch;
581 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 582
0a1f7b09 583 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
584 g_snprintf(command, sizeof(command),
585 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
586 i);
587
23f43dff 588 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
589 &state->digital_channels[i]) != SR_OK)
590 return SR_ERR;
bd70ec4b
SB
591
592 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_LOGIC);
593 if (ch)
594 ch->enabled = state->digital_channels[i];
13f2b9d7
DJ
595 }
596
e131be0a
GT
597 /* According to the SCPI standard, the response to the command
598 * SCPI_CMD_GET_DIG_POD_THRESHOLD might return "USER" instead of
599 * "USER1".
600 *
601 * This makes more difficult to validate the response when the logic
602 * threshold is set to "USER1" and therefore we need to prevent device
603 * opening failures in such configuration case...
604 */
605 for (i = 0; i < config->num_logic_threshold; i++) {
606 logic_threshold_short[i] = g_strdup((*config->logic_threshold)[i]);
607 if (!strcmp("USER1", (*config->logic_threshold)[i]))
608 g_strlcpy(logic_threshold_short[i],
609 (*config->logic_threshold)[i], strlen((*config->logic_threshold)[i]));
610 }
611
0a1f7b09 612 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
613 g_snprintf(command, sizeof(command),
614 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
615 i + 1);
616
23f43dff 617 if (sr_scpi_get_bool(scpi, command,
e131be0a
GT
618 &state->digital_pods[i].state) != SR_OK)
619 goto exit;
620
621 g_snprintf(command, sizeof(command),
622 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_THRESHOLD],
623 i + 1);
624
625 /* Check for both standard and shortened responses. */
626 if (scope_state_get_array_option(scpi, command, config->logic_threshold,
627 config->num_logic_threshold,
628 &state->digital_pods[i].threshold) != SR_OK)
629 if (scope_state_get_array_option(scpi, command, (const char * (*)[]) &logic_threshold_short,
630 config->num_logic_threshold,
631 &state->digital_pods[i].threshold) != SR_OK)
632 goto exit;
633
634 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]))
635 g_snprintf(command, sizeof(command),
636 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
637 i + 1, 1); // USER1 logic threshold setting
638
639 if (!strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
640 g_snprintf(command, sizeof(command),
641 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
642 i + 1, 2); // USER2 for custom logic_threshold setting
643
644 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
645 !strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
646 if (sr_scpi_get_float(scpi, command,
647 &state->digital_pods[i].user_threshold) != SR_OK)
648 goto exit;
13f2b9d7
DJ
649 }
650
e131be0a
GT
651 result = SR_OK;
652
653exit:
654 for (i = 0; i < config->num_logic_threshold; i++)
655 g_free(logic_threshold_short[i]);
656
657 return result;
13f2b9d7
DJ
658}
659
14a2f74d
DJ
660SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
661{
662 struct dev_context *devc;
663 struct scope_state *state;
329733d9 664 const struct scope_config *config;
14a2f74d 665 float tmp_float;
14a2f74d
DJ
666
667 devc = sdi->priv;
668 config = devc->model_config;
669 state = devc->model_state;
14a2f74d 670
39e19723
GT
671 if (sr_scpi_get_float(sdi->conn,
672 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
673 &tmp_float) != SR_OK)
674 return SR_ERR;
c06c24d2 675
39e19723 676 state->sample_rate = tmp_float;
14a2f74d
DJ
677
678 return SR_OK;
679}
680
719eff68 681SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
682{
683 struct dev_context *devc;
684 struct scope_state *state;
329733d9 685 const struct scope_config *config;
8de2dc3b
DJ
686 float tmp_float;
687 unsigned int i;
8cccbac8 688 char *tmp_str;
13f2b9d7
DJ
689
690 devc = sdi->priv;
691 config = devc->model_config;
692 state = devc->model_state;
693
8de2dc3b
DJ
694 sr_info("Fetching scope state");
695
bd70ec4b 696 if (analog_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
697 return SR_ERR;
698
bd70ec4b 699 if (digital_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
700 return SR_ERR;
701
89280b1a
UH
702 if (sr_scpi_get_float(sdi->conn,
703 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
704 &tmp_float) != SR_OK)
705 return SR_ERR;
706
8cccbac8
SA
707 if (sr_scpi_get_string(sdi->conn,
708 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
709 &tmp_str) != SR_OK)
710 return SR_ERR;
711
53012da6 712 if (array_float_get(tmp_str, ARRAY_AND_SIZE(timebases), &i) != SR_OK) {
8cccbac8 713 g_free(tmp_str);
b4e31d2a 714 sr_err("Could not determine array index for time base.");
13f2b9d7 715 return SR_ERR;
b4e31d2a 716 }
e5b7eef7 717 g_free(tmp_str);
13f2b9d7 718
8cccbac8
SA
719 state->timebase = i;
720
89280b1a
UH
721 if (sr_scpi_get_float(sdi->conn,
722 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 723 &tmp_float) != SR_OK)
13f2b9d7 724 return SR_ERR;
422a1c0d
DJ
725 state->horiz_triggerpos = tmp_float /
726 (((double) (*config->timebases)[state->timebase][0] /
727 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
728 state->horiz_triggerpos -= 0.5;
729 state->horiz_triggerpos *= -1;
13f2b9d7 730
89280b1a
UH
731 if (scope_state_get_array_option(sdi->conn,
732 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
692716f5
UH
733 config->trigger_sources, config->num_trigger_sources,
734 &state->trigger_source) != SR_OK)
13f2b9d7
DJ
735 return SR_ERR;
736
89280b1a 737 if (scope_state_get_array_option(sdi->conn,
692716f5
UH
738 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
739 config->trigger_slopes, config->num_trigger_slopes,
740 &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
741 return SR_ERR;
742
4fa4db2c
GT
743 if (sr_scpi_get_string(sdi->conn,
744 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_PATTERN],
745 &state->trigger_pattern) != SR_OK)
746 return SR_ERR;
747
14a2f74d
DJ
748 if (hmo_update_sample_rate(sdi) != SR_OK)
749 return SR_ERR;
750
8de2dc3b
DJ
751 sr_info("Fetching finished.");
752
13f2b9d7
DJ
753 scope_state_dump(config, state);
754
755 return SR_OK;
756}
757
329733d9 758static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
759{
760 struct scope_state *state;
761
a95f142e
UH
762 state = g_malloc0(sizeof(struct scope_state));
763 state->analog_channels = g_malloc0_n(config->analog_channels,
764 sizeof(struct analog_channel_state));
765 state->digital_channels = g_malloc0_n(
766 config->digital_channels, sizeof(gboolean));
767 state->digital_pods = g_malloc0_n(config->digital_pods,
e131be0a 768 sizeof(struct digital_pod_state));
13f2b9d7
DJ
769
770 return state;
13f2b9d7
DJ
771}
772
719eff68 773SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
774{
775 g_free(state->analog_channels);
776 g_free(state->digital_channels);
777 g_free(state->digital_pods);
778 g_free(state);
779}
780
781SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
782{
13f2b9d7 783 int model_index;
2d224dba 784 unsigned int i, j, group;
ba7dd8bb 785 struct sr_channel *ch;
13f2b9d7 786 struct dev_context *devc;
eac9fcd2 787 int ret;
13f2b9d7
DJ
788
789 devc = sdi->priv;
790 model_index = -1;
791
89280b1a 792 /* Find the exact model. */
13f2b9d7
DJ
793 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
794 for (j = 0; scope_models[i].name[j]; j++) {
795 if (!strcmp(sdi->model, scope_models[i].name[j])) {
796 model_index = i;
797 break;
798 }
799 }
800 if (model_index != -1)
801 break;
802 }
803
804 if (model_index == -1) {
e35ebc6a 805 sr_dbg("Unsupported device.");
13f2b9d7
DJ
806 return SR_ERR_NA;
807 }
808
562b7ae5
SA
809 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
810 scope_models[model_index].analog_channels);
562b7ae5
SA
811 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
812 scope_models[model_index].digital_pods);
b0e80e9a
GS
813 if (!devc->analog_groups || !devc->digital_groups) {
814 g_free(devc->analog_groups);
815 g_free(devc->digital_groups);
816 return SR_ERR_MALLOC;
817 }
13f2b9d7 818
89280b1a 819 /* Add analog channels. */
13f2b9d7 820 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 821 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 822 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 823
562b7ae5
SA
824 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
825
826 devc->analog_groups[i]->name = g_strdup(
827 (char *)(*scope_models[model_index].analog_names)[i]);
828 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 829
660e398f 830 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 831 devc->analog_groups[i]);
13f2b9d7
DJ
832 }
833
660e398f 834 /* Add digital channel groups. */
eac9fcd2 835 ret = SR_OK;
0a1f7b09 836 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
562b7ae5 837 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
eac9fcd2
GS
838 if (!devc->digital_groups[i]) {
839 ret = SR_ERR_MALLOC;
840 break;
841 }
262061ff 842 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i + 1);
660e398f 843 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 844 devc->digital_groups[i]);
13f2b9d7 845 }
eac9fcd2
GS
846 if (ret != SR_OK)
847 return ret;
13f2b9d7 848
89280b1a 849 /* Add digital channels. */
13f2b9d7 850 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 851 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 852 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 853
2d224dba
GS
854 group = i / 8;
855 devc->digital_groups[group]->channels = g_slist_append(
856 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
857 }
858
859 devc->model_config = &scope_models[model_index];
d779dcac 860 devc->samples_limit = 0;
13f2b9d7
DJ
861 devc->frame_limit = 0;
862
863 if (!(devc->model_state = scope_state_new(devc->model_config)))
864 return SR_ERR_MALLOC;
865
866 return SR_OK;
867}
868
e06875b2
GS
869/* Queue data of one channel group, for later submission. */
870SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
871 size_t group, GByteArray *pod_data)
872{
873 size_t size;
874 GByteArray *store;
875 uint8_t *logic_data;
876 size_t idx, logic_step;
877
878 /*
879 * Upon first invocation, allocate the array which can hold the
880 * combined logic data for all channels. Assume that each channel
881 * will yield an identical number of samples per receive call.
882 *
883 * As a poor man's safety measure: (Silently) skip processing
884 * for unexpected sample counts, and ignore samples for
885 * unexpected channel groups. Don't bother with complicated
886 * resize logic, considering that many models only support one
887 * pod, and the most capable supported models have two pods of
888 * identical size. We haven't yet seen any "odd" configuration.
889 */
890 if (!devc->logic_data) {
891 size = pod_data->len * devc->pod_count;
892 store = g_byte_array_sized_new(size);
893 memset(store->data, 0, size);
894 store = g_byte_array_set_size(store, size);
895 devc->logic_data = store;
896 } else {
897 store = devc->logic_data;
898 size = store->len / devc->pod_count;
e06875b2
GS
899 if (group >= devc->pod_count)
900 return;
901 }
902
903 /*
904 * Fold the data of the most recently received channel group into
905 * the storage, where data resides for all channels combined.
906 */
907 logic_data = store->data;
908 logic_data += group;
909 logic_step = devc->pod_count;
910 for (idx = 0; idx < pod_data->len; idx++) {
911 *logic_data = pod_data->data[idx];
912 logic_data += logic_step;
913 }
d779dcac
GT
914
915 /* Truncate acquisition if a smaller number of samples has been requested. */
916 if (devc->samples_limit > 0 && devc->logic_data->len > devc->samples_limit * devc->pod_count)
917 devc->logic_data->len = devc->samples_limit * devc->pod_count;
e06875b2
GS
918}
919
920/* Submit data for all channels, after the individual groups got collected. */
921SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
922 struct dev_context *devc)
923{
924 struct sr_datafeed_packet packet;
925 struct sr_datafeed_logic logic;
926
927 if (!devc->logic_data)
928 return;
929
930 logic.data = devc->logic_data->data;
931 logic.length = devc->logic_data->len;
932 logic.unitsize = devc->pod_count;
933
934 packet.type = SR_DF_LOGIC;
935 packet.payload = &logic;
936
937 sr_session_send(sdi, &packet);
938}
939
940/* Undo previous resource allocation. */
941SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
942{
943
944 if (devc->logic_data) {
945 g_byte_array_free(devc->logic_data, TRUE);
946 devc->logic_data = NULL;
947 }
948 /*
949 * Keep 'pod_count'! It's required when more frames will be
950 * received, and does not harm when kept after acquisition.
951 */
952}
953
719eff68 954SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 955{
ba7dd8bb 956 struct sr_channel *ch;
13f2b9d7 957 struct sr_dev_inst *sdi;
06a3e78a 958 struct dev_context *devc;
401b83a1 959 struct scope_state *state;
13f2b9d7 960 struct sr_datafeed_packet packet;
401b83a1
SB
961 GByteArray *data;
962 struct sr_datafeed_analog analog;
963 struct sr_analog_encoding encoding;
964 struct sr_analog_meaning meaning;
965 struct sr_analog_spec spec;
89280b1a 966 struct sr_datafeed_logic logic;
e06875b2 967 size_t group;
06a3e78a
DJ
968
969 (void)fd;
f0729866 970 (void)revents;
06a3e78a 971
f62f595b
MK
972 data = NULL;
973
06a3e78a
DJ
974 if (!(sdi = cb_data))
975 return TRUE;
976
977 if (!(devc = sdi->priv))
978 return TRUE;
979
f4f273ce
SB
980 /* Although this is correct in general, the USBTMC libusb implementation
981 * currently does not generate an event prior to the first read. Often
982 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
983 if (revents != G_IO_IN)
984 return TRUE;
f4f273ce 985 */
13f2b9d7 986
dc89faea 987 ch = devc->current_channel->data;
401b83a1 988 state = devc->model_state;
13f2b9d7 989
b23eb1d4
GS
990 /*
991 * Send "frame begin" packet upon reception of data for the
992 * first enabled channel.
993 */
994 if (devc->current_channel == devc->enabled_channels) {
995 packet.type = SR_DF_FRAME_BEGIN;
996 sr_session_send(sdi, &packet);
997 }
998
999 /*
1000 * Pass on the received data of the channel(s).
1001 */
dc89faea
UH
1002 switch (ch->type) {
1003 case SR_CHANNEL_ANALOG:
401b83a1 1004 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 1005 if (data)
401b83a1 1006 g_byte_array_free(data, TRUE);
dc89faea 1007 return TRUE;
13f2b9d7
DJ
1008 }
1009
401b83a1
SB
1010 packet.type = SR_DF_ANALOG;
1011
1012 analog.data = data->data;
1013 analog.num_samples = data->len / sizeof(float);
d779dcac
GT
1014 /* Truncate acquisition if a smaller number of samples has been requested. */
1015 if (devc->samples_limit > 0 && analog.num_samples > devc->samples_limit)
1016 analog.num_samples = devc->samples_limit;
401b83a1
SB
1017 analog.encoding = &encoding;
1018 analog.meaning = &meaning;
1019 analog.spec = &spec;
1020
1021 encoding.unitsize = sizeof(float);
1022 encoding.is_signed = TRUE;
1023 encoding.is_float = TRUE;
65a6794e
GS
1024#ifdef WORDS_BIGENDIAN
1025 encoding.is_bigendian = TRUE;
1026#else
d1ad8b10 1027 encoding.is_bigendian = FALSE;
65a6794e 1028#endif
7dcaddd3
UH
1029 /* TODO: Use proper 'digits' value for this device (and its modes). */
1030 encoding.digits = 2;
401b83a1
SB
1031 encoding.is_digits_decimal = FALSE;
1032 encoding.scale.p = 1;
1033 encoding.scale.q = 1;
1034 encoding.offset.p = 0;
1035 encoding.offset.q = 1;
1036 if (state->analog_channels[ch->index].probe_unit == 'V') {
1037 meaning.mq = SR_MQ_VOLTAGE;
1038 meaning.unit = SR_UNIT_VOLT;
1039 } else {
1040 meaning.mq = SR_MQ_CURRENT;
1041 meaning.unit = SR_UNIT_AMPERE;
1042 }
1043 meaning.mqflags = 0;
1044 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
1045 /* TODO: Use proper 'digits' value for this device (and its modes). */
1046 spec.spec_digits = 2;
dc89faea 1047 packet.payload = &analog;
695dc859 1048 sr_session_send(sdi, &packet);
d779dcac 1049 devc->num_samples = data->len / sizeof(float);
401b83a1
SB
1050 g_slist_free(meaning.channels);
1051 g_byte_array_free(data, TRUE);
dc89faea
UH
1052 data = NULL;
1053 break;
1054 case SR_CHANNEL_LOGIC:
401b83a1 1055 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
14cb6aa4
GT
1056 if (data)
1057 g_byte_array_free(data, TRUE);
dc89faea 1058 return TRUE;
13f2b9d7 1059 }
dc89faea 1060
e06875b2
GS
1061 /*
1062 * If only data from the first pod is involved in the
1063 * acquisition, then the raw input bytes can get passed
1064 * forward for performance reasons. When the second pod
1065 * is involved (either alone, or in combination with the
1066 * first pod), then the received bytes need to be put
1067 * into memory in such a layout that all channel groups
1068 * get combined, and a unitsize larger than a single byte
1069 * applies. The "queue" logic transparently copes with
1070 * any such configuration. This works around the lack
1071 * of support for "meaning" to logic data, which is used
1072 * above for analog data.
1073 */
1074 if (devc->pod_count == 1) {
1075 packet.type = SR_DF_LOGIC;
1076 logic.data = data->data;
1077 logic.length = data->len;
d779dcac
GT
1078 /* Truncate acquisition if a smaller number of samples has been requested. */
1079 if (devc->samples_limit > 0 && logic.length > devc->samples_limit)
1080 logic.length = devc->samples_limit;
e06875b2
GS
1081 logic.unitsize = 1;
1082 packet.payload = &logic;
1083 sr_session_send(sdi, &packet);
1084 } else {
1085 group = ch->index / 8;
1086 hmo_queue_logic_data(devc, group, data);
1087 }
dc89faea 1088
d779dcac 1089 devc->num_samples = data->len / devc->pod_count;
401b83a1 1090 g_byte_array_free(data, TRUE);
dc89faea
UH
1091 data = NULL;
1092 break;
1093 default:
1094 sr_err("Invalid channel type.");
1095 break;
1096 }
1097
b23eb1d4
GS
1098 /*
1099 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
1100 * channels was received, then flush potentially queued logic data,
1101 * and send the "frame end" packet.
b23eb1d4 1102 */
dc89faea
UH
1103 if (devc->current_channel->next) {
1104 devc->current_channel = devc->current_channel->next;
1105 hmo_request_data(sdi);
b23eb1d4
GS
1106 return TRUE;
1107 }
e06875b2
GS
1108 hmo_send_logic_packet(sdi, devc);
1109
1110 /*
1111 * Release the logic data storage after each frame. This copes
1112 * with sample counts that differ in length per frame. -- Is
1113 * this a real constraint when acquiring multiple frames with
1114 * identical device settings?
1115 */
1116 hmo_cleanup_logic_data(devc);
1117
b23eb1d4
GS
1118 packet.type = SR_DF_FRAME_END;
1119 sr_session_send(sdi, &packet);
1120
1121 /*
1122 * End of frame was reached. Stop acquisition after the specified
d779dcac
GT
1123 * number of frames or after the specified number of samples, or
1124 * continue reception by starting over at the first enabled channel.
b23eb1d4 1125 */
d779dcac 1126 if (++devc->num_frames >= devc->frame_limit || devc->num_samples >= devc->samples_limit) {
d2f7c417 1127 sr_dev_acquisition_stop(sdi);
e06875b2 1128 hmo_cleanup_logic_data(devc);
dc89faea
UH
1129 } else {
1130 devc->current_channel = devc->enabled_channels;
1131 hmo_request_data(sdi);
06a3e78a
DJ
1132 }
1133
1134 return TRUE;
1135}