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