]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
rdtech-dps: Prevent null pointer exception
[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
4cf90b86 223/* HMO Compact4 */
6d0f3508 224static const char *an4_dig8_trigger_sources[] = {
f8195cb2
UH
225 "CH1", "CH2", "CH3", "CH4",
226 "LINE", "EXT", "PATT", "BUS1", "BUS2",
227 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
228};
229
4cf90b86 230/* HMO3xx4 and HMO2524 */
6d0f3508 231static const char *an4_dig16_trigger_sources[] = {
f8195cb2
UH
232 "CH1", "CH2", "CH3", "CH4",
233 "LINE", "EXT", "PATT", "BUS1", "BUS2",
234 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
235 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
74413faf
GS
236};
237
b720f16e 238/* RTB2004, RTM3004 and RTA4004 */
aac30633
GT
239static const char *an4_dig16_sbus_trigger_sources[] = {
240 "CH1", "CH2", "CH3", "CH4",
241 "LINE", "EXT", "PATT", "SBUS1", "SBUS2",
242 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
243 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
244};
245
10e6dfd1 246/* RTH1004 */
247static const char *an4_dig8_isol_trigger_sources[] = {
248 "CH1", "CH2", "CH3", "CH4",
249 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
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 },
776 /* RTH1002 & RTH1004 are both identified as RTH */
777 {
778 .name = {"RTH", NULL},
779 .analog_channels = 4,
780 .digital_channels = 8,
781
782 .analog_names = &scope_analog_channel_names,
783 .digital_names = &scope_digital_channel_names,
784
785 .devopts = &devopts,
786 .num_devopts = ARRAY_SIZE(devopts),
787
788 .devopts_cg_analog = &devopts_cg_analog,
789 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
790
791 .devopts_cg_digital = &devopts_cg_digital,
792 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
793
794 .coupling_options = &coupling_options_rth100x,
795 .num_coupling_options = ARRAY_SIZE(coupling_options_rth100x),
796
797 .logic_threshold = &logic_threshold,
798 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
799 .logic_threshold_for_pod = TRUE,
800
801 .trigger_sources = &an4_dig8_isol_trigger_sources,
802 .num_trigger_sources = ARRAY_SIZE(an4_dig8_isol_trigger_sources),
803
804 .trigger_slopes = &scope_trigger_slopes,
805 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
806
807 .timebases = &timebases,
808 .num_timebases = ARRAY_SIZE(timebases),
809
810 .vdivs = &vdivs,
811 .num_vdivs = ARRAY_SIZE(vdivs),
812
813 .num_ydivs = 8,
814
aac30633
GT
815 .scpi_dialect = &rohde_schwarz_log_not_pod_scpi_dialect,
816 },
13f2b9d7
DJ
817};
818
329733d9 819static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
820 struct scope_state *state)
821{
822 unsigned int i;
8de2dc3b 823 char *tmp;
13f2b9d7 824
0a1f7b09 825 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
826 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
827 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
d9251a2c 828 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 829 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 830 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 831 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
832 }
833
0a1f7b09 834 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
835 sr_info("State of digital channel %d -> %s", i,
836 state->digital_channels[i] ? "On" : "Off");
837 }
838
0a1f7b09 839 for (i = 0; i < config->digital_pods; i++) {
aac30633
GT
840 if (!strncmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold], 4) ||
841 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
262061ff 842 sr_info("State of digital POD %d -> %s : %E (threshold)", i + 1,
e131be0a
GT
843 state->digital_pods[i].state ? "On" : "Off",
844 state->digital_pods[i].user_threshold);
aac30633
GT
845 else
846 sr_info("State of digital POD %d -> %s : %s (threshold)", i + 1,
847 state->digital_pods[i].state ? "On" : "Off",
848 (*config->logic_threshold)[state->digital_pods[i].threshold]);
13f2b9d7
DJ
849 }
850
6984cfb2
SA
851 tmp = sr_period_string((*config->timebases)[state->timebase][0],
852 (*config->timebases)[state->timebase][1]);
8de2dc3b
DJ
853 sr_info("Current timebase: %s", tmp);
854 g_free(tmp);
855
14a2f74d
DJ
856 tmp = sr_samplerate_string(state->sample_rate);
857 sr_info("Current samplerate: %s", tmp);
858 g_free(tmp);
859
4fa4db2c
GT
860 if (!strcmp("PATT", (*config->trigger_sources)[state->trigger_source]))
861 sr_info("Current trigger: %s (pattern), %.2f (offset)",
862 state->trigger_pattern,
863 state->horiz_triggerpos);
864 else // Edge (slope) trigger
865 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
866 (*config->trigger_sources)[state->trigger_source],
867 (*config->trigger_slopes)[state->trigger_slope],
868 state->horiz_triggerpos);
13f2b9d7
DJ
869}
870
23f43dff 871static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
692716f5 872 const char *command, const char *(*array)[], unsigned int n, int *result)
13f2b9d7
DJ
873{
874 char *tmp;
bd633efa 875 int idx;
13f2b9d7 876
67398969 877 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK)
13f2b9d7 878 return SR_ERR;
13f2b9d7 879
bd633efa 880 if ((idx = std_str_idx_s(tmp, *array, n)) < 0) {
13f2b9d7 881 g_free(tmp);
bd633efa 882 return SR_ERR_ARG;
13f2b9d7
DJ
883 }
884
bd633efa
UH
885 *result = idx;
886
887 g_free(tmp);
888
13f2b9d7
DJ
889 return SR_OK;
890}
891
8fff7519 892/**
a53acd7d
SB
893 * This function takes a value of the form "2.000E-03" and returns the index
894 * of an array where a matching pair was found.
8fff7519
SA
895 *
896 * @param value The string to be parsed.
897 * @param array The array of s/f pairs.
898 * @param array_len The number of pairs in the array.
899 * @param result The index at which a matching pair was found.
900 *
901 * @return SR_ERR on any parsing error, SR_OK otherwise.
902 */
903static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 904 int array_len, unsigned int *result)
8fff7519 905{
a53acd7d
SB
906 struct sr_rational rval;
907 struct sr_rational aval;
8cccbac8 908
a53acd7d 909 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
910 return SR_ERR;
911
a53acd7d
SB
912 for (int i = 0; i < array_len; i++) {
913 sr_rational_set(&aval, array[i][0], array[i][1]);
914 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
915 *result = i;
916 return SR_OK;
917 }
918 }
919
920 return SR_ERR;
921}
922
bd70ec4b
SB
923static struct sr_channel *get_channel_by_index_and_type(GSList *channel_lhead,
924 int index, int type)
925{
926 while (channel_lhead) {
927 struct sr_channel *ch = channel_lhead->data;
928 if (ch->index == index && ch->type == type)
929 return ch;
930
931 channel_lhead = channel_lhead->next;
932 }
933
934 return 0;
935}
936
937static int analog_channel_state_get(struct sr_dev_inst *sdi,
329733d9 938 const struct scope_config *config,
13f2b9d7
DJ
939 struct scope_state *state)
940{
8de2dc3b 941 unsigned int i, j;
13f2b9d7 942 char command[MAX_COMMAND_SIZE];
8fff7519 943 char *tmp_str;
bd70ec4b
SB
944 struct sr_channel *ch;
945 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 946
0a1f7b09 947 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
948 g_snprintf(command, sizeof(command),
949 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
950 i + 1);
951
23f43dff 952 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
953 &state->analog_channels[i].state) != SR_OK)
954 return SR_ERR;
955
bd70ec4b
SB
956 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_ANALOG);
957 if (ch)
958 ch->enabled = state->analog_channels[i].state;
959
13f2b9d7 960 g_snprintf(command, sizeof(command),
66ddc22a 961 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_SCALE],
13f2b9d7
DJ
962 i + 1);
963
8fff7519 964 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 965 return SR_ERR;
8fff7519 966
bb91b583 967 if (array_float_get(tmp_str, *(config->vdivs), config->num_vdivs, &j) != SR_OK) {
8fff7519 968 g_free(tmp_str);
b4e31d2a 969 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 970 return SR_ERR;
b4e31d2a 971 }
13f2b9d7 972
8fff7519
SA
973 g_free(tmp_str);
974 state->analog_channels[i].vdiv = j;
975
13f2b9d7
DJ
976 g_snprintf(command, sizeof(command),
977 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
978 i + 1);
979
23f43dff 980 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
981 &state->analog_channels[i].vertical_offset) != SR_OK)
982 return SR_ERR;
983
984 g_snprintf(command, sizeof(command),
985 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
986 i + 1);
987
23f43dff 988 if (scope_state_get_array_option(scpi, command, config->coupling_options,
692716f5 989 config->num_coupling_options,
13f2b9d7
DJ
990 &state->analog_channels[i].coupling) != SR_OK)
991 return SR_ERR;
448e81b1
SB
992
993 g_snprintf(command, sizeof(command),
994 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
995 i + 1);
996
997 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
998 return SR_ERR;
999
1000 if (tmp_str[0] == 'A')
1001 state->analog_channels[i].probe_unit = 'A';
1002 else
1003 state->analog_channels[i].probe_unit = 'V';
1004 g_free(tmp_str);
13f2b9d7
DJ
1005 }
1006
1007 return SR_OK;
1008}
1009
bd70ec4b 1010static int digital_channel_state_get(struct sr_dev_inst *sdi,
329733d9 1011 const struct scope_config *config,
13f2b9d7
DJ
1012 struct scope_state *state)
1013{
aac30633 1014 unsigned int i, idx;
e131be0a 1015 int result = SR_ERR;
c38d69ad 1016 char *logic_threshold_short[MAX_NUM_LOGIC_THRESHOLD_ENTRIES];
13f2b9d7 1017 char command[MAX_COMMAND_SIZE];
bd70ec4b
SB
1018 struct sr_channel *ch;
1019 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 1020
0a1f7b09 1021 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
1022 g_snprintf(command, sizeof(command),
1023 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
1024 i);
1025
23f43dff 1026 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
1027 &state->digital_channels[i]) != SR_OK)
1028 return SR_ERR;
bd70ec4b
SB
1029
1030 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_LOGIC);
1031 if (ch)
1032 ch->enabled = state->digital_channels[i];
13f2b9d7
DJ
1033 }
1034
aac30633
GT
1035 /* According to the SCPI standard, on models that support multiple
1036 * user-defined logic threshold settings the response to the command
e131be0a
GT
1037 * SCPI_CMD_GET_DIG_POD_THRESHOLD might return "USER" instead of
1038 * "USER1".
1039 *
1040 * This makes more difficult to validate the response when the logic
1041 * threshold is set to "USER1" and therefore we need to prevent device
1042 * opening failures in such configuration case...
1043 */
1044 for (i = 0; i < config->num_logic_threshold; i++) {
1045 logic_threshold_short[i] = g_strdup((*config->logic_threshold)[i]);
1046 if (!strcmp("USER1", (*config->logic_threshold)[i]))
1047 g_strlcpy(logic_threshold_short[i],
1048 (*config->logic_threshold)[i], strlen((*config->logic_threshold)[i]));
1049 }
1050
0a1f7b09 1051 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
1052 g_snprintf(command, sizeof(command),
1053 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
1054 i + 1);
1055
23f43dff 1056 if (sr_scpi_get_bool(scpi, command,
e131be0a
GT
1057 &state->digital_pods[i].state) != SR_OK)
1058 goto exit;
1059
aac30633
GT
1060 /* Check if the threshold command is based on the POD or digital channel index. */
1061 if (config->logic_threshold_for_pod)
1062 idx = i + 1;
1063 else
a12456f1 1064 idx = i * DIGITAL_CHANNELS_PER_POD;
aac30633 1065
e131be0a
GT
1066 g_snprintf(command, sizeof(command),
1067 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_THRESHOLD],
aac30633 1068 idx);
e131be0a
GT
1069
1070 /* Check for both standard and shortened responses. */
1071 if (scope_state_get_array_option(scpi, command, config->logic_threshold,
1072 config->num_logic_threshold,
1073 &state->digital_pods[i].threshold) != SR_OK)
1074 if (scope_state_get_array_option(scpi, command, (const char * (*)[]) &logic_threshold_short,
1075 config->num_logic_threshold,
1076 &state->digital_pods[i].threshold) != SR_OK)
1077 goto exit;
1078
aac30633 1079 /* If used-defined or custom threshold is active, get the level. */
e131be0a
GT
1080 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]))
1081 g_snprintf(command, sizeof(command),
1082 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
aac30633
GT
1083 idx, 1); /* USER1 logic threshold setting. */
1084 else if (!strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
e131be0a
GT
1085 g_snprintf(command, sizeof(command),
1086 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
aac30633
GT
1087 idx, 2); /* USER2 for custom logic_threshold setting. */
1088 else if (!strcmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1089 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
1090 g_snprintf(command, sizeof(command),
1091 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
1092 idx); /* USER or MAN for custom logic_threshold setting. */
e131be0a 1093 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
aac30633
GT
1094 !strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1095 !strcmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
1096 !strcmp("MAN", (*config->logic_threshold)[state->digital_pods[i].threshold]))
e131be0a
GT
1097 if (sr_scpi_get_float(scpi, command,
1098 &state->digital_pods[i].user_threshold) != SR_OK)
1099 goto exit;
13f2b9d7
DJ
1100 }
1101
e131be0a
GT
1102 result = SR_OK;
1103
1104exit:
1105 for (i = 0; i < config->num_logic_threshold; i++)
1106 g_free(logic_threshold_short[i]);
1107
1108 return result;
13f2b9d7
DJ
1109}
1110
14a2f74d
DJ
1111SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
1112{
1113 struct dev_context *devc;
1114 struct scope_state *state;
329733d9 1115 const struct scope_config *config;
14a2f74d 1116 float tmp_float;
14a2f74d
DJ
1117
1118 devc = sdi->priv;
1119 config = devc->model_config;
1120 state = devc->model_state;
14a2f74d 1121
39e19723
GT
1122 if (sr_scpi_get_float(sdi->conn,
1123 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
1124 &tmp_float) != SR_OK)
1125 return SR_ERR;
c06c24d2 1126
39e19723 1127 state->sample_rate = tmp_float;
14a2f74d
DJ
1128
1129 return SR_OK;
1130}
1131
719eff68 1132SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
1133{
1134 struct dev_context *devc;
1135 struct scope_state *state;
329733d9 1136 const struct scope_config *config;
8de2dc3b
DJ
1137 float tmp_float;
1138 unsigned int i;
8cccbac8 1139 char *tmp_str;
13f2b9d7
DJ
1140
1141 devc = sdi->priv;
1142 config = devc->model_config;
1143 state = devc->model_state;
1144
8de2dc3b
DJ
1145 sr_info("Fetching scope state");
1146
bd70ec4b 1147 if (analog_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
1148 return SR_ERR;
1149
bd70ec4b 1150 if (digital_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
1151 return SR_ERR;
1152
8cccbac8
SA
1153 if (sr_scpi_get_string(sdi->conn,
1154 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
1155 &tmp_str) != SR_OK)
1156 return SR_ERR;
1157
53012da6 1158 if (array_float_get(tmp_str, ARRAY_AND_SIZE(timebases), &i) != SR_OK) {
8cccbac8 1159 g_free(tmp_str);
b4e31d2a 1160 sr_err("Could not determine array index for time base.");
13f2b9d7 1161 return SR_ERR;
b4e31d2a 1162 }
e5b7eef7 1163 g_free(tmp_str);
13f2b9d7 1164
8cccbac8
SA
1165 state->timebase = i;
1166
29a9b1a0
GT
1167 /* Determine the number of horizontal (x) divisions. */
1168 if (sr_scpi_get_int(sdi->conn,
1169 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZONTAL_DIV],
1170 (int *)&config->num_xdivs) != SR_OK)
1171 return SR_ERR;
1172
89280b1a
UH
1173 if (sr_scpi_get_float(sdi->conn,
1174 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 1175 &tmp_float) != SR_OK)
13f2b9d7 1176 return SR_ERR;
422a1c0d
DJ
1177 state->horiz_triggerpos = tmp_float /
1178 (((double) (*config->timebases)[state->timebase][0] /
1179 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
1180 state->horiz_triggerpos -= 0.5;
1181 state->horiz_triggerpos *= -1;
13f2b9d7 1182
89280b1a
UH
1183 if (scope_state_get_array_option(sdi->conn,
1184 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
692716f5
UH
1185 config->trigger_sources, config->num_trigger_sources,
1186 &state->trigger_source) != SR_OK)
13f2b9d7
DJ
1187 return SR_ERR;
1188
89280b1a 1189 if (scope_state_get_array_option(sdi->conn,
692716f5
UH
1190 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
1191 config->trigger_slopes, config->num_trigger_slopes,
1192 &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
1193 return SR_ERR;
1194
4fa4db2c
GT
1195 if (sr_scpi_get_string(sdi->conn,
1196 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_PATTERN],
396af5ad 1197 &tmp_str) != SR_OK)
4fa4db2c 1198 return SR_ERR;
396af5ad
GT
1199 strncpy(state->trigger_pattern,
1200 sr_scpi_unquote_string(tmp_str),
1201 MAX_ANALOG_CHANNEL_COUNT + MAX_DIGITAL_CHANNEL_COUNT);
1202 g_free(tmp_str);
4fa4db2c 1203
97a00074
GT
1204 if (sr_scpi_get_string(sdi->conn,
1205 (*config->scpi_dialect)[SCPI_CMD_GET_HIGH_RESOLUTION],
1206 &tmp_str) != SR_OK)
1207 return SR_ERR;
1208 if (!strcmp("OFF", tmp_str))
1209 state->high_resolution = FALSE;
1210 else
1211 state->high_resolution = TRUE;
1212 g_free(tmp_str);
1213
1214 if (sr_scpi_get_string(sdi->conn,
1215 (*config->scpi_dialect)[SCPI_CMD_GET_PEAK_DETECTION],
1216 &tmp_str) != SR_OK)
1217 return SR_ERR;
1218 if (!strcmp("OFF", tmp_str))
1219 state->peak_detection = FALSE;
1220 else
1221 state->peak_detection = TRUE;
1222 g_free(tmp_str);
1223
14a2f74d
DJ
1224 if (hmo_update_sample_rate(sdi) != SR_OK)
1225 return SR_ERR;
1226
8de2dc3b
DJ
1227 sr_info("Fetching finished.");
1228
13f2b9d7
DJ
1229 scope_state_dump(config, state);
1230
1231 return SR_OK;
1232}
1233
329733d9 1234static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
1235{
1236 struct scope_state *state;
1237
a95f142e
UH
1238 state = g_malloc0(sizeof(struct scope_state));
1239 state->analog_channels = g_malloc0_n(config->analog_channels,
1240 sizeof(struct analog_channel_state));
1241 state->digital_channels = g_malloc0_n(
1242 config->digital_channels, sizeof(gboolean));
1243 state->digital_pods = g_malloc0_n(config->digital_pods,
e131be0a 1244 sizeof(struct digital_pod_state));
13f2b9d7
DJ
1245
1246 return state;
13f2b9d7
DJ
1247}
1248
719eff68 1249SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
1250{
1251 g_free(state->analog_channels);
1252 g_free(state->digital_channels);
1253 g_free(state->digital_pods);
1254 g_free(state);
1255}
1256
1257SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
1258{
13f2b9d7 1259 int model_index;
2d224dba 1260 unsigned int i, j, group;
ba7dd8bb 1261 struct sr_channel *ch;
13f2b9d7 1262 struct dev_context *devc;
d810901a 1263 const char *cg_name;
eac9fcd2 1264 int ret;
13f2b9d7
DJ
1265
1266 devc = sdi->priv;
1267 model_index = -1;
1268
89280b1a 1269 /* Find the exact model. */
13f2b9d7
DJ
1270 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
1271 for (j = 0; scope_models[i].name[j]; j++) {
1272 if (!strcmp(sdi->model, scope_models[i].name[j])) {
1273 model_index = i;
1274 break;
1275 }
1276 }
1277 if (model_index != -1)
1278 break;
1279 }
1280
1281 if (model_index == -1) {
e35ebc6a 1282 sr_dbg("Unsupported device.");
13f2b9d7
DJ
1283 return SR_ERR_NA;
1284 }
29a9b1a0 1285
a12456f1
GT
1286 /* Configure the number of PODs given the number of digital channels. */
1287 scope_models[model_index].digital_pods = scope_models[model_index].digital_channels / DIGITAL_CHANNELS_PER_POD;
13f2b9d7 1288
562b7ae5
SA
1289 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1290 scope_models[model_index].analog_channels);
562b7ae5
SA
1291 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1292 scope_models[model_index].digital_pods);
b0e80e9a
GS
1293 if (!devc->analog_groups || !devc->digital_groups) {
1294 g_free(devc->analog_groups);
1295 g_free(devc->digital_groups);
1296 return SR_ERR_MALLOC;
1297 }
13f2b9d7 1298
89280b1a 1299 /* Add analog channels. */
13f2b9d7 1300 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 1301 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 1302 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 1303
d810901a
GS
1304 cg_name = (*scope_models[model_index].analog_names)[i];
1305 devc->analog_groups[i] = sr_channel_group_new(sdi, cg_name, NULL);
562b7ae5 1306 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7
DJ
1307 }
1308
660e398f 1309 /* Add digital channel groups. */
eac9fcd2 1310 ret = SR_OK;
0a1f7b09 1311 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
d810901a 1312 devc->digital_groups[i] = sr_channel_group_new(sdi, NULL, NULL);
eac9fcd2
GS
1313 if (!devc->digital_groups[i]) {
1314 ret = SR_ERR_MALLOC;
1315 break;
1316 }
262061ff 1317 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i + 1);
13f2b9d7 1318 }
eac9fcd2
GS
1319 if (ret != SR_OK)
1320 return ret;
13f2b9d7 1321
89280b1a 1322 /* Add digital channels. */
13f2b9d7 1323 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 1324 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 1325 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 1326
a12456f1 1327 group = i / DIGITAL_CHANNELS_PER_POD;
2d224dba
GS
1328 devc->digital_groups[group]->channels = g_slist_append(
1329 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
1330 }
1331
1332 devc->model_config = &scope_models[model_index];
d779dcac 1333 devc->samples_limit = 0;
13f2b9d7
DJ
1334 devc->frame_limit = 0;
1335
1336 if (!(devc->model_state = scope_state_new(devc->model_config)))
1337 return SR_ERR_MALLOC;
1338
1339 return SR_OK;
1340}
1341
e06875b2
GS
1342/* Queue data of one channel group, for later submission. */
1343SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
1344 size_t group, GByteArray *pod_data)
1345{
1346 size_t size;
1347 GByteArray *store;
1348 uint8_t *logic_data;
1349 size_t idx, logic_step;
1350
1351 /*
1352 * Upon first invocation, allocate the array which can hold the
1353 * combined logic data for all channels. Assume that each channel
1354 * will yield an identical number of samples per receive call.
1355 *
1356 * As a poor man's safety measure: (Silently) skip processing
1357 * for unexpected sample counts, and ignore samples for
1358 * unexpected channel groups. Don't bother with complicated
1359 * resize logic, considering that many models only support one
1360 * pod, and the most capable supported models have two pods of
1361 * identical size. We haven't yet seen any "odd" configuration.
1362 */
1363 if (!devc->logic_data) {
1364 size = pod_data->len * devc->pod_count;
1365 store = g_byte_array_sized_new(size);
1366 memset(store->data, 0, size);
1367 store = g_byte_array_set_size(store, size);
1368 devc->logic_data = store;
1369 } else {
1370 store = devc->logic_data;
1371 size = store->len / devc->pod_count;
e06875b2
GS
1372 if (group >= devc->pod_count)
1373 return;
1374 }
1375
1376 /*
1377 * Fold the data of the most recently received channel group into
1378 * the storage, where data resides for all channels combined.
1379 */
1380 logic_data = store->data;
1381 logic_data += group;
1382 logic_step = devc->pod_count;
1383 for (idx = 0; idx < pod_data->len; idx++) {
1384 *logic_data = pod_data->data[idx];
1385 logic_data += logic_step;
1386 }
d779dcac
GT
1387
1388 /* Truncate acquisition if a smaller number of samples has been requested. */
1389 if (devc->samples_limit > 0 && devc->logic_data->len > devc->samples_limit * devc->pod_count)
1390 devc->logic_data->len = devc->samples_limit * devc->pod_count;
e06875b2
GS
1391}
1392
1393/* Submit data for all channels, after the individual groups got collected. */
1394SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
1395 struct dev_context *devc)
1396{
1397 struct sr_datafeed_packet packet;
1398 struct sr_datafeed_logic logic;
1399
1400 if (!devc->logic_data)
1401 return;
1402
1403 logic.data = devc->logic_data->data;
1404 logic.length = devc->logic_data->len;
1405 logic.unitsize = devc->pod_count;
1406
1407 packet.type = SR_DF_LOGIC;
1408 packet.payload = &logic;
1409
1410 sr_session_send(sdi, &packet);
1411}
1412
1413/* Undo previous resource allocation. */
1414SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
1415{
1416
1417 if (devc->logic_data) {
1418 g_byte_array_free(devc->logic_data, TRUE);
1419 devc->logic_data = NULL;
1420 }
1421 /*
1422 * Keep 'pod_count'! It's required when more frames will be
1423 * received, and does not harm when kept after acquisition.
1424 */
1425}
1426
719eff68 1427SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 1428{
ba7dd8bb 1429 struct sr_channel *ch;
13f2b9d7 1430 struct sr_dev_inst *sdi;
06a3e78a 1431 struct dev_context *devc;
401b83a1 1432 struct scope_state *state;
13f2b9d7 1433 struct sr_datafeed_packet packet;
401b83a1
SB
1434 GByteArray *data;
1435 struct sr_datafeed_analog analog;
1436 struct sr_analog_encoding encoding;
1437 struct sr_analog_meaning meaning;
1438 struct sr_analog_spec spec;
89280b1a 1439 struct sr_datafeed_logic logic;
e06875b2 1440 size_t group;
06a3e78a
DJ
1441
1442 (void)fd;
f0729866 1443 (void)revents;
06a3e78a
DJ
1444
1445 if (!(sdi = cb_data))
1446 return TRUE;
1447
1448 if (!(devc = sdi->priv))
1449 return TRUE;
1450
f4f273ce
SB
1451 /* Although this is correct in general, the USBTMC libusb implementation
1452 * currently does not generate an event prior to the first read. Often
1453 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
1454 if (revents != G_IO_IN)
1455 return TRUE;
f4f273ce 1456 */
13f2b9d7 1457
dc89faea 1458 ch = devc->current_channel->data;
401b83a1 1459 state = devc->model_state;
13f2b9d7 1460
b23eb1d4
GS
1461 /*
1462 * Send "frame begin" packet upon reception of data for the
1463 * first enabled channel.
1464 */
4c5f7006
UH
1465 if (devc->current_channel == devc->enabled_channels)
1466 std_session_send_df_frame_begin(sdi);
b23eb1d4
GS
1467
1468 /*
1469 * Pass on the received data of the channel(s).
1470 */
dc89faea
UH
1471 switch (ch->type) {
1472 case SR_CHANNEL_ANALOG:
4da62209 1473 data = NULL;
401b83a1 1474 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 1475 if (data)
401b83a1 1476 g_byte_array_free(data, TRUE);
dc89faea 1477 return TRUE;
13f2b9d7
DJ
1478 }
1479
401b83a1
SB
1480 packet.type = SR_DF_ANALOG;
1481
1482 analog.data = data->data;
1483 analog.num_samples = data->len / sizeof(float);
d779dcac
GT
1484 /* Truncate acquisition if a smaller number of samples has been requested. */
1485 if (devc->samples_limit > 0 && analog.num_samples > devc->samples_limit)
1486 analog.num_samples = devc->samples_limit;
7dcaddd3 1487 /* TODO: Use proper 'digits' value for this device (and its modes). */
8c381a35
GS
1488 sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
1489 encoding.is_signed = TRUE;
401b83a1
SB
1490 if (state->analog_channels[ch->index].probe_unit == 'V') {
1491 meaning.mq = SR_MQ_VOLTAGE;
1492 meaning.unit = SR_UNIT_VOLT;
1493 } else {
1494 meaning.mq = SR_MQ_CURRENT;
1495 meaning.unit = SR_UNIT_AMPERE;
1496 }
401b83a1 1497 meaning.channels = g_slist_append(NULL, ch);
dc89faea 1498 packet.payload = &analog;
695dc859 1499 sr_session_send(sdi, &packet);
d779dcac 1500 devc->num_samples = data->len / sizeof(float);
401b83a1
SB
1501 g_slist_free(meaning.channels);
1502 g_byte_array_free(data, TRUE);
dc89faea
UH
1503 data = NULL;
1504 break;
1505 case SR_CHANNEL_LOGIC:
4da62209 1506 data = NULL;
401b83a1 1507 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
14cb6aa4
GT
1508 if (data)
1509 g_byte_array_free(data, TRUE);
dc89faea 1510 return TRUE;
13f2b9d7 1511 }
dc89faea 1512
e06875b2
GS
1513 /*
1514 * If only data from the first pod is involved in the
1515 * acquisition, then the raw input bytes can get passed
1516 * forward for performance reasons. When the second pod
1517 * is involved (either alone, or in combination with the
1518 * first pod), then the received bytes need to be put
1519 * into memory in such a layout that all channel groups
1520 * get combined, and a unitsize larger than a single byte
1521 * applies. The "queue" logic transparently copes with
1522 * any such configuration. This works around the lack
1523 * of support for "meaning" to logic data, which is used
1524 * above for analog data.
1525 */
1526 if (devc->pod_count == 1) {
1527 packet.type = SR_DF_LOGIC;
1528 logic.data = data->data;
1529 logic.length = data->len;
d779dcac
GT
1530 /* Truncate acquisition if a smaller number of samples has been requested. */
1531 if (devc->samples_limit > 0 && logic.length > devc->samples_limit)
1532 logic.length = devc->samples_limit;
e06875b2
GS
1533 logic.unitsize = 1;
1534 packet.payload = &logic;
1535 sr_session_send(sdi, &packet);
1536 } else {
a12456f1 1537 group = ch->index / DIGITAL_CHANNELS_PER_POD;
e06875b2
GS
1538 hmo_queue_logic_data(devc, group, data);
1539 }
dc89faea 1540
d779dcac 1541 devc->num_samples = data->len / devc->pod_count;
401b83a1 1542 g_byte_array_free(data, TRUE);
dc89faea
UH
1543 data = NULL;
1544 break;
1545 default:
1546 sr_err("Invalid channel type.");
1547 break;
1548 }
1549
b23eb1d4
GS
1550 /*
1551 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
1552 * channels was received, then flush potentially queued logic data,
1553 * and send the "frame end" packet.
b23eb1d4 1554 */
dc89faea
UH
1555 if (devc->current_channel->next) {
1556 devc->current_channel = devc->current_channel->next;
1557 hmo_request_data(sdi);
b23eb1d4
GS
1558 return TRUE;
1559 }
e06875b2
GS
1560 hmo_send_logic_packet(sdi, devc);
1561
1562 /*
1563 * Release the logic data storage after each frame. This copes
1564 * with sample counts that differ in length per frame. -- Is
1565 * this a real constraint when acquiring multiple frames with
1566 * identical device settings?
1567 */
1568 hmo_cleanup_logic_data(devc);
1569
4c5f7006 1570 std_session_send_df_frame_end(sdi);
b23eb1d4
GS
1571
1572 /*
1573 * End of frame was reached. Stop acquisition after the specified
d779dcac
GT
1574 * number of frames or after the specified number of samples, or
1575 * continue reception by starting over at the first enabled channel.
b23eb1d4 1576 */
d779dcac 1577 if (++devc->num_frames >= devc->frame_limit || devc->num_samples >= devc->samples_limit) {
d2f7c417 1578 sr_dev_acquisition_stop(sdi);
e06875b2 1579 hmo_cleanup_logic_data(devc);
dc89faea
UH
1580 } else {
1581 devc->current_channel = devc->enabled_channels;
1582 hmo_request_data(sdi);
06a3e78a
DJ
1583 }
1584
1585 return TRUE;
1586}