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