]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: free memory that was allocated by SCPI get routines
[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",
29a9b1a0 37 [SCPI_CMD_GET_HORIZONTAL_DIV] = ":TIM:DIV?",
e131be0a
GT
38 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
39 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
40 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
e131be0a
GT
41 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
42 ":FORM REAL,32;:CHAN%d:DATA?",
66ddc22a
GT
43 [SCPI_CMD_GET_VERTICAL_SCALE] = ":CHAN%d:SCAL?",
44 [SCPI_CMD_SET_VERTICAL_SCALE] = ":CHAN%d:SCAL %s",
e131be0a
GT
45 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
46 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
97a00074
GT
47 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
48 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
e131be0a 49 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
c8ecfa6e 50 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:TYPE EDGE;:TRIG:A:EDGE:SLOP %s",
4fa4db2c
GT
51 [SCPI_CMD_GET_TRIGGER_PATTERN] = ":TRIG:A:PATT:SOUR?",
52 [SCPI_CMD_SET_TRIGGER_PATTERN] = ":TRIG:A:TYPE LOGIC;" \
53 ":TRIG:A:PATT:FUNC AND;" \
0184aca1 54 ":TRIG:A:PATT:COND \"TRUE\";" \
4fa4db2c
GT
55 ":TRIG:A:PATT:MODE OFF;" \
56 ":TRIG:A:PATT:SOUR \"%s\"",
97a00074
GT
57 [SCPI_CMD_GET_HIGH_RESOLUTION] = ":ACQ:HRES?",
58 [SCPI_CMD_SET_HIGH_RESOLUTION] = ":ACQ:HRES %s",
59 [SCPI_CMD_GET_PEAK_DETECTION] = ":ACQ:PEAK?",
60 [SCPI_CMD_SET_PEAK_DETECTION] = ":ACQ:PEAK %s",
e131be0a
GT
61 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
62 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
63 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
64 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
65 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
66 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
67 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
68 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
69 [SCPI_CMD_GET_DIG_POD_THRESHOLD] = ":POD%d:THR?",
70 [SCPI_CMD_SET_DIG_POD_THRESHOLD] = ":POD%d:THR %s",
71 [SCPI_CMD_GET_DIG_POD_USER_THRESHOLD] = ":POD%d:THR:UDL%d?",
72 [SCPI_CMD_SET_DIG_POD_USER_THRESHOLD] = ":POD%d:THR:UDL%d %s",
13f2b9d7
DJ
73};
74
aac30633
GT
75static const char *rohde_schwarz_log_not_pod_scpi_dialect[] = {
76 [SCPI_CMD_GET_DIG_DATA] = ":FORM UINT,8;:LOG%d:DATA?",
77 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
78 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
29a9b1a0 79 [SCPI_CMD_GET_HORIZONTAL_DIV] = ":TIM:DIV?",
aac30633
GT
80 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
81 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
82 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
83 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
84 ":FORM REAL,32;:CHAN%d:DATA?",
66ddc22a
GT
85 [SCPI_CMD_GET_VERTICAL_SCALE] = ":CHAN%d:SCAL?",
86 [SCPI_CMD_SET_VERTICAL_SCALE] = ":CHAN%d:SCAL %s",
aac30633
GT
87 [SCPI_CMD_GET_DIG_POD_STATE] = ":LOG%d:STAT?",
88 [SCPI_CMD_SET_DIG_POD_STATE] = ":LOG%d:STAT %d",
97a00074
GT
89 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
90 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
aac30633
GT
91 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
92 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:TYPE EDGE;:TRIG:A:EDGE:SLOP %s",
93 [SCPI_CMD_GET_TRIGGER_PATTERN] = ":TRIG:A:PATT:SOUR?",
94 [SCPI_CMD_SET_TRIGGER_PATTERN] = ":TRIG:A:TYPE LOGIC;" \
95 ":TRIG:A:PATT:FUNC AND;" \
0184aca1 96 ":TRIG:A:PATT:COND \"TRUE\";" \
aac30633
GT
97 ":TRIG:A:PATT:MODE OFF;" \
98 ":TRIG:A:PATT:SOUR \"%s\"",
97a00074
GT
99 [SCPI_CMD_GET_HIGH_RESOLUTION] = ":ACQ:HRES?",
100 [SCPI_CMD_SET_HIGH_RESOLUTION] = ":ACQ:HRES %s",
101 [SCPI_CMD_GET_PEAK_DETECTION] = ":ACQ:PEAK?",
102 [SCPI_CMD_SET_PEAK_DETECTION] = ":ACQ:PEAK %s",
aac30633
GT
103 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
104 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
105 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?", /* Might not be supported on RTB200x... */
106 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
107 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
108 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
109 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
110 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
111 [SCPI_CMD_GET_DIG_POD_THRESHOLD] = ":DIG%d:TECH?",
112 [SCPI_CMD_SET_DIG_POD_THRESHOLD] = ":DIG%d:TECH %s",
113 [SCPI_CMD_GET_DIG_POD_USER_THRESHOLD] = ":DIG%d:THR?",
114 [SCPI_CMD_SET_DIG_POD_USER_THRESHOLD] = ":DIG%d:THR %s",
115};
116
4b25cbff 117static const uint32_t devopts[] = {
13f2b9d7 118 SR_CONF_OSCILLOSCOPE,
830e24b6 119 SR_CONF_LIMIT_SAMPLES | SR_CONF_SET,
98c7ef37 120 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
86621306 121 SR_CONF_SAMPLERATE | SR_CONF_GET,
5827f61b 122 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 123 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 124 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
86621306
UH
125 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
126 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
4fa4db2c 127 SR_CONF_TRIGGER_PATTERN | SR_CONF_GET | SR_CONF_SET,
97a00074
GT
128 SR_CONF_HIGH_RESOLUTION | SR_CONF_GET | SR_CONF_SET,
129 SR_CONF_PEAK_DETECTION | SR_CONF_GET | SR_CONF_SET,
13f2b9d7
DJ
130};
131
6b82c3e5 132static const uint32_t devopts_cg_analog[] = {
5827f61b 133 SR_CONF_NUM_VDIV | SR_CONF_GET,
5827f61b 134 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
86621306 135 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
136};
137
e131be0a
GT
138static const uint32_t devopts_cg_digital[] = {
139 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
140 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
141};
142
4b25cbff 143static const char *coupling_options[] = {
b05ab7d2
SB
144 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
145 "ACL", // AC with 1 MOhm termination
146 "DC", // DC with 50 Ohm termination
147 "DCL", // DC with 1 MOhm termination
13f2b9d7 148 "GND",
13f2b9d7
DJ
149};
150
aac30633
GT
151static const char *coupling_options_rtb200x[] = {
152 "ACL", // AC with 1 MOhm termination
153 "DCL", // DC with 1 MOhm termination
154 "GND",
155};
156
157static const char *coupling_options_rtm300x[] = {
158 "ACL", // AC with 1 MOhm termination
159 "DC", // DC with 50 Ohm termination
160 "DCL", // DC with 1 MOhm termination
161 "GND",
162};
163
13f2b9d7
DJ
164static const char *scope_trigger_slopes[] = {
165 "POS",
166 "NEG",
356f64f8 167 "EITH",
13f2b9d7
DJ
168};
169
e131be0a
GT
170/* Predefined logic thresholds. */
171static const char *logic_threshold[] = {
172 "TTL",
173 "ECL",
174 "CMOS",
175 "USER1",
176 "USER2", // overwritten by logic_threshold_custom, use USER1 for permanent setting
177};
178
aac30633
GT
179static const char *logic_threshold_rtb200x_rtm300x[] = {
180 "TTL",
181 "ECL",
182 "CMOS",
183 "MAN", // overwritten by logic_threshold_custom
184};
185
c38d69ad
UH
186/* This might need updates whenever logic_threshold* above change. */
187#define MAX_NUM_LOGIC_THRESHOLD_ENTRIES ARRAY_SIZE(logic_threshold)
188
4cf90b86 189/* RTC1002, HMO Compact2 and HMO1002/HMO1202 */
6d0f3508 190static const char *an2_dig8_trigger_sources[] = {
f8195cb2
UH
191 "CH1", "CH2",
192 "LINE", "EXT", "PATT", "BUS1", "BUS2",
193 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
194};
195
4cf90b86 196/* HMO3xx2 */
6d0f3508
GT
197static const char *an2_dig16_trigger_sources[] = {
198 "CH1", "CH2",
199 "LINE", "EXT", "PATT", "BUS1", "BUS2",
200 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
201 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
202};
203
aac30633
GT
204/* RTB2002 and RTM3002 */
205static const char *an2_dig16_sbus_trigger_sources[] = {
206 "CH1", "CH2",
207 "LINE", "EXT", "PATT", "SBUS1", "SBUS2",
208 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
209 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
210};
211
4cf90b86 212/* HMO Compact4 */
6d0f3508 213static const char *an4_dig8_trigger_sources[] = {
f8195cb2
UH
214 "CH1", "CH2", "CH3", "CH4",
215 "LINE", "EXT", "PATT", "BUS1", "BUS2",
216 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
217};
218
4cf90b86 219/* HMO3xx4 and HMO2524 */
6d0f3508 220static const char *an4_dig16_trigger_sources[] = {
f8195cb2
UH
221 "CH1", "CH2", "CH3", "CH4",
222 "LINE", "EXT", "PATT", "BUS1", "BUS2",
223 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
224 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
74413faf
GS
225};
226
b720f16e 227/* RTB2004, RTM3004 and RTA4004 */
aac30633
GT
228static const char *an4_dig16_sbus_trigger_sources[] = {
229 "CH1", "CH2", "CH3", "CH4",
230 "LINE", "EXT", "PATT", "SBUS1", "SBUS2",
231 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
232 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
233};
234
4b25cbff 235static const uint64_t timebases[][2] = {
a058de04
GT
236 /* nanoseconds */
237 { 1, 1000000000 },
238 { 2, 1000000000 },
239 { 5, 1000000000 },
240 { 10, 1000000000 },
241 { 20, 1000000000 },
242 { 50, 1000000000 },
243 { 100, 1000000000 },
244 { 200, 1000000000 },
245 { 500, 1000000000 },
246 /* microseconds */
247 { 1, 1000000 },
248 { 2, 1000000 },
249 { 5, 1000000 },
250 { 10, 1000000 },
251 { 20, 1000000 },
252 { 50, 1000000 },
253 { 100, 1000000 },
254 { 200, 1000000 },
255 { 500, 1000000 },
256 /* milliseconds */
257 { 1, 1000 },
258 { 2, 1000 },
259 { 5, 1000 },
260 { 10, 1000 },
261 { 20, 1000 },
262 { 50, 1000 },
263 { 100, 1000 },
264 { 200, 1000 },
265 { 500, 1000 },
266 /* seconds */
267 { 1, 1 },
268 { 2, 1 },
269 { 5, 1 },
270 { 10, 1 },
271 { 20, 1 },
272 { 50, 1 },
273};
274
275/* HMO Compact series (HMO722/724/1022/1024/1522/1524/2022/2024) do
276 * not support 1 ns timebase setting.
277 */
278static const uint64_t timebases_hmo_compact[][2] = {
13f2b9d7
DJ
279 /* nanoseconds */
280 { 2, 1000000000 },
281 { 5, 1000000000 },
282 { 10, 1000000000 },
283 { 20, 1000000000 },
284 { 50, 1000000000 },
285 { 100, 1000000000 },
286 { 200, 1000000000 },
287 { 500, 1000000000 },
288 /* microseconds */
289 { 1, 1000000 },
290 { 2, 1000000 },
291 { 5, 1000000 },
292 { 10, 1000000 },
293 { 20, 1000000 },
294 { 50, 1000000 },
295 { 100, 1000000 },
296 { 200, 1000000 },
297 { 500, 1000000 },
298 /* milliseconds */
299 { 1, 1000 },
300 { 2, 1000 },
301 { 5, 1000 },
302 { 10, 1000 },
303 { 20, 1000 },
304 { 50, 1000 },
305 { 100, 1000 },
306 { 200, 1000 },
307 { 500, 1000 },
308 /* seconds */
309 { 1, 1 },
310 { 2, 1 },
311 { 5, 1 },
312 { 10, 1 },
313 { 20, 1 },
314 { 50, 1 },
315};
316
4b25cbff 317static const uint64_t vdivs[][2] = {
13f2b9d7
DJ
318 /* millivolts */
319 { 1, 1000 },
320 { 2, 1000 },
321 { 5, 1000 },
322 { 10, 1000 },
323 { 20, 1000 },
324 { 50, 1000 },
325 { 100, 1000 },
326 { 200, 1000 },
327 { 500, 1000 },
328 /* volts */
329 { 1, 1 },
330 { 2, 1 },
331 { 5, 1 },
332 { 10, 1 },
333};
334
ba7dd8bb 335static const char *scope_analog_channel_names[] = {
f8195cb2 336 "CH1", "CH2", "CH3", "CH4",
13f2b9d7
DJ
337};
338
ba7dd8bb 339static const char *scope_digital_channel_names[] = {
f8195cb2
UH
340 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
341 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
13f2b9d7
DJ
342};
343
a12456f1 344static struct scope_config scope_models[] = {
13f2b9d7 345 {
a058de04
GT
346 /* HMO Compact2: HMO722/1022/1522/2022 support only 8 digital channels. */
347 .name = {"HMO722", "HMO1022", "HMO1522", "HMO2022", NULL},
348 .analog_channels = 2,
349 .digital_channels = 8,
350
351 .analog_names = &scope_analog_channel_names,
352 .digital_names = &scope_digital_channel_names,
353
354 .devopts = &devopts,
355 .num_devopts = ARRAY_SIZE(devopts),
356
357 .devopts_cg_analog = &devopts_cg_analog,
358 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
359
360 .devopts_cg_digital = &devopts_cg_digital,
361 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
362
363 .coupling_options = &coupling_options,
364 .num_coupling_options = ARRAY_SIZE(coupling_options),
365
366 .logic_threshold = &logic_threshold,
367 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
368 .logic_threshold_for_pod = TRUE,
369
370 .trigger_sources = &an2_dig8_trigger_sources,
371 .num_trigger_sources = ARRAY_SIZE(an2_dig8_trigger_sources),
372
373 .trigger_slopes = &scope_trigger_slopes,
374 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
375
376 .timebases = &timebases_hmo_compact,
377 .num_timebases = ARRAY_SIZE(timebases_hmo_compact),
378
379 .vdivs = &vdivs,
380 .num_vdivs = ARRAY_SIZE(vdivs),
381
a058de04
GT
382 .num_ydivs = 8,
383
384 .scpi_dialect = &hameg_scpi_dialect,
385 },
386 {
387 /* RTC1002 and HMO1002/HMO1202 support only 8 digital channels. */
388 .name = {"RTC1002", "HMO1002", "HMO1202", NULL},
13f2b9d7
DJ
389 .analog_channels = 2,
390 .digital_channels = 8,
13f2b9d7 391
ba7dd8bb
UH
392 .analog_names = &scope_analog_channel_names,
393 .digital_names = &scope_digital_channel_names,
13f2b9d7 394
4b25cbff
UH
395 .devopts = &devopts,
396 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 397
6b82c3e5
UH
398 .devopts_cg_analog = &devopts_cg_analog,
399 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 400
e131be0a
GT
401 .devopts_cg_digital = &devopts_cg_digital,
402 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
403
4b25cbff 404 .coupling_options = &coupling_options,
692716f5
UH
405 .num_coupling_options = ARRAY_SIZE(coupling_options),
406
e131be0a
GT
407 .logic_threshold = &logic_threshold,
408 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
aac30633 409 .logic_threshold_for_pod = TRUE,
e131be0a 410
6d0f3508
GT
411 .trigger_sources = &an2_dig8_trigger_sources,
412 .num_trigger_sources = ARRAY_SIZE(an2_dig8_trigger_sources),
413
414 .trigger_slopes = &scope_trigger_slopes,
415 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
416
417 .timebases = &timebases,
418 .num_timebases = ARRAY_SIZE(timebases),
419
420 .vdivs = &vdivs,
421 .num_vdivs = ARRAY_SIZE(vdivs),
422
6d0f3508
GT
423 .num_ydivs = 8,
424
425 .scpi_dialect = &hameg_scpi_dialect,
426 },
427 {
428 /* HMO3032/3042/3052/3522 support 16 digital channels. */
429 .name = {"HMO3032", "HMO3042", "HMO3052", "HMO3522", NULL},
430 .analog_channels = 2,
431 .digital_channels = 16,
6d0f3508
GT
432
433 .analog_names = &scope_analog_channel_names,
434 .digital_names = &scope_digital_channel_names,
435
436 .devopts = &devopts,
437 .num_devopts = ARRAY_SIZE(devopts),
438
439 .devopts_cg_analog = &devopts_cg_analog,
440 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
441
e131be0a
GT
442 .devopts_cg_digital = &devopts_cg_digital,
443 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
444
6d0f3508
GT
445 .coupling_options = &coupling_options,
446 .num_coupling_options = ARRAY_SIZE(coupling_options),
447
e131be0a
GT
448 .logic_threshold = &logic_threshold,
449 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
aac30633 450 .logic_threshold_for_pod = TRUE,
e131be0a 451
6d0f3508
GT
452 .trigger_sources = &an2_dig16_trigger_sources,
453 .num_trigger_sources = ARRAY_SIZE(an2_dig16_trigger_sources),
692716f5 454
13f2b9d7 455 .trigger_slopes = &scope_trigger_slopes,
692716f5 456 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 457
4b25cbff
UH
458 .timebases = &timebases,
459 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 460
4b25cbff
UH
461 .vdivs = &vdivs,
462 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7 463
13f2b9d7
DJ
464 .num_ydivs = 8,
465
466 .scpi_dialect = &hameg_scpi_dialect,
467 },
468 {
a058de04 469 /* HMO Compact4: HMO724/1024/1524/2024 support only 8 digital channels. */
74413faf 470 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
13f2b9d7
DJ
471 .analog_channels = 4,
472 .digital_channels = 8,
13f2b9d7 473
ba7dd8bb
UH
474 .analog_names = &scope_analog_channel_names,
475 .digital_names = &scope_digital_channel_names,
13f2b9d7 476
4b25cbff
UH
477 .devopts = &devopts,
478 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 479
6b82c3e5
UH
480 .devopts_cg_analog = &devopts_cg_analog,
481 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 482
e131be0a
GT
483 .devopts_cg_digital = &devopts_cg_digital,
484 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
485
4b25cbff 486 .coupling_options = &coupling_options,
692716f5
UH
487 .num_coupling_options = ARRAY_SIZE(coupling_options),
488
e131be0a
GT
489 .logic_threshold = &logic_threshold,
490 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
aac30633 491 .logic_threshold_for_pod = TRUE,
e131be0a 492
6d0f3508
GT
493 .trigger_sources = &an4_dig8_trigger_sources,
494 .num_trigger_sources = ARRAY_SIZE(an4_dig8_trigger_sources),
692716f5 495
13f2b9d7 496 .trigger_slopes = &scope_trigger_slopes,
692716f5 497 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 498
a058de04
GT
499 .timebases = &timebases_hmo_compact,
500 .num_timebases = ARRAY_SIZE(timebases_hmo_compact),
13f2b9d7 501
4b25cbff
UH
502 .vdivs = &vdivs,
503 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7 504
13f2b9d7
DJ
505 .num_ydivs = 8,
506
74413faf
GS
507 .scpi_dialect = &hameg_scpi_dialect,
508 },
509 {
bf8a02b6 510 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", "HMO3524", NULL},
74413faf
GS
511 .analog_channels = 4,
512 .digital_channels = 16,
74413faf
GS
513
514 .analog_names = &scope_analog_channel_names,
515 .digital_names = &scope_digital_channel_names,
516
4b25cbff
UH
517 .devopts = &devopts,
518 .num_devopts = ARRAY_SIZE(devopts),
74413faf 519
6b82c3e5
UH
520 .devopts_cg_analog = &devopts_cg_analog,
521 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
74413faf 522
e131be0a
GT
523 .devopts_cg_digital = &devopts_cg_digital,
524 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
525
4b25cbff 526 .coupling_options = &coupling_options,
692716f5
UH
527 .num_coupling_options = ARRAY_SIZE(coupling_options),
528
e131be0a
GT
529 .logic_threshold = &logic_threshold,
530 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
aac30633 531 .logic_threshold_for_pod = TRUE,
e131be0a 532
6d0f3508
GT
533 .trigger_sources = &an4_dig16_trigger_sources,
534 .num_trigger_sources = ARRAY_SIZE(an4_dig16_trigger_sources),
692716f5 535
74413faf 536 .trigger_slopes = &scope_trigger_slopes,
692716f5 537 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
74413faf 538
4b25cbff
UH
539 .timebases = &timebases,
540 .num_timebases = ARRAY_SIZE(timebases),
74413faf 541
4b25cbff
UH
542 .vdivs = &vdivs,
543 .num_vdivs = ARRAY_SIZE(vdivs),
74413faf 544
74413faf
GS
545 .num_ydivs = 8,
546
13f2b9d7
DJ
547 .scpi_dialect = &hameg_scpi_dialect,
548 },
aac30633
GT
549 {
550 .name = {"RTB2002", NULL},
551 .analog_channels = 2,
552 .digital_channels = 16,
aac30633
GT
553
554 .analog_names = &scope_analog_channel_names,
555 .digital_names = &scope_digital_channel_names,
556
557 .devopts = &devopts,
558 .num_devopts = ARRAY_SIZE(devopts),
559
560 .devopts_cg_analog = &devopts_cg_analog,
561 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
562
563 .devopts_cg_digital = &devopts_cg_digital,
564 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
565
566 .coupling_options = &coupling_options_rtb200x,
567 .num_coupling_options = ARRAY_SIZE(coupling_options_rtb200x),
568
569 .logic_threshold = &logic_threshold_rtb200x_rtm300x,
570 .num_logic_threshold = ARRAY_SIZE(logic_threshold_rtb200x_rtm300x),
571 .logic_threshold_for_pod = FALSE,
572
573 .trigger_sources = &an2_dig16_sbus_trigger_sources,
574 .num_trigger_sources = ARRAY_SIZE(an2_dig16_sbus_trigger_sources),
575
576 .trigger_slopes = &scope_trigger_slopes,
577 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
578
579 .timebases = &timebases,
580 .num_timebases = ARRAY_SIZE(timebases),
581
582 .vdivs = &vdivs,
583 .num_vdivs = ARRAY_SIZE(vdivs),
584
aac30633
GT
585 .num_ydivs = 8,
586
587 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
588 },
589 {
590 .name = {"RTB2004", NULL},
591 .analog_channels = 4,
592 .digital_channels = 16,
aac30633
GT
593
594 .analog_names = &scope_analog_channel_names,
595 .digital_names = &scope_digital_channel_names,
596
597 .devopts = &devopts,
598 .num_devopts = ARRAY_SIZE(devopts),
599
600 .devopts_cg_analog = &devopts_cg_analog,
601 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
602
603 .devopts_cg_digital = &devopts_cg_digital,
604 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
605
606 .coupling_options = &coupling_options_rtb200x,
607 .num_coupling_options = ARRAY_SIZE(coupling_options_rtb200x),
608
609 .logic_threshold = &logic_threshold_rtb200x_rtm300x,
610 .num_logic_threshold = ARRAY_SIZE(logic_threshold_rtb200x_rtm300x),
611 .logic_threshold_for_pod = FALSE,
612
613 .trigger_sources = &an4_dig16_sbus_trigger_sources,
614 .num_trigger_sources = ARRAY_SIZE(an4_dig16_sbus_trigger_sources),
615
616 .trigger_slopes = &scope_trigger_slopes,
617 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
618
619 .timebases = &timebases,
620 .num_timebases = ARRAY_SIZE(timebases),
621
622 .vdivs = &vdivs,
623 .num_vdivs = ARRAY_SIZE(vdivs),
624
aac30633
GT
625 .num_ydivs = 8,
626
627 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
628 },
629 {
630 .name = {"RTM3002", NULL},
631 .analog_channels = 2,
632 .digital_channels = 16,
aac30633
GT
633
634 .analog_names = &scope_analog_channel_names,
635 .digital_names = &scope_digital_channel_names,
636
637 .devopts = &devopts,
638 .num_devopts = ARRAY_SIZE(devopts),
639
640 .devopts_cg_analog = &devopts_cg_analog,
641 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
642
643 .devopts_cg_digital = &devopts_cg_digital,
644 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
645
646 .coupling_options = &coupling_options_rtm300x,
647 .num_coupling_options = ARRAY_SIZE(coupling_options_rtm300x),
648
649 .logic_threshold = &logic_threshold_rtb200x_rtm300x,
650 .num_logic_threshold = ARRAY_SIZE(logic_threshold_rtb200x_rtm300x),
651 .logic_threshold_for_pod = FALSE,
652
653 .trigger_sources = &an2_dig16_sbus_trigger_sources,
654 .num_trigger_sources = ARRAY_SIZE(an2_dig16_sbus_trigger_sources),
655
656 .trigger_slopes = &scope_trigger_slopes,
657 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
658
659 .timebases = &timebases,
660 .num_timebases = ARRAY_SIZE(timebases),
661
662 .vdivs = &vdivs,
663 .num_vdivs = ARRAY_SIZE(vdivs),
664
aac30633
GT
665 .num_ydivs = 8,
666
667 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
668 },
669 {
670 .name = {"RTM3004", NULL},
671 .analog_channels = 4,
672 .digital_channels = 16,
aac30633
GT
673
674 .analog_names = &scope_analog_channel_names,
675 .digital_names = &scope_digital_channel_names,
676
677 .devopts = &devopts,
678 .num_devopts = ARRAY_SIZE(devopts),
679
680 .devopts_cg_analog = &devopts_cg_analog,
681 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
682
683 .devopts_cg_digital = &devopts_cg_digital,
684 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
685
686 .coupling_options = &coupling_options_rtm300x,
687 .num_coupling_options = ARRAY_SIZE(coupling_options_rtm300x),
b720f16e
GT
688
689 .logic_threshold = &logic_threshold_rtb200x_rtm300x,
690 .num_logic_threshold = ARRAY_SIZE(logic_threshold_rtb200x_rtm300x),
691 .logic_threshold_for_pod = FALSE,
692
693 .trigger_sources = &an4_dig16_sbus_trigger_sources,
694 .num_trigger_sources = ARRAY_SIZE(an4_dig16_sbus_trigger_sources),
695
696 .trigger_slopes = &scope_trigger_slopes,
697 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
698
699 .timebases = &timebases,
700 .num_timebases = ARRAY_SIZE(timebases),
701
702 .vdivs = &vdivs,
703 .num_vdivs = ARRAY_SIZE(vdivs),
704
b720f16e
GT
705 .num_ydivs = 8,
706
707 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
708 },
709 {
710 .name = {"RTA4004", NULL},
711 .analog_channels = 4,
712 .digital_channels = 16,
b720f16e
GT
713
714 .analog_names = &scope_analog_channel_names,
715 .digital_names = &scope_digital_channel_names,
716
717 .devopts = &devopts,
718 .num_devopts = ARRAY_SIZE(devopts),
719
720 .devopts_cg_analog = &devopts_cg_analog,
721 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
722
723 .devopts_cg_digital = &devopts_cg_digital,
724 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
725
726 .coupling_options = &coupling_options_rtm300x,
727 .num_coupling_options = ARRAY_SIZE(coupling_options_rtm300x),
aac30633
GT
728
729 .logic_threshold = &logic_threshold_rtb200x_rtm300x,
730 .num_logic_threshold = ARRAY_SIZE(logic_threshold_rtb200x_rtm300x),
731 .logic_threshold_for_pod = FALSE,
732
733 .trigger_sources = &an4_dig16_sbus_trigger_sources,
734 .num_trigger_sources = ARRAY_SIZE(an4_dig16_sbus_trigger_sources),
735
736 .trigger_slopes = &scope_trigger_slopes,
737 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
738
739 .timebases = &timebases,
740 .num_timebases = ARRAY_SIZE(timebases),
741
742 .vdivs = &vdivs,
743 .num_vdivs = ARRAY_SIZE(vdivs),
744
aac30633
GT
745 .num_ydivs = 8,
746
747 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
748 },
13f2b9d7
DJ
749};
750
329733d9 751static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
752 struct scope_state *state)
753{
754 unsigned int i;
8de2dc3b 755 char *tmp;
13f2b9d7 756
0a1f7b09 757 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
758 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
759 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
d9251a2c 760 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 761 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 762 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 763 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
764 }
765
0a1f7b09 766 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
767 sr_info("State of digital channel %d -> %s", i,
768 state->digital_channels[i] ? "On" : "Off");
769 }
770
0a1f7b09 771 for (i = 0; i < config->digital_pods; i++) {
aac30633
GT
772 if (!strncmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold], 4) ||
773 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
262061ff 774 sr_info("State of digital POD %d -> %s : %E (threshold)", i + 1,
e131be0a
GT
775 state->digital_pods[i].state ? "On" : "Off",
776 state->digital_pods[i].user_threshold);
aac30633
GT
777 else
778 sr_info("State of digital POD %d -> %s : %s (threshold)", i + 1,
779 state->digital_pods[i].state ? "On" : "Off",
780 (*config->logic_threshold)[state->digital_pods[i].threshold]);
13f2b9d7
DJ
781 }
782
6984cfb2
SA
783 tmp = sr_period_string((*config->timebases)[state->timebase][0],
784 (*config->timebases)[state->timebase][1]);
8de2dc3b
DJ
785 sr_info("Current timebase: %s", tmp);
786 g_free(tmp);
787
14a2f74d
DJ
788 tmp = sr_samplerate_string(state->sample_rate);
789 sr_info("Current samplerate: %s", tmp);
790 g_free(tmp);
791
4fa4db2c
GT
792 if (!strcmp("PATT", (*config->trigger_sources)[state->trigger_source]))
793 sr_info("Current trigger: %s (pattern), %.2f (offset)",
794 state->trigger_pattern,
795 state->horiz_triggerpos);
796 else // Edge (slope) trigger
797 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
798 (*config->trigger_sources)[state->trigger_source],
799 (*config->trigger_slopes)[state->trigger_slope],
800 state->horiz_triggerpos);
13f2b9d7
DJ
801}
802
23f43dff 803static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
692716f5 804 const char *command, const char *(*array)[], unsigned int n, int *result)
13f2b9d7
DJ
805{
806 char *tmp;
bd633efa 807 int idx;
13f2b9d7 808
67398969 809 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK)
13f2b9d7 810 return SR_ERR;
13f2b9d7 811
bd633efa 812 if ((idx = std_str_idx_s(tmp, *array, n)) < 0) {
13f2b9d7 813 g_free(tmp);
bd633efa 814 return SR_ERR_ARG;
13f2b9d7
DJ
815 }
816
bd633efa
UH
817 *result = idx;
818
819 g_free(tmp);
820
13f2b9d7
DJ
821 return SR_OK;
822}
823
8fff7519 824/**
a53acd7d
SB
825 * This function takes a value of the form "2.000E-03" and returns the index
826 * of an array where a matching pair was found.
8fff7519
SA
827 *
828 * @param value The string to be parsed.
829 * @param array The array of s/f pairs.
830 * @param array_len The number of pairs in the array.
831 * @param result The index at which a matching pair was found.
832 *
833 * @return SR_ERR on any parsing error, SR_OK otherwise.
834 */
835static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 836 int array_len, unsigned int *result)
8fff7519 837{
a53acd7d
SB
838 struct sr_rational rval;
839 struct sr_rational aval;
8cccbac8 840
a53acd7d 841 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
842 return SR_ERR;
843
a53acd7d
SB
844 for (int i = 0; i < array_len; i++) {
845 sr_rational_set(&aval, array[i][0], array[i][1]);
846 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
847 *result = i;
848 return SR_OK;
849 }
850 }
851
852 return SR_ERR;
853}
854
bd70ec4b
SB
855static struct sr_channel *get_channel_by_index_and_type(GSList *channel_lhead,
856 int index, int type)
857{
858 while (channel_lhead) {
859 struct sr_channel *ch = channel_lhead->data;
860 if (ch->index == index && ch->type == type)
861 return ch;
862
863 channel_lhead = channel_lhead->next;
864 }
865
866 return 0;
867}
868
869static int analog_channel_state_get(struct sr_dev_inst *sdi,
329733d9 870 const struct scope_config *config,
13f2b9d7
DJ
871 struct scope_state *state)
872{
8de2dc3b 873 unsigned int i, j;
13f2b9d7 874 char command[MAX_COMMAND_SIZE];
8fff7519 875 char *tmp_str;
bd70ec4b
SB
876 struct sr_channel *ch;
877 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 878
0a1f7b09 879 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
880 g_snprintf(command, sizeof(command),
881 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
882 i + 1);
883
23f43dff 884 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
885 &state->analog_channels[i].state) != SR_OK)
886 return SR_ERR;
887
bd70ec4b
SB
888 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_ANALOG);
889 if (ch)
890 ch->enabled = state->analog_channels[i].state;
891
13f2b9d7 892 g_snprintf(command, sizeof(command),
66ddc22a 893 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_SCALE],
13f2b9d7
DJ
894 i + 1);
895
8fff7519 896 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 897 return SR_ERR;
8fff7519 898
53012da6 899 if (array_float_get(tmp_str, ARRAY_AND_SIZE(vdivs), &j) != SR_OK) {
8fff7519 900 g_free(tmp_str);
b4e31d2a 901 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 902 return SR_ERR;
b4e31d2a 903 }
13f2b9d7 904
8fff7519
SA
905 g_free(tmp_str);
906 state->analog_channels[i].vdiv = j;
907
13f2b9d7
DJ
908 g_snprintf(command, sizeof(command),
909 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
910 i + 1);
911
23f43dff 912 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
913 &state->analog_channels[i].vertical_offset) != SR_OK)
914 return SR_ERR;
915
916 g_snprintf(command, sizeof(command),
917 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
918 i + 1);
919
23f43dff 920 if (scope_state_get_array_option(scpi, command, config->coupling_options,
692716f5 921 config->num_coupling_options,
13f2b9d7
DJ
922 &state->analog_channels[i].coupling) != SR_OK)
923 return SR_ERR;
448e81b1
SB
924
925 g_snprintf(command, sizeof(command),
926 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
927 i + 1);
928
929 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
930 return SR_ERR;
931
932 if (tmp_str[0] == 'A')
933 state->analog_channels[i].probe_unit = 'A';
934 else
935 state->analog_channels[i].probe_unit = 'V';
936 g_free(tmp_str);
13f2b9d7
DJ
937 }
938
939 return SR_OK;
940}
941
bd70ec4b 942static int digital_channel_state_get(struct sr_dev_inst *sdi,
329733d9 943 const struct scope_config *config,
13f2b9d7
DJ
944 struct scope_state *state)
945{
aac30633 946 unsigned int i, idx;
e131be0a 947 int result = SR_ERR;
c38d69ad 948 char *logic_threshold_short[MAX_NUM_LOGIC_THRESHOLD_ENTRIES];
13f2b9d7 949 char command[MAX_COMMAND_SIZE];
bd70ec4b
SB
950 struct sr_channel *ch;
951 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 952
0a1f7b09 953 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
954 g_snprintf(command, sizeof(command),
955 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
956 i);
957
23f43dff 958 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
959 &state->digital_channels[i]) != SR_OK)
960 return SR_ERR;
bd70ec4b
SB
961
962 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_LOGIC);
963 if (ch)
964 ch->enabled = state->digital_channels[i];
13f2b9d7
DJ
965 }
966
aac30633
GT
967 /* According to the SCPI standard, on models that support multiple
968 * user-defined logic threshold settings the response to the command
e131be0a
GT
969 * SCPI_CMD_GET_DIG_POD_THRESHOLD might return "USER" instead of
970 * "USER1".
971 *
972 * This makes more difficult to validate the response when the logic
973 * threshold is set to "USER1" and therefore we need to prevent device
974 * opening failures in such configuration case...
975 */
976 for (i = 0; i < config->num_logic_threshold; i++) {
977 logic_threshold_short[i] = g_strdup((*config->logic_threshold)[i]);
978 if (!strcmp("USER1", (*config->logic_threshold)[i]))
979 g_strlcpy(logic_threshold_short[i],
980 (*config->logic_threshold)[i], strlen((*config->logic_threshold)[i]));
981 }
982
0a1f7b09 983 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
984 g_snprintf(command, sizeof(command),
985 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
986 i + 1);
987
23f43dff 988 if (sr_scpi_get_bool(scpi, command,
e131be0a
GT
989 &state->digital_pods[i].state) != SR_OK)
990 goto exit;
991
aac30633
GT
992 /* Check if the threshold command is based on the POD or digital channel index. */
993 if (config->logic_threshold_for_pod)
994 idx = i + 1;
995 else
a12456f1 996 idx = i * DIGITAL_CHANNELS_PER_POD;
aac30633 997
e131be0a
GT
998 g_snprintf(command, sizeof(command),
999 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_THRESHOLD],
aac30633 1000 idx);
e131be0a
GT
1001
1002 /* Check for both standard and shortened responses. */
1003 if (scope_state_get_array_option(scpi, command, config->logic_threshold,
1004 config->num_logic_threshold,
1005 &state->digital_pods[i].threshold) != SR_OK)
1006 if (scope_state_get_array_option(scpi, command, (const char * (*)[]) &logic_threshold_short,
1007 config->num_logic_threshold,
1008 &state->digital_pods[i].threshold) != SR_OK)
1009 goto exit;
1010
aac30633 1011 /* If used-defined or custom threshold is active, get the level. */
e131be0a
GT
1012 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]))
1013 g_snprintf(command, sizeof(command),
1014 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
aac30633
GT
1015 idx, 1); /* USER1 logic threshold setting. */
1016 else if (!strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
e131be0a
GT
1017 g_snprintf(command, sizeof(command),
1018 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
aac30633
GT
1019 idx, 2); /* USER2 for custom logic_threshold setting. */
1020 else if (!strcmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1021 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
1022 g_snprintf(command, sizeof(command),
1023 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
1024 idx); /* USER or MAN for custom logic_threshold setting. */
e131be0a 1025 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
aac30633
GT
1026 !strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1027 !strcmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1028 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
e131be0a
GT
1029 if (sr_scpi_get_float(scpi, command,
1030 &state->digital_pods[i].user_threshold) != SR_OK)
1031 goto exit;
13f2b9d7
DJ
1032 }
1033
e131be0a
GT
1034 result = SR_OK;
1035
1036exit:
1037 for (i = 0; i < config->num_logic_threshold; i++)
1038 g_free(logic_threshold_short[i]);
1039
1040 return result;
13f2b9d7
DJ
1041}
1042
14a2f74d
DJ
1043SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
1044{
1045 struct dev_context *devc;
1046 struct scope_state *state;
329733d9 1047 const struct scope_config *config;
14a2f74d 1048 float tmp_float;
14a2f74d
DJ
1049
1050 devc = sdi->priv;
1051 config = devc->model_config;
1052 state = devc->model_state;
14a2f74d 1053
39e19723
GT
1054 if (sr_scpi_get_float(sdi->conn,
1055 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
1056 &tmp_float) != SR_OK)
1057 return SR_ERR;
c06c24d2 1058
39e19723 1059 state->sample_rate = tmp_float;
14a2f74d
DJ
1060
1061 return SR_OK;
1062}
1063
719eff68 1064SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
1065{
1066 struct dev_context *devc;
1067 struct scope_state *state;
329733d9 1068 const struct scope_config *config;
8de2dc3b
DJ
1069 float tmp_float;
1070 unsigned int i;
8cccbac8 1071 char *tmp_str;
13f2b9d7
DJ
1072
1073 devc = sdi->priv;
1074 config = devc->model_config;
1075 state = devc->model_state;
1076
8de2dc3b
DJ
1077 sr_info("Fetching scope state");
1078
bd70ec4b 1079 if (analog_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
1080 return SR_ERR;
1081
bd70ec4b 1082 if (digital_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
1083 return SR_ERR;
1084
8cccbac8
SA
1085 if (sr_scpi_get_string(sdi->conn,
1086 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
1087 &tmp_str) != SR_OK)
1088 return SR_ERR;
1089
53012da6 1090 if (array_float_get(tmp_str, ARRAY_AND_SIZE(timebases), &i) != SR_OK) {
8cccbac8 1091 g_free(tmp_str);
b4e31d2a 1092 sr_err("Could not determine array index for time base.");
13f2b9d7 1093 return SR_ERR;
b4e31d2a 1094 }
e5b7eef7 1095 g_free(tmp_str);
13f2b9d7 1096
8cccbac8
SA
1097 state->timebase = i;
1098
29a9b1a0
GT
1099 /* Determine the number of horizontal (x) divisions. */
1100 if (sr_scpi_get_int(sdi->conn,
1101 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZONTAL_DIV],
1102 (int *)&config->num_xdivs) != SR_OK)
1103 return SR_ERR;
1104
89280b1a
UH
1105 if (sr_scpi_get_float(sdi->conn,
1106 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 1107 &tmp_float) != SR_OK)
13f2b9d7 1108 return SR_ERR;
422a1c0d
DJ
1109 state->horiz_triggerpos = tmp_float /
1110 (((double) (*config->timebases)[state->timebase][0] /
1111 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
1112 state->horiz_triggerpos -= 0.5;
1113 state->horiz_triggerpos *= -1;
13f2b9d7 1114
89280b1a
UH
1115 if (scope_state_get_array_option(sdi->conn,
1116 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
692716f5
UH
1117 config->trigger_sources, config->num_trigger_sources,
1118 &state->trigger_source) != SR_OK)
13f2b9d7
DJ
1119 return SR_ERR;
1120
89280b1a 1121 if (scope_state_get_array_option(sdi->conn,
692716f5
UH
1122 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
1123 config->trigger_slopes, config->num_trigger_slopes,
1124 &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
1125 return SR_ERR;
1126
4fa4db2c
GT
1127 if (sr_scpi_get_string(sdi->conn,
1128 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_PATTERN],
396af5ad 1129 &tmp_str) != SR_OK)
4fa4db2c 1130 return SR_ERR;
396af5ad
GT
1131 strncpy(state->trigger_pattern,
1132 sr_scpi_unquote_string(tmp_str),
1133 MAX_ANALOG_CHANNEL_COUNT + MAX_DIGITAL_CHANNEL_COUNT);
1134 g_free(tmp_str);
4fa4db2c 1135
97a00074
GT
1136 if (sr_scpi_get_string(sdi->conn,
1137 (*config->scpi_dialect)[SCPI_CMD_GET_HIGH_RESOLUTION],
1138 &tmp_str) != SR_OK)
1139 return SR_ERR;
1140 if (!strcmp("OFF", tmp_str))
1141 state->high_resolution = FALSE;
1142 else
1143 state->high_resolution = TRUE;
1144 g_free(tmp_str);
1145
1146 if (sr_scpi_get_string(sdi->conn,
1147 (*config->scpi_dialect)[SCPI_CMD_GET_PEAK_DETECTION],
1148 &tmp_str) != SR_OK)
1149 return SR_ERR;
1150 if (!strcmp("OFF", tmp_str))
1151 state->peak_detection = FALSE;
1152 else
1153 state->peak_detection = TRUE;
1154 g_free(tmp_str);
1155
14a2f74d
DJ
1156 if (hmo_update_sample_rate(sdi) != SR_OK)
1157 return SR_ERR;
1158
8de2dc3b
DJ
1159 sr_info("Fetching finished.");
1160
13f2b9d7
DJ
1161 scope_state_dump(config, state);
1162
1163 return SR_OK;
1164}
1165
329733d9 1166static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
1167{
1168 struct scope_state *state;
1169
a95f142e
UH
1170 state = g_malloc0(sizeof(struct scope_state));
1171 state->analog_channels = g_malloc0_n(config->analog_channels,
1172 sizeof(struct analog_channel_state));
1173 state->digital_channels = g_malloc0_n(
1174 config->digital_channels, sizeof(gboolean));
1175 state->digital_pods = g_malloc0_n(config->digital_pods,
e131be0a 1176 sizeof(struct digital_pod_state));
13f2b9d7
DJ
1177
1178 return state;
13f2b9d7
DJ
1179}
1180
719eff68 1181SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
1182{
1183 g_free(state->analog_channels);
1184 g_free(state->digital_channels);
1185 g_free(state->digital_pods);
1186 g_free(state);
1187}
1188
1189SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
1190{
13f2b9d7 1191 int model_index;
2d224dba 1192 unsigned int i, j, group;
ba7dd8bb 1193 struct sr_channel *ch;
13f2b9d7 1194 struct dev_context *devc;
eac9fcd2 1195 int ret;
13f2b9d7
DJ
1196
1197 devc = sdi->priv;
1198 model_index = -1;
1199
89280b1a 1200 /* Find the exact model. */
13f2b9d7
DJ
1201 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
1202 for (j = 0; scope_models[i].name[j]; j++) {
1203 if (!strcmp(sdi->model, scope_models[i].name[j])) {
1204 model_index = i;
1205 break;
1206 }
1207 }
1208 if (model_index != -1)
1209 break;
1210 }
1211
1212 if (model_index == -1) {
e35ebc6a 1213 sr_dbg("Unsupported device.");
13f2b9d7
DJ
1214 return SR_ERR_NA;
1215 }
29a9b1a0 1216
a12456f1
GT
1217 /* Configure the number of PODs given the number of digital channels. */
1218 scope_models[model_index].digital_pods = scope_models[model_index].digital_channels / DIGITAL_CHANNELS_PER_POD;
13f2b9d7 1219
562b7ae5
SA
1220 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1221 scope_models[model_index].analog_channels);
562b7ae5
SA
1222 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1223 scope_models[model_index].digital_pods);
b0e80e9a
GS
1224 if (!devc->analog_groups || !devc->digital_groups) {
1225 g_free(devc->analog_groups);
1226 g_free(devc->digital_groups);
1227 return SR_ERR_MALLOC;
1228 }
13f2b9d7 1229
89280b1a 1230 /* Add analog channels. */
13f2b9d7 1231 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 1232 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 1233 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 1234
562b7ae5
SA
1235 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
1236
1237 devc->analog_groups[i]->name = g_strdup(
1238 (char *)(*scope_models[model_index].analog_names)[i]);
1239 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 1240
660e398f 1241 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 1242 devc->analog_groups[i]);
13f2b9d7
DJ
1243 }
1244
660e398f 1245 /* Add digital channel groups. */
eac9fcd2 1246 ret = SR_OK;
0a1f7b09 1247 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
562b7ae5 1248 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
eac9fcd2
GS
1249 if (!devc->digital_groups[i]) {
1250 ret = SR_ERR_MALLOC;
1251 break;
1252 }
262061ff 1253 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i + 1);
660e398f 1254 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 1255 devc->digital_groups[i]);
13f2b9d7 1256 }
eac9fcd2
GS
1257 if (ret != SR_OK)
1258 return ret;
13f2b9d7 1259
89280b1a 1260 /* Add digital channels. */
13f2b9d7 1261 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 1262 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 1263 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 1264
a12456f1 1265 group = i / DIGITAL_CHANNELS_PER_POD;
2d224dba
GS
1266 devc->digital_groups[group]->channels = g_slist_append(
1267 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
1268 }
1269
1270 devc->model_config = &scope_models[model_index];
d779dcac 1271 devc->samples_limit = 0;
13f2b9d7
DJ
1272 devc->frame_limit = 0;
1273
1274 if (!(devc->model_state = scope_state_new(devc->model_config)))
1275 return SR_ERR_MALLOC;
1276
1277 return SR_OK;
1278}
1279
e06875b2
GS
1280/* Queue data of one channel group, for later submission. */
1281SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
1282 size_t group, GByteArray *pod_data)
1283{
1284 size_t size;
1285 GByteArray *store;
1286 uint8_t *logic_data;
1287 size_t idx, logic_step;
1288
1289 /*
1290 * Upon first invocation, allocate the array which can hold the
1291 * combined logic data for all channels. Assume that each channel
1292 * will yield an identical number of samples per receive call.
1293 *
1294 * As a poor man's safety measure: (Silently) skip processing
1295 * for unexpected sample counts, and ignore samples for
1296 * unexpected channel groups. Don't bother with complicated
1297 * resize logic, considering that many models only support one
1298 * pod, and the most capable supported models have two pods of
1299 * identical size. We haven't yet seen any "odd" configuration.
1300 */
1301 if (!devc->logic_data) {
1302 size = pod_data->len * devc->pod_count;
1303 store = g_byte_array_sized_new(size);
1304 memset(store->data, 0, size);
1305 store = g_byte_array_set_size(store, size);
1306 devc->logic_data = store;
1307 } else {
1308 store = devc->logic_data;
1309 size = store->len / devc->pod_count;
e06875b2
GS
1310 if (group >= devc->pod_count)
1311 return;
1312 }
1313
1314 /*
1315 * Fold the data of the most recently received channel group into
1316 * the storage, where data resides for all channels combined.
1317 */
1318 logic_data = store->data;
1319 logic_data += group;
1320 logic_step = devc->pod_count;
1321 for (idx = 0; idx < pod_data->len; idx++) {
1322 *logic_data = pod_data->data[idx];
1323 logic_data += logic_step;
1324 }
d779dcac
GT
1325
1326 /* Truncate acquisition if a smaller number of samples has been requested. */
1327 if (devc->samples_limit > 0 && devc->logic_data->len > devc->samples_limit * devc->pod_count)
1328 devc->logic_data->len = devc->samples_limit * devc->pod_count;
e06875b2
GS
1329}
1330
1331/* Submit data for all channels, after the individual groups got collected. */
1332SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
1333 struct dev_context *devc)
1334{
1335 struct sr_datafeed_packet packet;
1336 struct sr_datafeed_logic logic;
1337
1338 if (!devc->logic_data)
1339 return;
1340
1341 logic.data = devc->logic_data->data;
1342 logic.length = devc->logic_data->len;
1343 logic.unitsize = devc->pod_count;
1344
1345 packet.type = SR_DF_LOGIC;
1346 packet.payload = &logic;
1347
1348 sr_session_send(sdi, &packet);
1349}
1350
1351/* Undo previous resource allocation. */
1352SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
1353{
1354
1355 if (devc->logic_data) {
1356 g_byte_array_free(devc->logic_data, TRUE);
1357 devc->logic_data = NULL;
1358 }
1359 /*
1360 * Keep 'pod_count'! It's required when more frames will be
1361 * received, and does not harm when kept after acquisition.
1362 */
1363}
1364
719eff68 1365SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 1366{
ba7dd8bb 1367 struct sr_channel *ch;
13f2b9d7 1368 struct sr_dev_inst *sdi;
06a3e78a 1369 struct dev_context *devc;
401b83a1 1370 struct scope_state *state;
13f2b9d7 1371 struct sr_datafeed_packet packet;
401b83a1
SB
1372 GByteArray *data;
1373 struct sr_datafeed_analog analog;
1374 struct sr_analog_encoding encoding;
1375 struct sr_analog_meaning meaning;
1376 struct sr_analog_spec spec;
89280b1a 1377 struct sr_datafeed_logic logic;
e06875b2 1378 size_t group;
06a3e78a
DJ
1379
1380 (void)fd;
f0729866 1381 (void)revents;
06a3e78a
DJ
1382
1383 if (!(sdi = cb_data))
1384 return TRUE;
1385
1386 if (!(devc = sdi->priv))
1387 return TRUE;
1388
f4f273ce
SB
1389 /* Although this is correct in general, the USBTMC libusb implementation
1390 * currently does not generate an event prior to the first read. Often
1391 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
1392 if (revents != G_IO_IN)
1393 return TRUE;
f4f273ce 1394 */
13f2b9d7 1395
dc89faea 1396 ch = devc->current_channel->data;
401b83a1 1397 state = devc->model_state;
13f2b9d7 1398
b23eb1d4
GS
1399 /*
1400 * Send "frame begin" packet upon reception of data for the
1401 * first enabled channel.
1402 */
4c5f7006
UH
1403 if (devc->current_channel == devc->enabled_channels)
1404 std_session_send_df_frame_begin(sdi);
b23eb1d4
GS
1405
1406 /*
1407 * Pass on the received data of the channel(s).
1408 */
dc89faea
UH
1409 switch (ch->type) {
1410 case SR_CHANNEL_ANALOG:
4da62209 1411 data = NULL;
401b83a1 1412 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 1413 if (data)
401b83a1 1414 g_byte_array_free(data, TRUE);
dc89faea 1415 return TRUE;
13f2b9d7
DJ
1416 }
1417
401b83a1
SB
1418 packet.type = SR_DF_ANALOG;
1419
1420 analog.data = data->data;
1421 analog.num_samples = data->len / sizeof(float);
d779dcac
GT
1422 /* Truncate acquisition if a smaller number of samples has been requested. */
1423 if (devc->samples_limit > 0 && analog.num_samples > devc->samples_limit)
1424 analog.num_samples = devc->samples_limit;
7dcaddd3 1425 /* TODO: Use proper 'digits' value for this device (and its modes). */
8c381a35
GS
1426 sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
1427 encoding.is_signed = TRUE;
401b83a1
SB
1428 if (state->analog_channels[ch->index].probe_unit == 'V') {
1429 meaning.mq = SR_MQ_VOLTAGE;
1430 meaning.unit = SR_UNIT_VOLT;
1431 } else {
1432 meaning.mq = SR_MQ_CURRENT;
1433 meaning.unit = SR_UNIT_AMPERE;
1434 }
401b83a1 1435 meaning.channels = g_slist_append(NULL, ch);
dc89faea 1436 packet.payload = &analog;
695dc859 1437 sr_session_send(sdi, &packet);
d779dcac 1438 devc->num_samples = data->len / sizeof(float);
401b83a1
SB
1439 g_slist_free(meaning.channels);
1440 g_byte_array_free(data, TRUE);
dc89faea
UH
1441 data = NULL;
1442 break;
1443 case SR_CHANNEL_LOGIC:
4da62209 1444 data = NULL;
401b83a1 1445 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
14cb6aa4
GT
1446 if (data)
1447 g_byte_array_free(data, TRUE);
dc89faea 1448 return TRUE;
13f2b9d7 1449 }
dc89faea 1450
e06875b2
GS
1451 /*
1452 * If only data from the first pod is involved in the
1453 * acquisition, then the raw input bytes can get passed
1454 * forward for performance reasons. When the second pod
1455 * is involved (either alone, or in combination with the
1456 * first pod), then the received bytes need to be put
1457 * into memory in such a layout that all channel groups
1458 * get combined, and a unitsize larger than a single byte
1459 * applies. The "queue" logic transparently copes with
1460 * any such configuration. This works around the lack
1461 * of support for "meaning" to logic data, which is used
1462 * above for analog data.
1463 */
1464 if (devc->pod_count == 1) {
1465 packet.type = SR_DF_LOGIC;
1466 logic.data = data->data;
1467 logic.length = data->len;
d779dcac
GT
1468 /* Truncate acquisition if a smaller number of samples has been requested. */
1469 if (devc->samples_limit > 0 && logic.length > devc->samples_limit)
1470 logic.length = devc->samples_limit;
e06875b2
GS
1471 logic.unitsize = 1;
1472 packet.payload = &logic;
1473 sr_session_send(sdi, &packet);
1474 } else {
a12456f1 1475 group = ch->index / DIGITAL_CHANNELS_PER_POD;
e06875b2
GS
1476 hmo_queue_logic_data(devc, group, data);
1477 }
dc89faea 1478
d779dcac 1479 devc->num_samples = data->len / devc->pod_count;
401b83a1 1480 g_byte_array_free(data, TRUE);
dc89faea
UH
1481 data = NULL;
1482 break;
1483 default:
1484 sr_err("Invalid channel type.");
1485 break;
1486 }
1487
b23eb1d4
GS
1488 /*
1489 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
1490 * channels was received, then flush potentially queued logic data,
1491 * and send the "frame end" packet.
b23eb1d4 1492 */
dc89faea
UH
1493 if (devc->current_channel->next) {
1494 devc->current_channel = devc->current_channel->next;
1495 hmo_request_data(sdi);
b23eb1d4
GS
1496 return TRUE;
1497 }
e06875b2
GS
1498 hmo_send_logic_packet(sdi, devc);
1499
1500 /*
1501 * Release the logic data storage after each frame. This copes
1502 * with sample counts that differ in length per frame. -- Is
1503 * this a real constraint when acquiring multiple frames with
1504 * identical device settings?
1505 */
1506 hmo_cleanup_logic_data(devc);
1507
4c5f7006 1508 std_session_send_df_frame_end(sdi);
b23eb1d4
GS
1509
1510 /*
1511 * End of frame was reached. Stop acquisition after the specified
d779dcac
GT
1512 * number of frames or after the specified number of samples, or
1513 * continue reception by starting over at the first enabled channel.
b23eb1d4 1514 */
d779dcac 1515 if (++devc->num_frames >= devc->frame_limit || devc->num_samples >= devc->samples_limit) {
d2f7c417 1516 sr_dev_acquisition_stop(sdi);
e06875b2 1517 hmo_cleanup_logic_data(devc);
dc89faea
UH
1518 } else {
1519 devc->current_channel = devc->enabled_channels;
1520 hmo_request_data(sdi);
06a3e78a
DJ
1521 }
1522
1523 return TRUE;
1524}