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