]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/hameg-hmo/protocol.c
scope drivers: More consistent config key ordering.
[libsigrok.git] / src / hardware / hameg-hmo / protocol.c
... / ...
CommitLineData
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
20#include <config.h>
21#include <math.h>
22#include <stdlib.h>
23#include "scpi.h"
24#include "protocol.h"
25
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
32static const char *hameg_scpi_dialect[] = {
33 [SCPI_CMD_GET_DIG_DATA] = ":FORM UINT,8;:POD%d:DATA?",
34 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
35 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
36 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
37 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
38 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
39 [SCPI_CMD_GET_SAMPLE_RATE_LIVE] = ":%s:DATA:POINTS?",
40 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
41 ":FORM REAL,32;:CHAN%d:DATA?",
42 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
43 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
44 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
45 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
46 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
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?",
54 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
55 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
56 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
57 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
58};
59
60static const uint32_t hmo_devopts[] = {
61 SR_CONF_OSCILLOSCOPE,
62 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
63 SR_CONF_SAMPLERATE | SR_CONF_GET,
64 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
65 SR_CONF_NUM_HDIV | SR_CONF_GET,
66 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
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,
69};
70
71static const uint32_t hmo_analog_devopts[] = {
72 SR_CONF_NUM_VDIV | SR_CONF_GET,
73 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
74 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
75};
76
77static const char *hmo_coupling_options[] = {
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
82 "GND",
83 NULL,
84};
85
86static const char *scope_trigger_slopes[] = {
87 "POS",
88 "NEG",
89 "EITH",
90 NULL,
91};
92
93static const char *hmo_compact2_trigger_sources[] = {
94 "CH1",
95 "CH2",
96 "LINE",
97 "EXT",
98 "PATT",
99 "BUS1",
100 "BUS2",
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",
119 "PATT",
120 "BUS1",
121 "BUS2",
122 "D0",
123 "D1",
124 "D2",
125 "D3",
126 "D4",
127 "D5",
128 "D6",
129 "D7",
130 NULL,
131};
132
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
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 },
217 { 20, 1 },
218 { 50, 1 },
219};
220
221static const char *scope_analog_channel_names[] = {
222 "CH1",
223 "CH2",
224 "CH3",
225 "CH4",
226};
227
228static const char *scope_digital_channel_names[] = {
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
247static const struct scope_config scope_models[] = {
248 {
249 /* HMO2522/3032/3042/3052 support 16 digital channels but they're not supported yet. */
250 .name = {"HMO1002", "HMO722", "HMO1022", "HMO1522", "HMO2022", "HMO2522",
251 "HMO3032", "HMO3042", "HMO3052", NULL},
252 .analog_channels = 2,
253 .digital_channels = 8,
254 .digital_pods = 1,
255
256 .analog_names = &scope_analog_channel_names,
257 .digital_names = &scope_digital_channel_names,
258
259 .devopts = &hmo_devopts,
260 .num_devopts = ARRAY_SIZE(hmo_devopts),
261
262 .analog_devopts = &hmo_analog_devopts,
263 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
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 {
281 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
282 .analog_channels = 4,
283 .digital_channels = 8,
284 .digital_pods = 1,
285
286 .analog_names = &scope_analog_channel_names,
287 .digital_names = &scope_digital_channel_names,
288
289 .devopts = &hmo_devopts,
290 .num_devopts = ARRAY_SIZE(hmo_devopts),
291
292 .analog_devopts = &hmo_analog_devopts,
293 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
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
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
338 .scpi_dialect = &hameg_scpi_dialect,
339 },
340};
341
342static void scope_state_dump(const struct scope_config *config,
343 struct scope_state *state)
344{
345 unsigned int i;
346 char *tmp;
347
348 for (i = 0; i < config->analog_channels; i++) {
349 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
350 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
351 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
352 i + 1, state->analog_channels[i].state ? "On" : "Off",
353 (*config->coupling_options)[state->analog_channels[i].coupling],
354 tmp, state->analog_channels[i].vertical_offset);
355 }
356
357 for (i = 0; i < config->digital_channels; i++) {
358 sr_info("State of digital channel %d -> %s", i,
359 state->digital_channels[i] ? "On" : "Off");
360 }
361
362 for (i = 0; i < config->digital_pods; i++) {
363 sr_info("State of digital POD %d -> %s", i,
364 state->digital_pods[i] ? "On" : "Off");
365 }
366
367 tmp = sr_period_string((*config->timebases)[state->timebase][0],
368 (*config->timebases)[state->timebase][1]);
369 sr_info("Current timebase: %s", tmp);
370 g_free(tmp);
371
372 tmp = sr_samplerate_string(state->sample_rate);
373 sr_info("Current samplerate: %s", tmp);
374 g_free(tmp);
375
376 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
377 (*config->trigger_sources)[state->trigger_source],
378 (*config->trigger_slopes)[state->trigger_slope],
379 state->horiz_triggerpos);
380}
381
382static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
383 const char *command, const char *(*array)[], int *result)
384{
385 char *tmp;
386 unsigned int i;
387
388 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
389 g_free(tmp);
390 return SR_ERR;
391 }
392
393 for (i = 0; (*array)[i]; i++) {
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
410/**
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.
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],
422 int array_len, unsigned int *result)
423{
424 struct sr_rational rval;
425 struct sr_rational aval;
426
427 if (sr_parse_rational(value, &rval) != SR_OK)
428 return SR_ERR;
429
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)) {
433 *result = i;
434 return SR_OK;
435 }
436 }
437
438 return SR_ERR;
439}
440
441static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
442 const struct scope_config *config,
443 struct scope_state *state)
444{
445 unsigned int i, j;
446 char command[MAX_COMMAND_SIZE];
447 char *tmp_str;
448
449 for (i = 0; i < config->analog_channels; i++) {
450 g_snprintf(command, sizeof(command),
451 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
452 i + 1);
453
454 if (sr_scpi_get_bool(scpi, command,
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
462 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
463 return SR_ERR;
464
465 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
466 &j) != SR_OK) {
467 g_free(tmp_str);
468 sr_err("Could not determine array index for vertical div scale.");
469 return SR_ERR;
470 }
471
472 g_free(tmp_str);
473 state->analog_channels[i].vdiv = j;
474
475 g_snprintf(command, sizeof(command),
476 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
477 i + 1);
478
479 if (sr_scpi_get_float(scpi, command,
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
487 if (scope_state_get_array_option(scpi, command, config->coupling_options,
488 &state->analog_channels[i].coupling) != SR_OK)
489 return SR_ERR;
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);
503 }
504
505 return SR_OK;
506}
507
508static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
509 const struct scope_config *config,
510 struct scope_state *state)
511{
512 unsigned int i;
513 char command[MAX_COMMAND_SIZE];
514
515 for (i = 0; i < config->digital_channels; i++) {
516 g_snprintf(command, sizeof(command),
517 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
518 i);
519
520 if (sr_scpi_get_bool(scpi, command,
521 &state->digital_channels[i]) != SR_OK)
522 return SR_ERR;
523 }
524
525 for (i = 0; i < config->digital_pods; i++) {
526 g_snprintf(command, sizeof(command),
527 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
528 i + 1);
529
530 if (sr_scpi_get_bool(scpi, command,
531 &state->digital_pods[i]) != SR_OK)
532 return SR_ERR;
533 }
534
535 return SR_OK;
536}
537
538SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
539{
540 struct dev_context *devc;
541 struct scope_state *state;
542 const struct scope_config *config;
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
556 for (i = 0; i < config->analog_channels; i++) {
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) {
583 if (sr_scpi_get_float(sdi->conn,
584 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
585 &tmp_float) != SR_OK)
586 return SR_ERR;
587
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
600SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
601{
602 struct dev_context *devc;
603 struct scope_state *state;
604 const struct scope_config *config;
605 float tmp_float;
606 unsigned int i;
607 char *tmp_str;
608
609 devc = sdi->priv;
610 config = devc->model_config;
611 state = devc->model_state;
612
613 sr_info("Fetching scope state");
614
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
621 if (sr_scpi_get_float(sdi->conn,
622 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
623 &tmp_float) != SR_OK)
624 return SR_ERR;
625
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);
634 sr_err("Could not determine array index for time base.");
635 return SR_ERR;
636 }
637 g_free(tmp_str);
638
639 state->timebase = i;
640
641 if (sr_scpi_get_float(sdi->conn,
642 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
643 &tmp_float) != SR_OK)
644 return SR_ERR;
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;
650
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)
654 return SR_ERR;
655
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)
659 return SR_ERR;
660
661 if (hmo_update_sample_rate(sdi) != SR_OK)
662 return SR_ERR;
663
664 sr_info("Fetching finished.");
665
666 scope_state_dump(config, state);
667
668 return SR_OK;
669}
670
671static struct scope_state *scope_state_new(const struct scope_config *config)
672{
673 struct scope_state *state;
674
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));
682
683 return state;
684}
685
686SR_PRIV void hmo_scope_state_free(struct scope_state *state)
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;
698 unsigned int i, j, group;
699 struct sr_channel *ch;
700 struct dev_context *devc;
701
702 devc = sdi->priv;
703 model_index = -1;
704
705 /* Find the exact model. */
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) {
718 sr_dbg("Unsupported HMO device.");
719 return SR_ERR_NA;
720 }
721
722 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
723 scope_models[model_index].analog_channels);
724
725 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
726 scope_models[model_index].digital_pods);
727
728 /* Add analog channels. */
729 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
730 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
731 (*scope_models[model_index].analog_names)[i]);
732
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);
738
739 sdi->channel_groups = g_slist_append(sdi->channel_groups,
740 devc->analog_groups[i]);
741 }
742
743 /* Add digital channel groups. */
744 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
745 g_snprintf(tmp, 25, "POD%d", i);
746
747 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
748
749 devc->digital_groups[i]->name = g_strdup(tmp);
750 sdi->channel_groups = g_slist_append(sdi->channel_groups,
751 devc->digital_groups[i]);
752 }
753
754 /* Add digital channels. */
755 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
756 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
757 (*scope_models[model_index].digital_names)[i]);
758
759 group = i / 8;
760 devc->digital_groups[group]->channels = g_slist_append(
761 devc->digital_groups[group]->channels, ch);
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
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
856SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
857{
858 struct sr_channel *ch;
859 struct sr_dev_inst *sdi;
860 struct dev_context *devc;
861 struct scope_state *state;
862 struct sr_datafeed_packet packet;
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;
868 struct sr_datafeed_logic logic;
869 size_t group;
870
871 (void)fd;
872 (void)revents;
873
874 data = NULL;
875
876 if (!(sdi = cb_data))
877 return TRUE;
878
879 if (!(devc = sdi->priv))
880 return TRUE;
881
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.
885 if (revents != G_IO_IN)
886 return TRUE;
887 */
888
889 ch = devc->current_channel->data;
890 state = devc->model_state;
891
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 */
904 switch (ch->type) {
905 case SR_CHANNEL_ANALOG:
906 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
907 if (data)
908 g_byte_array_free(data, TRUE);
909
910 return TRUE;
911 }
912
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;
924#ifdef WORDS_BIGENDIAN
925 encoding.is_bigendian = TRUE;
926#else
927 encoding.is_bigendian = FALSE;
928#endif
929 /* TODO: Use proper 'digits' value for this device (and its modes). */
930 encoding.digits = 2;
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);
945 /* TODO: Use proper 'digits' value for this device (and its modes). */
946 spec.spec_digits = 2;
947 packet.payload = &analog;
948 sr_session_send(sdi, &packet);
949 g_slist_free(meaning.channels);
950 g_byte_array_free(data, TRUE);
951 data = NULL;
952 break;
953 case SR_CHANNEL_LOGIC:
954 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
955 g_free(data);
956 return TRUE;
957 }
958
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 }
983
984 g_byte_array_free(data, TRUE);
985 data = NULL;
986 break;
987 default:
988 sr_err("Invalid channel type.");
989 break;
990 }
991
992 /*
993 * Advance to the next enabled channel. When data for all enabled
994 * channels was received, then flush potentially queued logic data,
995 * and send the "frame end" packet.
996 */
997 if (devc->current_channel->next) {
998 devc->current_channel = devc->current_channel->next;
999 hmo_request_data(sdi);
1000 return TRUE;
1001 }
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
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) {
1021 sdi->driver->dev_acquisition_stop(sdi);
1022 hmo_cleanup_logic_data(devc);
1023 } else {
1024 devc->current_channel = devc->enabled_channels;
1025 hmo_request_data(sdi);
1026 }
1027
1028 return TRUE;
1029}