]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Fix for an incorrect samplerate being returned.
[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
4b25cbff 70static const uint32_t devopts[] = {
13f2b9d7 71 SR_CONF_OSCILLOSCOPE,
830e24b6
GT
72 SR_CONF_LIMIT_SAMPLES | SR_CONF_SET,
73 SR_CONF_LIMIT_FRAMES | SR_CONF_SET,
86621306 74 SR_CONF_SAMPLERATE | SR_CONF_GET,
5827f61b 75 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 76 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 77 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
86621306
UH
78 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
79 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
4fa4db2c 80 SR_CONF_TRIGGER_PATTERN | SR_CONF_GET | SR_CONF_SET,
13f2b9d7
DJ
81};
82
6b82c3e5 83static const uint32_t devopts_cg_analog[] = {
5827f61b 84 SR_CONF_NUM_VDIV | SR_CONF_GET,
5827f61b 85 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
86621306 86 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
87};
88
e131be0a
GT
89static const uint32_t devopts_cg_digital[] = {
90 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
91 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
92};
93
4b25cbff 94static const char *coupling_options[] = {
b05ab7d2
SB
95 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
96 "ACL", // AC with 1 MOhm termination
97 "DC", // DC with 50 Ohm termination
98 "DCL", // DC with 1 MOhm termination
13f2b9d7 99 "GND",
13f2b9d7
DJ
100};
101
102static const char *scope_trigger_slopes[] = {
103 "POS",
104 "NEG",
356f64f8 105 "EITH",
13f2b9d7
DJ
106};
107
e131be0a
GT
108/* Predefined logic thresholds. */
109static const char *logic_threshold[] = {
110 "TTL",
111 "ECL",
112 "CMOS",
113 "USER1",
114 "USER2", // overwritten by logic_threshold_custom, use USER1 for permanent setting
115};
116
4cf90b86 117/* RTC1002, HMO Compact2 and HMO1002/HMO1202 */
6d0f3508 118static const char *an2_dig8_trigger_sources[] = {
f8195cb2
UH
119 "CH1", "CH2",
120 "LINE", "EXT", "PATT", "BUS1", "BUS2",
121 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
122};
123
4cf90b86 124/* HMO3xx2 */
6d0f3508
GT
125static const char *an2_dig16_trigger_sources[] = {
126 "CH1", "CH2",
127 "LINE", "EXT", "PATT", "BUS1", "BUS2",
128 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
129 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
130};
131
4cf90b86 132/* HMO Compact4 */
6d0f3508 133static const char *an4_dig8_trigger_sources[] = {
f8195cb2
UH
134 "CH1", "CH2", "CH3", "CH4",
135 "LINE", "EXT", "PATT", "BUS1", "BUS2",
136 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
13f2b9d7
DJ
137};
138
4cf90b86 139/* HMO3xx4 and HMO2524 */
6d0f3508 140static const char *an4_dig16_trigger_sources[] = {
f8195cb2
UH
141 "CH1", "CH2", "CH3", "CH4",
142 "LINE", "EXT", "PATT", "BUS1", "BUS2",
143 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
144 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
74413faf
GS
145};
146
4b25cbff 147static const uint64_t timebases[][2] = {
13f2b9d7
DJ
148 /* nanoseconds */
149 { 2, 1000000000 },
150 { 5, 1000000000 },
151 { 10, 1000000000 },
152 { 20, 1000000000 },
153 { 50, 1000000000 },
154 { 100, 1000000000 },
155 { 200, 1000000000 },
156 { 500, 1000000000 },
157 /* microseconds */
158 { 1, 1000000 },
159 { 2, 1000000 },
160 { 5, 1000000 },
161 { 10, 1000000 },
162 { 20, 1000000 },
163 { 50, 1000000 },
164 { 100, 1000000 },
165 { 200, 1000000 },
166 { 500, 1000000 },
167 /* milliseconds */
168 { 1, 1000 },
169 { 2, 1000 },
170 { 5, 1000 },
171 { 10, 1000 },
172 { 20, 1000 },
173 { 50, 1000 },
174 { 100, 1000 },
175 { 200, 1000 },
176 { 500, 1000 },
177 /* seconds */
178 { 1, 1 },
179 { 2, 1 },
180 { 5, 1 },
181 { 10, 1 },
182 { 20, 1 },
183 { 50, 1 },
184};
185
4b25cbff 186static const uint64_t vdivs[][2] = {
13f2b9d7
DJ
187 /* millivolts */
188 { 1, 1000 },
189 { 2, 1000 },
190 { 5, 1000 },
191 { 10, 1000 },
192 { 20, 1000 },
193 { 50, 1000 },
194 { 100, 1000 },
195 { 200, 1000 },
196 { 500, 1000 },
197 /* volts */
198 { 1, 1 },
199 { 2, 1 },
200 { 5, 1 },
201 { 10, 1 },
fe227d17
SA
202 { 20, 1 },
203 { 50, 1 },
13f2b9d7
DJ
204};
205
ba7dd8bb 206static const char *scope_analog_channel_names[] = {
f8195cb2 207 "CH1", "CH2", "CH3", "CH4",
13f2b9d7
DJ
208};
209
ba7dd8bb 210static const char *scope_digital_channel_names[] = {
f8195cb2
UH
211 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
212 "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15",
13f2b9d7
DJ
213};
214
329733d9 215static const struct scope_config scope_models[] = {
13f2b9d7 216 {
4cf90b86
GT
217 /* RTC1002 and HMO722/1002/1022/1202/1522/2022 support only 8 digital channels. */
218 .name = {"RTC1002", "HMO722", "HMO1002", "HMO1022", "HMO1202", "HMO1522", "HMO2022", NULL},
13f2b9d7
DJ
219 .analog_channels = 2,
220 .digital_channels = 8,
221 .digital_pods = 1,
222
ba7dd8bb
UH
223 .analog_names = &scope_analog_channel_names,
224 .digital_names = &scope_digital_channel_names,
13f2b9d7 225
4b25cbff
UH
226 .devopts = &devopts,
227 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 228
6b82c3e5
UH
229 .devopts_cg_analog = &devopts_cg_analog,
230 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 231
e131be0a
GT
232 .devopts_cg_digital = &devopts_cg_digital,
233 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
234
4b25cbff 235 .coupling_options = &coupling_options,
692716f5
UH
236 .num_coupling_options = ARRAY_SIZE(coupling_options),
237
e131be0a
GT
238 .logic_threshold = &logic_threshold,
239 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
240
6d0f3508
GT
241 .trigger_sources = &an2_dig8_trigger_sources,
242 .num_trigger_sources = ARRAY_SIZE(an2_dig8_trigger_sources),
243
244 .trigger_slopes = &scope_trigger_slopes,
245 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
246
247 .timebases = &timebases,
248 .num_timebases = ARRAY_SIZE(timebases),
249
250 .vdivs = &vdivs,
251 .num_vdivs = ARRAY_SIZE(vdivs),
252
253 .num_xdivs = 12,
254 .num_ydivs = 8,
255
256 .scpi_dialect = &hameg_scpi_dialect,
257 },
258 {
259 /* HMO3032/3042/3052/3522 support 16 digital channels. */
260 .name = {"HMO3032", "HMO3042", "HMO3052", "HMO3522", NULL},
261 .analog_channels = 2,
262 .digital_channels = 16,
263 .digital_pods = 2,
264
265 .analog_names = &scope_analog_channel_names,
266 .digital_names = &scope_digital_channel_names,
267
268 .devopts = &devopts,
269 .num_devopts = ARRAY_SIZE(devopts),
270
271 .devopts_cg_analog = &devopts_cg_analog,
272 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
273
e131be0a
GT
274 .devopts_cg_digital = &devopts_cg_digital,
275 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
276
6d0f3508
GT
277 .coupling_options = &coupling_options,
278 .num_coupling_options = ARRAY_SIZE(coupling_options),
279
e131be0a
GT
280 .logic_threshold = &logic_threshold,
281 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
282
6d0f3508
GT
283 .trigger_sources = &an2_dig16_trigger_sources,
284 .num_trigger_sources = ARRAY_SIZE(an2_dig16_trigger_sources),
692716f5 285
13f2b9d7 286 .trigger_slopes = &scope_trigger_slopes,
692716f5 287 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 288
4b25cbff
UH
289 .timebases = &timebases,
290 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 291
4b25cbff
UH
292 .vdivs = &vdivs,
293 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
294
295 .num_xdivs = 12,
296 .num_ydivs = 8,
297
298 .scpi_dialect = &hameg_scpi_dialect,
299 },
300 {
74413faf 301 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
13f2b9d7
DJ
302 .analog_channels = 4,
303 .digital_channels = 8,
304 .digital_pods = 1,
305
ba7dd8bb
UH
306 .analog_names = &scope_analog_channel_names,
307 .digital_names = &scope_digital_channel_names,
13f2b9d7 308
4b25cbff
UH
309 .devopts = &devopts,
310 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 311
6b82c3e5
UH
312 .devopts_cg_analog = &devopts_cg_analog,
313 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 314
e131be0a
GT
315 .devopts_cg_digital = &devopts_cg_digital,
316 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
317
4b25cbff 318 .coupling_options = &coupling_options,
692716f5
UH
319 .num_coupling_options = ARRAY_SIZE(coupling_options),
320
e131be0a
GT
321 .logic_threshold = &logic_threshold,
322 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
323
6d0f3508
GT
324 .trigger_sources = &an4_dig8_trigger_sources,
325 .num_trigger_sources = ARRAY_SIZE(an4_dig8_trigger_sources),
692716f5 326
13f2b9d7 327 .trigger_slopes = &scope_trigger_slopes,
692716f5 328 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
13f2b9d7 329
4b25cbff
UH
330 .timebases = &timebases,
331 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 332
4b25cbff
UH
333 .vdivs = &vdivs,
334 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
335
336 .num_xdivs = 12,
337 .num_ydivs = 8,
338
74413faf
GS
339 .scpi_dialect = &hameg_scpi_dialect,
340 },
341 {
bf8a02b6 342 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", "HMO3524", NULL},
74413faf
GS
343 .analog_channels = 4,
344 .digital_channels = 16,
345 .digital_pods = 2,
346
347 .analog_names = &scope_analog_channel_names,
348 .digital_names = &scope_digital_channel_names,
349
4b25cbff
UH
350 .devopts = &devopts,
351 .num_devopts = ARRAY_SIZE(devopts),
74413faf 352
6b82c3e5
UH
353 .devopts_cg_analog = &devopts_cg_analog,
354 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
74413faf 355
e131be0a
GT
356 .devopts_cg_digital = &devopts_cg_digital,
357 .num_devopts_cg_digital = ARRAY_SIZE(devopts_cg_digital),
358
4b25cbff 359 .coupling_options = &coupling_options,
692716f5
UH
360 .num_coupling_options = ARRAY_SIZE(coupling_options),
361
e131be0a
GT
362 .logic_threshold = &logic_threshold,
363 .num_logic_threshold = ARRAY_SIZE(logic_threshold),
364
6d0f3508
GT
365 .trigger_sources = &an4_dig16_trigger_sources,
366 .num_trigger_sources = ARRAY_SIZE(an4_dig16_trigger_sources),
692716f5 367
74413faf 368 .trigger_slopes = &scope_trigger_slopes,
692716f5 369 .num_trigger_slopes = ARRAY_SIZE(scope_trigger_slopes),
74413faf 370
4b25cbff
UH
371 .timebases = &timebases,
372 .num_timebases = ARRAY_SIZE(timebases),
74413faf 373
4b25cbff
UH
374 .vdivs = &vdivs,
375 .num_vdivs = ARRAY_SIZE(vdivs),
74413faf
GS
376
377 .num_xdivs = 12,
378 .num_ydivs = 8,
379
13f2b9d7
DJ
380 .scpi_dialect = &hameg_scpi_dialect,
381 },
382};
383
329733d9 384static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
385 struct scope_state *state)
386{
387 unsigned int i;
8de2dc3b 388 char *tmp;
13f2b9d7 389
0a1f7b09 390 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
391 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
392 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
d9251a2c 393 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 394 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 395 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 396 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
397 }
398
0a1f7b09 399 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
400 sr_info("State of digital channel %d -> %s", i,
401 state->digital_channels[i] ? "On" : "Off");
402 }
403
0a1f7b09 404 for (i = 0; i < config->digital_pods; i++) {
e131be0a 405 if (strncmp("USER", (*config->logic_threshold)[state->digital_pods[i].threshold], 4))
262061ff 406 sr_info("State of digital POD %d -> %s : %s (threshold)", i + 1,
e131be0a
GT
407 state->digital_pods[i].state ? "On" : "Off",
408 (*config->logic_threshold)[state->digital_pods[i].threshold]);
409 else // user-defined or custom logic threshold
262061ff 410 sr_info("State of digital POD %d -> %s : %E (threshold)", i + 1,
e131be0a
GT
411 state->digital_pods[i].state ? "On" : "Off",
412 state->digital_pods[i].user_threshold);
13f2b9d7
DJ
413 }
414
6984cfb2
SA
415 tmp = sr_period_string((*config->timebases)[state->timebase][0],
416 (*config->timebases)[state->timebase][1]);
8de2dc3b
DJ
417 sr_info("Current timebase: %s", tmp);
418 g_free(tmp);
419
14a2f74d
DJ
420 tmp = sr_samplerate_string(state->sample_rate);
421 sr_info("Current samplerate: %s", tmp);
422 g_free(tmp);
423
4fa4db2c
GT
424 if (!strcmp("PATT", (*config->trigger_sources)[state->trigger_source]))
425 sr_info("Current trigger: %s (pattern), %.2f (offset)",
426 state->trigger_pattern,
427 state->horiz_triggerpos);
428 else // Edge (slope) trigger
429 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
430 (*config->trigger_sources)[state->trigger_source],
431 (*config->trigger_slopes)[state->trigger_slope],
432 state->horiz_triggerpos);
13f2b9d7
DJ
433}
434
23f43dff 435static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
692716f5 436 const char *command, const char *(*array)[], unsigned int n, int *result)
13f2b9d7
DJ
437{
438 char *tmp;
bd633efa 439 int idx;
13f2b9d7 440
67398969 441 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK)
13f2b9d7 442 return SR_ERR;
13f2b9d7 443
bd633efa 444 if ((idx = std_str_idx_s(tmp, *array, n)) < 0) {
13f2b9d7 445 g_free(tmp);
bd633efa 446 return SR_ERR_ARG;
13f2b9d7
DJ
447 }
448
bd633efa
UH
449 *result = idx;
450
451 g_free(tmp);
452
13f2b9d7
DJ
453 return SR_OK;
454}
455
8fff7519 456/**
a53acd7d
SB
457 * This function takes a value of the form "2.000E-03" and returns the index
458 * of an array where a matching pair was found.
8fff7519
SA
459 *
460 * @param value The string to be parsed.
461 * @param array The array of s/f pairs.
462 * @param array_len The number of pairs in the array.
463 * @param result The index at which a matching pair was found.
464 *
465 * @return SR_ERR on any parsing error, SR_OK otherwise.
466 */
467static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 468 int array_len, unsigned int *result)
8fff7519 469{
a53acd7d
SB
470 struct sr_rational rval;
471 struct sr_rational aval;
8cccbac8 472
a53acd7d 473 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
474 return SR_ERR;
475
a53acd7d
SB
476 for (int i = 0; i < array_len; i++) {
477 sr_rational_set(&aval, array[i][0], array[i][1]);
478 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
479 *result = i;
480 return SR_OK;
481 }
482 }
483
484 return SR_ERR;
485}
486
bd70ec4b
SB
487static struct sr_channel *get_channel_by_index_and_type(GSList *channel_lhead,
488 int index, int type)
489{
490 while (channel_lhead) {
491 struct sr_channel *ch = channel_lhead->data;
492 if (ch->index == index && ch->type == type)
493 return ch;
494
495 channel_lhead = channel_lhead->next;
496 }
497
498 return 0;
499}
500
501static int analog_channel_state_get(struct sr_dev_inst *sdi,
329733d9 502 const struct scope_config *config,
13f2b9d7
DJ
503 struct scope_state *state)
504{
8de2dc3b 505 unsigned int i, j;
13f2b9d7 506 char command[MAX_COMMAND_SIZE];
8fff7519 507 char *tmp_str;
bd70ec4b
SB
508 struct sr_channel *ch;
509 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 510
0a1f7b09 511 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
512 g_snprintf(command, sizeof(command),
513 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
514 i + 1);
515
23f43dff 516 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
517 &state->analog_channels[i].state) != SR_OK)
518 return SR_ERR;
519
bd70ec4b
SB
520 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_ANALOG);
521 if (ch)
522 ch->enabled = state->analog_channels[i].state;
523
13f2b9d7
DJ
524 g_snprintf(command, sizeof(command),
525 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
526 i + 1);
527
8fff7519 528 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 529 return SR_ERR;
8fff7519 530
53012da6 531 if (array_float_get(tmp_str, ARRAY_AND_SIZE(vdivs), &j) != SR_OK) {
8fff7519 532 g_free(tmp_str);
b4e31d2a 533 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 534 return SR_ERR;
b4e31d2a 535 }
13f2b9d7 536
8fff7519
SA
537 g_free(tmp_str);
538 state->analog_channels[i].vdiv = j;
539
13f2b9d7
DJ
540 g_snprintf(command, sizeof(command),
541 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
542 i + 1);
543
23f43dff 544 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
545 &state->analog_channels[i].vertical_offset) != SR_OK)
546 return SR_ERR;
547
548 g_snprintf(command, sizeof(command),
549 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
550 i + 1);
551
23f43dff 552 if (scope_state_get_array_option(scpi, command, config->coupling_options,
692716f5 553 config->num_coupling_options,
13f2b9d7
DJ
554 &state->analog_channels[i].coupling) != SR_OK)
555 return SR_ERR;
448e81b1
SB
556
557 g_snprintf(command, sizeof(command),
558 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
559 i + 1);
560
561 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
562 return SR_ERR;
563
564 if (tmp_str[0] == 'A')
565 state->analog_channels[i].probe_unit = 'A';
566 else
567 state->analog_channels[i].probe_unit = 'V';
568 g_free(tmp_str);
13f2b9d7
DJ
569 }
570
571 return SR_OK;
572}
573
bd70ec4b 574static int digital_channel_state_get(struct sr_dev_inst *sdi,
329733d9 575 const struct scope_config *config,
13f2b9d7
DJ
576 struct scope_state *state)
577{
578 unsigned int i;
e131be0a
GT
579 int result = SR_ERR;
580 static char *logic_threshold_short[] = {};
13f2b9d7 581 char command[MAX_COMMAND_SIZE];
bd70ec4b
SB
582 struct sr_channel *ch;
583 struct sr_scpi_dev_inst *scpi = sdi->conn;
13f2b9d7 584
0a1f7b09 585 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
586 g_snprintf(command, sizeof(command),
587 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
588 i);
589
23f43dff 590 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
591 &state->digital_channels[i]) != SR_OK)
592 return SR_ERR;
bd70ec4b
SB
593
594 ch = get_channel_by_index_and_type(sdi->channels, i, SR_CHANNEL_LOGIC);
595 if (ch)
596 ch->enabled = state->digital_channels[i];
13f2b9d7
DJ
597 }
598
e131be0a
GT
599 /* According to the SCPI standard, the response to the command
600 * SCPI_CMD_GET_DIG_POD_THRESHOLD might return "USER" instead of
601 * "USER1".
602 *
603 * This makes more difficult to validate the response when the logic
604 * threshold is set to "USER1" and therefore we need to prevent device
605 * opening failures in such configuration case...
606 */
607 for (i = 0; i < config->num_logic_threshold; i++) {
608 logic_threshold_short[i] = g_strdup((*config->logic_threshold)[i]);
609 if (!strcmp("USER1", (*config->logic_threshold)[i]))
610 g_strlcpy(logic_threshold_short[i],
611 (*config->logic_threshold)[i], strlen((*config->logic_threshold)[i]));
612 }
613
0a1f7b09 614 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
615 g_snprintf(command, sizeof(command),
616 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
617 i + 1);
618
23f43dff 619 if (sr_scpi_get_bool(scpi, command,
e131be0a
GT
620 &state->digital_pods[i].state) != SR_OK)
621 goto exit;
622
623 g_snprintf(command, sizeof(command),
624 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_THRESHOLD],
625 i + 1);
626
627 /* Check for both standard and shortened responses. */
628 if (scope_state_get_array_option(scpi, command, config->logic_threshold,
629 config->num_logic_threshold,
630 &state->digital_pods[i].threshold) != SR_OK)
631 if (scope_state_get_array_option(scpi, command, (const char * (*)[]) &logic_threshold_short,
632 config->num_logic_threshold,
633 &state->digital_pods[i].threshold) != SR_OK)
634 goto exit;
635
636 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]))
637 g_snprintf(command, sizeof(command),
638 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
639 i + 1, 1); // USER1 logic threshold setting
640
641 if (!strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
642 g_snprintf(command, sizeof(command),
643 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_USER_THRESHOLD],
644 i + 1, 2); // USER2 for custom logic_threshold setting
645
646 if (!strcmp("USER1", (*config->logic_threshold)[state->digital_pods[i].threshold]) ||
647 !strcmp("USER2", (*config->logic_threshold)[state->digital_pods[i].threshold]))
648 if (sr_scpi_get_float(scpi, command,
649 &state->digital_pods[i].user_threshold) != SR_OK)
650 goto exit;
13f2b9d7
DJ
651 }
652
e131be0a
GT
653 result = SR_OK;
654
655exit:
656 for (i = 0; i < config->num_logic_threshold; i++)
657 g_free(logic_threshold_short[i]);
658
659 return result;
13f2b9d7
DJ
660}
661
14a2f74d
DJ
662SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
663{
664 struct dev_context *devc;
665 struct scope_state *state;
329733d9 666 const struct scope_config *config;
14a2f74d 667 float tmp_float;
14a2f74d
DJ
668
669 devc = sdi->priv;
670 config = devc->model_config;
671 state = devc->model_state;
14a2f74d 672
39e19723
GT
673 if (sr_scpi_get_float(sdi->conn,
674 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
675 &tmp_float) != SR_OK)
676 return SR_ERR;
c06c24d2 677
39e19723 678 state->sample_rate = tmp_float;
14a2f74d
DJ
679
680 return SR_OK;
681}
682
719eff68 683SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
684{
685 struct dev_context *devc;
686 struct scope_state *state;
329733d9 687 const struct scope_config *config;
8de2dc3b
DJ
688 float tmp_float;
689 unsigned int i;
8cccbac8 690 char *tmp_str;
13f2b9d7
DJ
691
692 devc = sdi->priv;
693 config = devc->model_config;
694 state = devc->model_state;
695
8de2dc3b
DJ
696 sr_info("Fetching scope state");
697
bd70ec4b 698 if (analog_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
699 return SR_ERR;
700
bd70ec4b 701 if (digital_channel_state_get(sdi, config, state) != SR_OK)
13f2b9d7
DJ
702 return SR_ERR;
703
89280b1a
UH
704 if (sr_scpi_get_float(sdi->conn,
705 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
706 &tmp_float) != SR_OK)
707 return SR_ERR;
708
8cccbac8
SA
709 if (sr_scpi_get_string(sdi->conn,
710 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
711 &tmp_str) != SR_OK)
712 return SR_ERR;
713
53012da6 714 if (array_float_get(tmp_str, ARRAY_AND_SIZE(timebases), &i) != SR_OK) {
8cccbac8 715 g_free(tmp_str);
b4e31d2a 716 sr_err("Could not determine array index for time base.");
13f2b9d7 717 return SR_ERR;
b4e31d2a 718 }
e5b7eef7 719 g_free(tmp_str);
13f2b9d7 720
8cccbac8
SA
721 state->timebase = i;
722
89280b1a
UH
723 if (sr_scpi_get_float(sdi->conn,
724 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 725 &tmp_float) != SR_OK)
13f2b9d7 726 return SR_ERR;
422a1c0d
DJ
727 state->horiz_triggerpos = tmp_float /
728 (((double) (*config->timebases)[state->timebase][0] /
729 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
730 state->horiz_triggerpos -= 0.5;
731 state->horiz_triggerpos *= -1;
13f2b9d7 732
89280b1a
UH
733 if (scope_state_get_array_option(sdi->conn,
734 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
692716f5
UH
735 config->trigger_sources, config->num_trigger_sources,
736 &state->trigger_source) != SR_OK)
13f2b9d7
DJ
737 return SR_ERR;
738
89280b1a 739 if (scope_state_get_array_option(sdi->conn,
692716f5
UH
740 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
741 config->trigger_slopes, config->num_trigger_slopes,
742 &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
743 return SR_ERR;
744
4fa4db2c
GT
745 if (sr_scpi_get_string(sdi->conn,
746 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_PATTERN],
747 &state->trigger_pattern) != SR_OK)
748 return SR_ERR;
749
14a2f74d
DJ
750 if (hmo_update_sample_rate(sdi) != SR_OK)
751 return SR_ERR;
752
8de2dc3b
DJ
753 sr_info("Fetching finished.");
754
13f2b9d7
DJ
755 scope_state_dump(config, state);
756
757 return SR_OK;
758}
759
329733d9 760static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
761{
762 struct scope_state *state;
763
a95f142e
UH
764 state = g_malloc0(sizeof(struct scope_state));
765 state->analog_channels = g_malloc0_n(config->analog_channels,
766 sizeof(struct analog_channel_state));
767 state->digital_channels = g_malloc0_n(
768 config->digital_channels, sizeof(gboolean));
769 state->digital_pods = g_malloc0_n(config->digital_pods,
e131be0a 770 sizeof(struct digital_pod_state));
13f2b9d7
DJ
771
772 return state;
13f2b9d7
DJ
773}
774
719eff68 775SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
776{
777 g_free(state->analog_channels);
778 g_free(state->digital_channels);
779 g_free(state->digital_pods);
780 g_free(state);
781}
782
783SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
784{
13f2b9d7 785 int model_index;
2d224dba 786 unsigned int i, j, group;
ba7dd8bb 787 struct sr_channel *ch;
13f2b9d7 788 struct dev_context *devc;
eac9fcd2 789 int ret;
13f2b9d7
DJ
790
791 devc = sdi->priv;
792 model_index = -1;
793
89280b1a 794 /* Find the exact model. */
13f2b9d7
DJ
795 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
796 for (j = 0; scope_models[i].name[j]; j++) {
797 if (!strcmp(sdi->model, scope_models[i].name[j])) {
798 model_index = i;
799 break;
800 }
801 }
802 if (model_index != -1)
803 break;
804 }
805
806 if (model_index == -1) {
e35ebc6a 807 sr_dbg("Unsupported device.");
13f2b9d7
DJ
808 return SR_ERR_NA;
809 }
810
562b7ae5
SA
811 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
812 scope_models[model_index].analog_channels);
562b7ae5
SA
813 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
814 scope_models[model_index].digital_pods);
b0e80e9a
GS
815 if (!devc->analog_groups || !devc->digital_groups) {
816 g_free(devc->analog_groups);
817 g_free(devc->digital_groups);
818 return SR_ERR_MALLOC;
819 }
13f2b9d7 820
89280b1a 821 /* Add analog channels. */
13f2b9d7 822 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 823 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 824 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 825
562b7ae5
SA
826 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
827
828 devc->analog_groups[i]->name = g_strdup(
829 (char *)(*scope_models[model_index].analog_names)[i]);
830 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 831
660e398f 832 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 833 devc->analog_groups[i]);
13f2b9d7
DJ
834 }
835
660e398f 836 /* Add digital channel groups. */
eac9fcd2 837 ret = SR_OK;
0a1f7b09 838 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
562b7ae5 839 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
eac9fcd2
GS
840 if (!devc->digital_groups[i]) {
841 ret = SR_ERR_MALLOC;
842 break;
843 }
262061ff 844 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i + 1);
660e398f 845 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 846 devc->digital_groups[i]);
13f2b9d7 847 }
eac9fcd2
GS
848 if (ret != SR_OK)
849 return ret;
13f2b9d7 850
89280b1a 851 /* Add digital channels. */
13f2b9d7 852 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 853 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 854 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 855
2d224dba
GS
856 group = i / 8;
857 devc->digital_groups[group]->channels = g_slist_append(
858 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
859 }
860
861 devc->model_config = &scope_models[model_index];
d779dcac 862 devc->samples_limit = 0;
13f2b9d7
DJ
863 devc->frame_limit = 0;
864
865 if (!(devc->model_state = scope_state_new(devc->model_config)))
866 return SR_ERR_MALLOC;
867
868 return SR_OK;
869}
870
e06875b2
GS
871/* Queue data of one channel group, for later submission. */
872SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
873 size_t group, GByteArray *pod_data)
874{
875 size_t size;
876 GByteArray *store;
877 uint8_t *logic_data;
878 size_t idx, logic_step;
879
880 /*
881 * Upon first invocation, allocate the array which can hold the
882 * combined logic data for all channels. Assume that each channel
883 * will yield an identical number of samples per receive call.
884 *
885 * As a poor man's safety measure: (Silently) skip processing
886 * for unexpected sample counts, and ignore samples for
887 * unexpected channel groups. Don't bother with complicated
888 * resize logic, considering that many models only support one
889 * pod, and the most capable supported models have two pods of
890 * identical size. We haven't yet seen any "odd" configuration.
891 */
892 if (!devc->logic_data) {
893 size = pod_data->len * devc->pod_count;
894 store = g_byte_array_sized_new(size);
895 memset(store->data, 0, size);
896 store = g_byte_array_set_size(store, size);
897 devc->logic_data = store;
898 } else {
899 store = devc->logic_data;
900 size = store->len / devc->pod_count;
e06875b2
GS
901 if (group >= devc->pod_count)
902 return;
903 }
904
905 /*
906 * Fold the data of the most recently received channel group into
907 * the storage, where data resides for all channels combined.
908 */
909 logic_data = store->data;
910 logic_data += group;
911 logic_step = devc->pod_count;
912 for (idx = 0; idx < pod_data->len; idx++) {
913 *logic_data = pod_data->data[idx];
914 logic_data += logic_step;
915 }
d779dcac
GT
916
917 /* Truncate acquisition if a smaller number of samples has been requested. */
918 if (devc->samples_limit > 0 && devc->logic_data->len > devc->samples_limit * devc->pod_count)
919 devc->logic_data->len = devc->samples_limit * devc->pod_count;
e06875b2
GS
920}
921
922/* Submit data for all channels, after the individual groups got collected. */
923SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
924 struct dev_context *devc)
925{
926 struct sr_datafeed_packet packet;
927 struct sr_datafeed_logic logic;
928
929 if (!devc->logic_data)
930 return;
931
932 logic.data = devc->logic_data->data;
933 logic.length = devc->logic_data->len;
934 logic.unitsize = devc->pod_count;
935
936 packet.type = SR_DF_LOGIC;
937 packet.payload = &logic;
938
939 sr_session_send(sdi, &packet);
940}
941
942/* Undo previous resource allocation. */
943SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
944{
945
946 if (devc->logic_data) {
947 g_byte_array_free(devc->logic_data, TRUE);
948 devc->logic_data = NULL;
949 }
950 /*
951 * Keep 'pod_count'! It's required when more frames will be
952 * received, and does not harm when kept after acquisition.
953 */
954}
955
719eff68 956SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 957{
ba7dd8bb 958 struct sr_channel *ch;
13f2b9d7 959 struct sr_dev_inst *sdi;
06a3e78a 960 struct dev_context *devc;
401b83a1 961 struct scope_state *state;
13f2b9d7 962 struct sr_datafeed_packet packet;
401b83a1
SB
963 GByteArray *data;
964 struct sr_datafeed_analog analog;
965 struct sr_analog_encoding encoding;
966 struct sr_analog_meaning meaning;
967 struct sr_analog_spec spec;
89280b1a 968 struct sr_datafeed_logic logic;
e06875b2 969 size_t group;
06a3e78a
DJ
970
971 (void)fd;
f0729866 972 (void)revents;
06a3e78a 973
f62f595b
MK
974 data = NULL;
975
06a3e78a
DJ
976 if (!(sdi = cb_data))
977 return TRUE;
978
979 if (!(devc = sdi->priv))
980 return TRUE;
981
f4f273ce
SB
982 /* Although this is correct in general, the USBTMC libusb implementation
983 * currently does not generate an event prior to the first read. Often
984 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
985 if (revents != G_IO_IN)
986 return TRUE;
f4f273ce 987 */
13f2b9d7 988
dc89faea 989 ch = devc->current_channel->data;
401b83a1 990 state = devc->model_state;
13f2b9d7 991
b23eb1d4
GS
992 /*
993 * Send "frame begin" packet upon reception of data for the
994 * first enabled channel.
995 */
996 if (devc->current_channel == devc->enabled_channels) {
997 packet.type = SR_DF_FRAME_BEGIN;
998 sr_session_send(sdi, &packet);
999 }
1000
1001 /*
1002 * Pass on the received data of the channel(s).
1003 */
dc89faea
UH
1004 switch (ch->type) {
1005 case SR_CHANNEL_ANALOG:
401b83a1 1006 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 1007 if (data)
401b83a1 1008 g_byte_array_free(data, TRUE);
dc89faea 1009 return TRUE;
13f2b9d7
DJ
1010 }
1011
401b83a1
SB
1012 packet.type = SR_DF_ANALOG;
1013
1014 analog.data = data->data;
1015 analog.num_samples = data->len / sizeof(float);
d779dcac
GT
1016 /* Truncate acquisition if a smaller number of samples has been requested. */
1017 if (devc->samples_limit > 0 && analog.num_samples > devc->samples_limit)
1018 analog.num_samples = devc->samples_limit;
401b83a1
SB
1019 analog.encoding = &encoding;
1020 analog.meaning = &meaning;
1021 analog.spec = &spec;
1022
1023 encoding.unitsize = sizeof(float);
1024 encoding.is_signed = TRUE;
1025 encoding.is_float = TRUE;
65a6794e
GS
1026#ifdef WORDS_BIGENDIAN
1027 encoding.is_bigendian = TRUE;
1028#else
d1ad8b10 1029 encoding.is_bigendian = FALSE;
65a6794e 1030#endif
7dcaddd3
UH
1031 /* TODO: Use proper 'digits' value for this device (and its modes). */
1032 encoding.digits = 2;
401b83a1
SB
1033 encoding.is_digits_decimal = FALSE;
1034 encoding.scale.p = 1;
1035 encoding.scale.q = 1;
1036 encoding.offset.p = 0;
1037 encoding.offset.q = 1;
1038 if (state->analog_channels[ch->index].probe_unit == 'V') {
1039 meaning.mq = SR_MQ_VOLTAGE;
1040 meaning.unit = SR_UNIT_VOLT;
1041 } else {
1042 meaning.mq = SR_MQ_CURRENT;
1043 meaning.unit = SR_UNIT_AMPERE;
1044 }
1045 meaning.mqflags = 0;
1046 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
1047 /* TODO: Use proper 'digits' value for this device (and its modes). */
1048 spec.spec_digits = 2;
dc89faea 1049 packet.payload = &analog;
695dc859 1050 sr_session_send(sdi, &packet);
d779dcac 1051 devc->num_samples = data->len / sizeof(float);
401b83a1
SB
1052 g_slist_free(meaning.channels);
1053 g_byte_array_free(data, TRUE);
dc89faea
UH
1054 data = NULL;
1055 break;
1056 case SR_CHANNEL_LOGIC:
401b83a1 1057 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
14cb6aa4
GT
1058 if (data)
1059 g_byte_array_free(data, TRUE);
dc89faea 1060 return TRUE;
13f2b9d7 1061 }
dc89faea 1062
e06875b2
GS
1063 /*
1064 * If only data from the first pod is involved in the
1065 * acquisition, then the raw input bytes can get passed
1066 * forward for performance reasons. When the second pod
1067 * is involved (either alone, or in combination with the
1068 * first pod), then the received bytes need to be put
1069 * into memory in such a layout that all channel groups
1070 * get combined, and a unitsize larger than a single byte
1071 * applies. The "queue" logic transparently copes with
1072 * any such configuration. This works around the lack
1073 * of support for "meaning" to logic data, which is used
1074 * above for analog data.
1075 */
1076 if (devc->pod_count == 1) {
1077 packet.type = SR_DF_LOGIC;
1078 logic.data = data->data;
1079 logic.length = data->len;
d779dcac
GT
1080 /* Truncate acquisition if a smaller number of samples has been requested. */
1081 if (devc->samples_limit > 0 && logic.length > devc->samples_limit)
1082 logic.length = devc->samples_limit;
e06875b2
GS
1083 logic.unitsize = 1;
1084 packet.payload = &logic;
1085 sr_session_send(sdi, &packet);
1086 } else {
1087 group = ch->index / 8;
1088 hmo_queue_logic_data(devc, group, data);
1089 }
dc89faea 1090
d779dcac 1091 devc->num_samples = data->len / devc->pod_count;
401b83a1 1092 g_byte_array_free(data, TRUE);
dc89faea
UH
1093 data = NULL;
1094 break;
1095 default:
1096 sr_err("Invalid channel type.");
1097 break;
1098 }
1099
b23eb1d4
GS
1100 /*
1101 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
1102 * channels was received, then flush potentially queued logic data,
1103 * and send the "frame end" packet.
b23eb1d4 1104 */
dc89faea
UH
1105 if (devc->current_channel->next) {
1106 devc->current_channel = devc->current_channel->next;
1107 hmo_request_data(sdi);
b23eb1d4
GS
1108 return TRUE;
1109 }
e06875b2
GS
1110 hmo_send_logic_packet(sdi, devc);
1111
1112 /*
1113 * Release the logic data storage after each frame. This copes
1114 * with sample counts that differ in length per frame. -- Is
1115 * this a real constraint when acquiring multiple frames with
1116 * identical device settings?
1117 */
1118 hmo_cleanup_logic_data(devc);
1119
b23eb1d4
GS
1120 packet.type = SR_DF_FRAME_END;
1121 sr_session_send(sdi, &packet);
1122
1123 /*
1124 * End of frame was reached. Stop acquisition after the specified
d779dcac
GT
1125 * number of frames or after the specified number of samples, or
1126 * continue reception by starting over at the first enabled channel.
b23eb1d4 1127 */
d779dcac 1128 if (++devc->num_frames >= devc->frame_limit || devc->num_samples >= devc->samples_limit) {
d2f7c417 1129 sr_dev_acquisition_stop(sdi);
e06875b2 1130 hmo_cleanup_logic_data(devc);
dc89faea
UH
1131 } else {
1132 devc->current_channel = devc->enabled_channels;
1133 hmo_request_data(sdi);
06a3e78a
DJ
1134 }
1135
1136 return TRUE;
1137}