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