]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add missing 1ns timebase for some models.
[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?",
42 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
43 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
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?",
79 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
80 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
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
DJ
896 g_snprintf(command, sizeof(command),
897 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
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],
1132 &state->trigger_pattern) != SR_OK)
1133 return SR_ERR;
1134
14a2f74d
DJ
1135 if (hmo_update_sample_rate(sdi) != SR_OK)
1136 return SR_ERR;
1137
8de2dc3b
DJ
1138 sr_info("Fetching finished.");
1139
13f2b9d7
DJ
1140 scope_state_dump(config, state);
1141
1142 return SR_OK;
1143}
1144
329733d9 1145static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
1146{
1147 struct scope_state *state;
1148
a95f142e
UH
1149 state = g_malloc0(sizeof(struct scope_state));
1150 state->analog_channels = g_malloc0_n(config->analog_channels,
1151 sizeof(struct analog_channel_state));
1152 state->digital_channels = g_malloc0_n(
1153 config->digital_channels, sizeof(gboolean));
1154 state->digital_pods = g_malloc0_n(config->digital_pods,
e131be0a 1155 sizeof(struct digital_pod_state));
13f2b9d7
DJ
1156
1157 return state;
13f2b9d7
DJ
1158}
1159
719eff68 1160SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
1161{
1162 g_free(state->analog_channels);
1163 g_free(state->digital_channels);
1164 g_free(state->digital_pods);
1165 g_free(state);
1166}
1167
1168SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
1169{
13f2b9d7 1170 int model_index;
2d224dba 1171 unsigned int i, j, group;
ba7dd8bb 1172 struct sr_channel *ch;
13f2b9d7 1173 struct dev_context *devc;
eac9fcd2 1174 int ret;
13f2b9d7
DJ
1175
1176 devc = sdi->priv;
1177 model_index = -1;
1178
89280b1a 1179 /* Find the exact model. */
13f2b9d7
DJ
1180 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
1181 for (j = 0; scope_models[i].name[j]; j++) {
1182 if (!strcmp(sdi->model, scope_models[i].name[j])) {
1183 model_index = i;
1184 break;
1185 }
1186 }
1187 if (model_index != -1)
1188 break;
1189 }
1190
1191 if (model_index == -1) {
e35ebc6a 1192 sr_dbg("Unsupported device.");
13f2b9d7
DJ
1193 return SR_ERR_NA;
1194 }
1195
562b7ae5
SA
1196 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1197 scope_models[model_index].analog_channels);
562b7ae5
SA
1198 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
1199 scope_models[model_index].digital_pods);
b0e80e9a
GS
1200 if (!devc->analog_groups || !devc->digital_groups) {
1201 g_free(devc->analog_groups);
1202 g_free(devc->digital_groups);
1203 return SR_ERR_MALLOC;
1204 }
13f2b9d7 1205
89280b1a 1206 /* Add analog channels. */
13f2b9d7 1207 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 1208 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 1209 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 1210
562b7ae5
SA
1211 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
1212
1213 devc->analog_groups[i]->name = g_strdup(
1214 (char *)(*scope_models[model_index].analog_names)[i]);
1215 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 1216
660e398f 1217 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 1218 devc->analog_groups[i]);
13f2b9d7
DJ
1219 }
1220
660e398f 1221 /* Add digital channel groups. */
eac9fcd2 1222 ret = SR_OK;
0a1f7b09 1223 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
562b7ae5 1224 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
eac9fcd2
GS
1225 if (!devc->digital_groups[i]) {
1226 ret = SR_ERR_MALLOC;
1227 break;
1228 }
262061ff 1229 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i + 1);
660e398f 1230 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 1231 devc->digital_groups[i]);
13f2b9d7 1232 }
eac9fcd2
GS
1233 if (ret != SR_OK)
1234 return ret;
13f2b9d7 1235
89280b1a 1236 /* Add digital channels. */
13f2b9d7 1237 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 1238 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 1239 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 1240
2d224dba
GS
1241 group = i / 8;
1242 devc->digital_groups[group]->channels = g_slist_append(
1243 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
1244 }
1245
1246 devc->model_config = &scope_models[model_index];
d779dcac 1247 devc->samples_limit = 0;
13f2b9d7
DJ
1248 devc->frame_limit = 0;
1249
1250 if (!(devc->model_state = scope_state_new(devc->model_config)))
1251 return SR_ERR_MALLOC;
1252
1253 return SR_OK;
1254}
1255
e06875b2
GS
1256/* Queue data of one channel group, for later submission. */
1257SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
1258 size_t group, GByteArray *pod_data)
1259{
1260 size_t size;
1261 GByteArray *store;
1262 uint8_t *logic_data;
1263 size_t idx, logic_step;
1264
1265 /*
1266 * Upon first invocation, allocate the array which can hold the
1267 * combined logic data for all channels. Assume that each channel
1268 * will yield an identical number of samples per receive call.
1269 *
1270 * As a poor man's safety measure: (Silently) skip processing
1271 * for unexpected sample counts, and ignore samples for
1272 * unexpected channel groups. Don't bother with complicated
1273 * resize logic, considering that many models only support one
1274 * pod, and the most capable supported models have two pods of
1275 * identical size. We haven't yet seen any "odd" configuration.
1276 */
1277 if (!devc->logic_data) {
1278 size = pod_data->len * devc->pod_count;
1279 store = g_byte_array_sized_new(size);
1280 memset(store->data, 0, size);
1281 store = g_byte_array_set_size(store, size);
1282 devc->logic_data = store;
1283 } else {
1284 store = devc->logic_data;
1285 size = store->len / devc->pod_count;
e06875b2
GS
1286 if (group >= devc->pod_count)
1287 return;
1288 }
1289
1290 /*
1291 * Fold the data of the most recently received channel group into
1292 * the storage, where data resides for all channels combined.
1293 */
1294 logic_data = store->data;
1295 logic_data += group;
1296 logic_step = devc->pod_count;
1297 for (idx = 0; idx < pod_data->len; idx++) {
1298 *logic_data = pod_data->data[idx];
1299 logic_data += logic_step;
1300 }
d779dcac
GT
1301
1302 /* Truncate acquisition if a smaller number of samples has been requested. */
1303 if (devc->samples_limit > 0 && devc->logic_data->len > devc->samples_limit * devc->pod_count)
1304 devc->logic_data->len = devc->samples_limit * devc->pod_count;
e06875b2
GS
1305}
1306
1307/* Submit data for all channels, after the individual groups got collected. */
1308SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
1309 struct dev_context *devc)
1310{
1311 struct sr_datafeed_packet packet;
1312 struct sr_datafeed_logic logic;
1313
1314 if (!devc->logic_data)
1315 return;
1316
1317 logic.data = devc->logic_data->data;
1318 logic.length = devc->logic_data->len;
1319 logic.unitsize = devc->pod_count;
1320
1321 packet.type = SR_DF_LOGIC;
1322 packet.payload = &logic;
1323
1324 sr_session_send(sdi, &packet);
1325}
1326
1327/* Undo previous resource allocation. */
1328SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
1329{
1330
1331 if (devc->logic_data) {
1332 g_byte_array_free(devc->logic_data, TRUE);
1333 devc->logic_data = NULL;
1334 }
1335 /*
1336 * Keep 'pod_count'! It's required when more frames will be
1337 * received, and does not harm when kept after acquisition.
1338 */
1339}
1340
719eff68 1341SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 1342{
ba7dd8bb 1343 struct sr_channel *ch;
13f2b9d7 1344 struct sr_dev_inst *sdi;
06a3e78a 1345 struct dev_context *devc;
401b83a1 1346 struct scope_state *state;
13f2b9d7 1347 struct sr_datafeed_packet packet;
401b83a1
SB
1348 GByteArray *data;
1349 struct sr_datafeed_analog analog;
1350 struct sr_analog_encoding encoding;
1351 struct sr_analog_meaning meaning;
1352 struct sr_analog_spec spec;
89280b1a 1353 struct sr_datafeed_logic logic;
e06875b2 1354 size_t group;
06a3e78a
DJ
1355
1356 (void)fd;
f0729866 1357 (void)revents;
06a3e78a 1358
f62f595b
MK
1359 data = NULL;
1360
06a3e78a
DJ
1361 if (!(sdi = cb_data))
1362 return TRUE;
1363
1364 if (!(devc = sdi->priv))
1365 return TRUE;
1366
f4f273ce
SB
1367 /* Although this is correct in general, the USBTMC libusb implementation
1368 * currently does not generate an event prior to the first read. Often
1369 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
1370 if (revents != G_IO_IN)
1371 return TRUE;
f4f273ce 1372 */
13f2b9d7 1373
dc89faea 1374 ch = devc->current_channel->data;
401b83a1 1375 state = devc->model_state;
13f2b9d7 1376
b23eb1d4
GS
1377 /*
1378 * Send "frame begin" packet upon reception of data for the
1379 * first enabled channel.
1380 */
1381 if (devc->current_channel == devc->enabled_channels) {
1382 packet.type = SR_DF_FRAME_BEGIN;
1383 sr_session_send(sdi, &packet);
1384 }
1385
1386 /*
1387 * Pass on the received data of the channel(s).
1388 */
dc89faea
UH
1389 switch (ch->type) {
1390 case SR_CHANNEL_ANALOG:
401b83a1 1391 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 1392 if (data)
401b83a1 1393 g_byte_array_free(data, TRUE);
dc89faea 1394 return TRUE;
13f2b9d7
DJ
1395 }
1396
401b83a1
SB
1397 packet.type = SR_DF_ANALOG;
1398
1399 analog.data = data->data;
1400 analog.num_samples = data->len / sizeof(float);
d779dcac
GT
1401 /* Truncate acquisition if a smaller number of samples has been requested. */
1402 if (devc->samples_limit > 0 && analog.num_samples > devc->samples_limit)
1403 analog.num_samples = devc->samples_limit;
401b83a1
SB
1404 analog.encoding = &encoding;
1405 analog.meaning = &meaning;
1406 analog.spec = &spec;
1407
1408 encoding.unitsize = sizeof(float);
1409 encoding.is_signed = TRUE;
1410 encoding.is_float = TRUE;
65a6794e
GS
1411#ifdef WORDS_BIGENDIAN
1412 encoding.is_bigendian = TRUE;
1413#else
d1ad8b10 1414 encoding.is_bigendian = FALSE;
65a6794e 1415#endif
7dcaddd3
UH
1416 /* TODO: Use proper 'digits' value for this device (and its modes). */
1417 encoding.digits = 2;
401b83a1
SB
1418 encoding.is_digits_decimal = FALSE;
1419 encoding.scale.p = 1;
1420 encoding.scale.q = 1;
1421 encoding.offset.p = 0;
1422 encoding.offset.q = 1;
1423 if (state->analog_channels[ch->index].probe_unit == 'V') {
1424 meaning.mq = SR_MQ_VOLTAGE;
1425 meaning.unit = SR_UNIT_VOLT;
1426 } else {
1427 meaning.mq = SR_MQ_CURRENT;
1428 meaning.unit = SR_UNIT_AMPERE;
1429 }
1430 meaning.mqflags = 0;
1431 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
1432 /* TODO: Use proper 'digits' value for this device (and its modes). */
1433 spec.spec_digits = 2;
dc89faea 1434 packet.payload = &analog;
695dc859 1435 sr_session_send(sdi, &packet);
d779dcac 1436 devc->num_samples = data->len / sizeof(float);
401b83a1
SB
1437 g_slist_free(meaning.channels);
1438 g_byte_array_free(data, TRUE);
dc89faea
UH
1439 data = NULL;
1440 break;
1441 case SR_CHANNEL_LOGIC:
401b83a1 1442 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
14cb6aa4
GT
1443 if (data)
1444 g_byte_array_free(data, TRUE);
dc89faea 1445 return TRUE;
13f2b9d7 1446 }
dc89faea 1447
e06875b2
GS
1448 /*
1449 * If only data from the first pod is involved in the
1450 * acquisition, then the raw input bytes can get passed
1451 * forward for performance reasons. When the second pod
1452 * is involved (either alone, or in combination with the
1453 * first pod), then the received bytes need to be put
1454 * into memory in such a layout that all channel groups
1455 * get combined, and a unitsize larger than a single byte
1456 * applies. The "queue" logic transparently copes with
1457 * any such configuration. This works around the lack
1458 * of support for "meaning" to logic data, which is used
1459 * above for analog data.
1460 */
1461 if (devc->pod_count == 1) {
1462 packet.type = SR_DF_LOGIC;
1463 logic.data = data->data;
1464 logic.length = data->len;
d779dcac
GT
1465 /* Truncate acquisition if a smaller number of samples has been requested. */
1466 if (devc->samples_limit > 0 && logic.length > devc->samples_limit)
1467 logic.length = devc->samples_limit;
e06875b2
GS
1468 logic.unitsize = 1;
1469 packet.payload = &logic;
1470 sr_session_send(sdi, &packet);
1471 } else {
1472 group = ch->index / 8;
1473 hmo_queue_logic_data(devc, group, data);
1474 }
dc89faea 1475
d779dcac 1476 devc->num_samples = data->len / devc->pod_count;
401b83a1 1477 g_byte_array_free(data, TRUE);
dc89faea
UH
1478 data = NULL;
1479 break;
1480 default:
1481 sr_err("Invalid channel type.");
1482 break;
1483 }
1484
b23eb1d4
GS
1485 /*
1486 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
1487 * channels was received, then flush potentially queued logic data,
1488 * and send the "frame end" packet.
b23eb1d4 1489 */
dc89faea
UH
1490 if (devc->current_channel->next) {
1491 devc->current_channel = devc->current_channel->next;
1492 hmo_request_data(sdi);
b23eb1d4
GS
1493 return TRUE;
1494 }
e06875b2
GS
1495 hmo_send_logic_packet(sdi, devc);
1496
1497 /*
1498 * Release the logic data storage after each frame. This copes
1499 * with sample counts that differ in length per frame. -- Is
1500 * this a real constraint when acquiring multiple frames with
1501 * identical device settings?
1502 */
1503 hmo_cleanup_logic_data(devc);
1504
b23eb1d4
GS
1505 packet.type = SR_DF_FRAME_END;
1506 sr_session_send(sdi, &packet);
1507
1508 /*
1509 * End of frame was reached. Stop acquisition after the specified
d779dcac
GT
1510 * number of frames or after the specified number of samples, or
1511 * continue reception by starting over at the first enabled channel.
b23eb1d4 1512 */
d779dcac 1513 if (++devc->num_frames >= devc->frame_limit || devc->num_samples >= devc->samples_limit) {
d2f7c417 1514 sr_dev_acquisition_stop(sdi);
e06875b2 1515 hmo_cleanup_logic_data(devc);
dc89faea
UH
1516 } else {
1517 devc->current_channel = devc->enabled_channels;
1518 hmo_request_data(sdi);
06a3e78a
DJ
1519 }
1520
1521 return TRUE;
1522}