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