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