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