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