]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Send exactly one sigrok frame per scope frame
[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
26static const char *hameg_scpi_dialect[] = {
27 [SCPI_CMD_GET_DIG_DATA] = ":FORM UINT,8;:POD%d:DATA?",
28 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
29 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
30 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
31 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
32 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
33 [SCPI_CMD_GET_SAMPLE_RATE_LIVE] = ":%s:DATA:POINTS?",
34 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
35 ":FORM REAL,32;:CHAN%d:DATA?",
36 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
37 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
38 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
39 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
40 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
41 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP %s",
42 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
43 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
44 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
45 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
46 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
47 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
48 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
49 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
50 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
51 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
52};
53
54static const uint32_t hmo_devopts[] = {
55 SR_CONF_OSCILLOSCOPE,
56 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
57 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
58 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
59 SR_CONF_NUM_HDIV | SR_CONF_GET,
60 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
61 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
62 SR_CONF_SAMPLERATE | SR_CONF_GET,
63};
64
65static const uint32_t hmo_analog_devopts[] = {
66 SR_CONF_NUM_VDIV | SR_CONF_GET,
67 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
68 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
69};
70
71static const char *hmo_coupling_options[] = {
72 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
73 "ACL", // AC with 1 MOhm termination
74 "DC", // DC with 50 Ohm termination
75 "DCL", // DC with 1 MOhm termination
76 "GND",
77 NULL,
78};
79
80static const char *scope_trigger_slopes[] = {
81 "POS",
82 "NEG",
83 "EITH",
84 NULL,
85};
86
87static const char *hmo_compact2_trigger_sources[] = {
88 "CH1",
89 "CH2",
90 "LINE",
91 "EXT",
92 "PATT",
93 "BUS1",
94 "BUS2",
95 "D0",
96 "D1",
97 "D2",
98 "D3",
99 "D4",
100 "D5",
101 "D6",
102 "D7",
103 NULL,
104};
105
106static const char *hmo_compact4_trigger_sources[] = {
107 "CH1",
108 "CH2",
109 "CH3",
110 "CH4",
111 "LINE",
112 "EXT",
113 "PATT",
114 "BUS1",
115 "BUS2",
116 "D0",
117 "D1",
118 "D2",
119 "D3",
120 "D4",
121 "D5",
122 "D6",
123 "D7",
124 NULL,
125};
126
127static const char *hmo_compact4_dig16_trigger_sources[] = {
128 "CH1",
129 "CH2",
130 "CH3",
131 "CH4",
132 "LINE",
133 "EXT",
134 "PATT",
135 "BUS1",
136 "BUS2",
137 "D0",
138 "D1",
139 "D2",
140 "D3",
141 "D4",
142 "D5",
143 "D6",
144 "D7",
145 "D8",
146 "D9",
147 "D10",
148 "D11",
149 "D12",
150 "D13",
151 "D14",
152 "D15",
153 NULL,
154};
155
156static const uint64_t hmo_timebases[][2] = {
157 /* nanoseconds */
158 { 2, 1000000000 },
159 { 5, 1000000000 },
160 { 10, 1000000000 },
161 { 20, 1000000000 },
162 { 50, 1000000000 },
163 { 100, 1000000000 },
164 { 200, 1000000000 },
165 { 500, 1000000000 },
166 /* microseconds */
167 { 1, 1000000 },
168 { 2, 1000000 },
169 { 5, 1000000 },
170 { 10, 1000000 },
171 { 20, 1000000 },
172 { 50, 1000000 },
173 { 100, 1000000 },
174 { 200, 1000000 },
175 { 500, 1000000 },
176 /* milliseconds */
177 { 1, 1000 },
178 { 2, 1000 },
179 { 5, 1000 },
180 { 10, 1000 },
181 { 20, 1000 },
182 { 50, 1000 },
183 { 100, 1000 },
184 { 200, 1000 },
185 { 500, 1000 },
186 /* seconds */
187 { 1, 1 },
188 { 2, 1 },
189 { 5, 1 },
190 { 10, 1 },
191 { 20, 1 },
192 { 50, 1 },
193};
194
195static const uint64_t hmo_vdivs[][2] = {
196 /* millivolts */
197 { 1, 1000 },
198 { 2, 1000 },
199 { 5, 1000 },
200 { 10, 1000 },
201 { 20, 1000 },
202 { 50, 1000 },
203 { 100, 1000 },
204 { 200, 1000 },
205 { 500, 1000 },
206 /* volts */
207 { 1, 1 },
208 { 2, 1 },
209 { 5, 1 },
210 { 10, 1 },
211 { 20, 1 },
212 { 50, 1 },
213};
214
215static const char *scope_analog_channel_names[] = {
216 "CH1",
217 "CH2",
218 "CH3",
219 "CH4",
220};
221
222static const char *scope_digital_channel_names[] = {
223 "D0",
224 "D1",
225 "D2",
226 "D3",
227 "D4",
228 "D5",
229 "D6",
230 "D7",
231 "D8",
232 "D9",
233 "D10",
234 "D11",
235 "D12",
236 "D13",
237 "D14",
238 "D15",
239};
240
241static const struct scope_config scope_models[] = {
242 {
243 /* HMO2522/3032/3042/3052 support 16 digital channels but they're not supported yet. */
244 .name = {"HMO1002", "HMO722", "HMO1022", "HMO1522", "HMO2022", "HMO2522",
245 "HMO3032", "HMO3042", "HMO3052", NULL},
246 .analog_channels = 2,
247 .digital_channels = 8,
248 .digital_pods = 1,
249
250 .analog_names = &scope_analog_channel_names,
251 .digital_names = &scope_digital_channel_names,
252
253 .devopts = &hmo_devopts,
254 .num_devopts = ARRAY_SIZE(hmo_devopts),
255
256 .analog_devopts = &hmo_analog_devopts,
257 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
258
259 .coupling_options = &hmo_coupling_options,
260 .trigger_sources = &hmo_compact2_trigger_sources,
261 .trigger_slopes = &scope_trigger_slopes,
262
263 .timebases = &hmo_timebases,
264 .num_timebases = ARRAY_SIZE(hmo_timebases),
265
266 .vdivs = &hmo_vdivs,
267 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
268
269 .num_xdivs = 12,
270 .num_ydivs = 8,
271
272 .scpi_dialect = &hameg_scpi_dialect,
273 },
274 {
275 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
276 .analog_channels = 4,
277 .digital_channels = 8,
278 .digital_pods = 1,
279
280 .analog_names = &scope_analog_channel_names,
281 .digital_names = &scope_digital_channel_names,
282
283 .devopts = &hmo_devopts,
284 .num_devopts = ARRAY_SIZE(hmo_devopts),
285
286 .analog_devopts = &hmo_analog_devopts,
287 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
288
289 .coupling_options = &hmo_coupling_options,
290 .trigger_sources = &hmo_compact4_trigger_sources,
291 .trigger_slopes = &scope_trigger_slopes,
292
293 .timebases = &hmo_timebases,
294 .num_timebases = ARRAY_SIZE(hmo_timebases),
295
296 .vdivs = &hmo_vdivs,
297 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
298
299 .num_xdivs = 12,
300 .num_ydivs = 8,
301
302 .scpi_dialect = &hameg_scpi_dialect,
303 },
304 {
305 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", NULL},
306 .analog_channels = 4,
307 .digital_channels = 16,
308 .digital_pods = 2,
309
310 .analog_names = &scope_analog_channel_names,
311 .digital_names = &scope_digital_channel_names,
312
313 .devopts = &hmo_devopts,
314 .num_devopts = ARRAY_SIZE(hmo_devopts),
315
316 .analog_devopts = &hmo_analog_devopts,
317 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
318
319 .coupling_options = &hmo_coupling_options,
320 .trigger_sources = &hmo_compact4_dig16_trigger_sources,
321 .trigger_slopes = &scope_trigger_slopes,
322
323 .timebases = &hmo_timebases,
324 .num_timebases = ARRAY_SIZE(hmo_timebases),
325
326 .vdivs = &hmo_vdivs,
327 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
328
329 .num_xdivs = 12,
330 .num_ydivs = 8,
331
332 .scpi_dialect = &hameg_scpi_dialect,
333 },
334};
335
336static void scope_state_dump(const struct scope_config *config,
337 struct scope_state *state)
338{
339 unsigned int i;
340 char *tmp;
341
342 for (i = 0; i < config->analog_channels; i++) {
343 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
344 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
345 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
346 i + 1, state->analog_channels[i].state ? "On" : "Off",
347 (*config->coupling_options)[state->analog_channels[i].coupling],
348 tmp, state->analog_channels[i].vertical_offset);
349 }
350
351 for (i = 0; i < config->digital_channels; i++) {
352 sr_info("State of digital channel %d -> %s", i,
353 state->digital_channels[i] ? "On" : "Off");
354 }
355
356 for (i = 0; i < config->digital_pods; i++) {
357 sr_info("State of digital POD %d -> %s", i,
358 state->digital_pods[i] ? "On" : "Off");
359 }
360
361 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
362 (*config->timebases)[state->timebase][1]);
363 sr_info("Current timebase: %s", tmp);
364 g_free(tmp);
365
366 tmp = sr_samplerate_string(state->sample_rate);
367 sr_info("Current samplerate: %s", tmp);
368 g_free(tmp);
369
370 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
371 (*config->trigger_sources)[state->trigger_source],
372 (*config->trigger_slopes)[state->trigger_slope],
373 state->horiz_triggerpos);
374}
375
376static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
377 const char *command, const char *(*array)[], int *result)
378{
379 char *tmp;
380 unsigned int i;
381
382 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
383 g_free(tmp);
384 return SR_ERR;
385 }
386
387 for (i = 0; (*array)[i]; i++) {
388 if (!g_strcmp0(tmp, (*array)[i])) {
389 *result = i;
390 g_free(tmp);
391 tmp = NULL;
392 break;
393 }
394 }
395
396 if (tmp) {
397 g_free(tmp);
398 return SR_ERR;
399 }
400
401 return SR_OK;
402}
403
404/**
405 * This function takes a value of the form "2.000E-03" and returns the index
406 * of an array where a matching pair was found.
407 *
408 * @param value The string to be parsed.
409 * @param array The array of s/f pairs.
410 * @param array_len The number of pairs in the array.
411 * @param result The index at which a matching pair was found.
412 *
413 * @return SR_ERR on any parsing error, SR_OK otherwise.
414 */
415static int array_float_get(gchar *value, const uint64_t array[][2],
416 int array_len, unsigned int *result)
417{
418 struct sr_rational rval;
419 struct sr_rational aval;
420
421 if (sr_parse_rational(value, &rval) != SR_OK)
422 return SR_ERR;
423
424 for (int i = 0; i < array_len; i++) {
425 sr_rational_set(&aval, array[i][0], array[i][1]);
426 if (sr_rational_eq(&rval, &aval)) {
427 *result = i;
428 return SR_OK;
429 }
430 }
431
432 return SR_ERR;
433}
434
435static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
436 const struct scope_config *config,
437 struct scope_state *state)
438{
439 unsigned int i, j;
440 char command[MAX_COMMAND_SIZE];
441 char *tmp_str;
442
443 for (i = 0; i < config->analog_channels; i++) {
444 g_snprintf(command, sizeof(command),
445 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
446 i + 1);
447
448 if (sr_scpi_get_bool(scpi, command,
449 &state->analog_channels[i].state) != SR_OK)
450 return SR_ERR;
451
452 g_snprintf(command, sizeof(command),
453 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
454 i + 1);
455
456 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
457 return SR_ERR;
458
459 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
460 &j) != SR_OK) {
461 g_free(tmp_str);
462 sr_err("Could not determine array index for vertical div scale.");
463 return SR_ERR;
464 }
465
466 g_free(tmp_str);
467 state->analog_channels[i].vdiv = j;
468
469 g_snprintf(command, sizeof(command),
470 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
471 i + 1);
472
473 if (sr_scpi_get_float(scpi, command,
474 &state->analog_channels[i].vertical_offset) != SR_OK)
475 return SR_ERR;
476
477 g_snprintf(command, sizeof(command),
478 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
479 i + 1);
480
481 if (scope_state_get_array_option(scpi, command, config->coupling_options,
482 &state->analog_channels[i].coupling) != SR_OK)
483 return SR_ERR;
484
485 g_snprintf(command, sizeof(command),
486 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
487 i + 1);
488
489 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
490 return SR_ERR;
491
492 if (tmp_str[0] == 'A')
493 state->analog_channels[i].probe_unit = 'A';
494 else
495 state->analog_channels[i].probe_unit = 'V';
496 g_free(tmp_str);
497 }
498
499 return SR_OK;
500}
501
502static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
503 const struct scope_config *config,
504 struct scope_state *state)
505{
506 unsigned int i;
507 char command[MAX_COMMAND_SIZE];
508
509 for (i = 0; i < config->digital_channels; i++) {
510 g_snprintf(command, sizeof(command),
511 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
512 i);
513
514 if (sr_scpi_get_bool(scpi, command,
515 &state->digital_channels[i]) != SR_OK)
516 return SR_ERR;
517 }
518
519 for (i = 0; i < config->digital_pods; i++) {
520 g_snprintf(command, sizeof(command),
521 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
522 i + 1);
523
524 if (sr_scpi_get_bool(scpi, command,
525 &state->digital_pods[i]) != SR_OK)
526 return SR_ERR;
527 }
528
529 return SR_OK;
530}
531
532SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
533{
534 struct dev_context *devc;
535 struct scope_state *state;
536 const struct scope_config *config;
537
538 int tmp;
539 unsigned int i;
540 float tmp_float;
541 gboolean channel_found;
542 char tmp_str[MAX_COMMAND_SIZE];
543 char chan_name[20];
544
545 devc = sdi->priv;
546 config = devc->model_config;
547 state = devc->model_state;
548 channel_found = FALSE;
549
550 for (i = 0; i < config->analog_channels; i++) {
551 if (state->analog_channels[i].state) {
552 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
553 g_snprintf(tmp_str, sizeof(tmp_str),
554 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
555 chan_name);
556 channel_found = TRUE;
557 break;
558 }
559 }
560
561 if (!channel_found) {
562 for (i = 0; i < config->digital_pods; i++) {
563 if (state->digital_pods[i]) {
564 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
565 g_snprintf(tmp_str, sizeof(tmp_str),
566 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
567 chan_name);
568 channel_found = TRUE;
569 break;
570 }
571 }
572 }
573
574 /* No channel is active, ask the instrument for the sample rate
575 * in single shot mode */
576 if (!channel_found) {
577 if (sr_scpi_get_float(sdi->conn,
578 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
579 &tmp_float) != SR_OK)
580 return SR_ERR;
581
582 state->sample_rate = tmp_float;
583 } else {
584 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
585 return SR_ERR;
586 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
587 (*config->timebases)[state->timebase][1]) *
588 config->num_xdivs);
589 }
590
591 return SR_OK;
592}
593
594SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
595{
596 struct dev_context *devc;
597 struct scope_state *state;
598 const struct scope_config *config;
599 float tmp_float;
600 unsigned int i;
601 char *tmp_str;
602
603 devc = sdi->priv;
604 config = devc->model_config;
605 state = devc->model_state;
606
607 sr_info("Fetching scope state");
608
609 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
610 return SR_ERR;
611
612 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
613 return SR_ERR;
614
615 if (sr_scpi_get_float(sdi->conn,
616 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
617 &tmp_float) != SR_OK)
618 return SR_ERR;
619
620 if (sr_scpi_get_string(sdi->conn,
621 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
622 &tmp_str) != SR_OK)
623 return SR_ERR;
624
625 if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
626 &i) != SR_OK) {
627 g_free(tmp_str);
628 sr_err("Could not determine array index for time base.");
629 return SR_ERR;
630 }
631 g_free(tmp_str);
632
633 state->timebase = i;
634
635 if (sr_scpi_get_float(sdi->conn,
636 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
637 &tmp_float) != SR_OK)
638 return SR_ERR;
639 state->horiz_triggerpos = tmp_float /
640 (((double) (*config->timebases)[state->timebase][0] /
641 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
642 state->horiz_triggerpos -= 0.5;
643 state->horiz_triggerpos *= -1;
644
645 if (scope_state_get_array_option(sdi->conn,
646 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
647 config->trigger_sources, &state->trigger_source) != SR_OK)
648 return SR_ERR;
649
650 if (scope_state_get_array_option(sdi->conn,
651 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
652 config->trigger_slopes, &state->trigger_slope) != SR_OK)
653 return SR_ERR;
654
655 if (hmo_update_sample_rate(sdi) != SR_OK)
656 return SR_ERR;
657
658 sr_info("Fetching finished.");
659
660 scope_state_dump(config, state);
661
662 return SR_OK;
663}
664
665static struct scope_state *scope_state_new(const struct scope_config *config)
666{
667 struct scope_state *state;
668
669 state = g_malloc0(sizeof(struct scope_state));
670 state->analog_channels = g_malloc0_n(config->analog_channels,
671 sizeof(struct analog_channel_state));
672 state->digital_channels = g_malloc0_n(
673 config->digital_channels, sizeof(gboolean));
674 state->digital_pods = g_malloc0_n(config->digital_pods,
675 sizeof(gboolean));
676
677 return state;
678}
679
680SR_PRIV void hmo_scope_state_free(struct scope_state *state)
681{
682 g_free(state->analog_channels);
683 g_free(state->digital_channels);
684 g_free(state->digital_pods);
685 g_free(state);
686}
687
688SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
689{
690 char tmp[25];
691 int model_index;
692 unsigned int i, j, group;
693 struct sr_channel *ch;
694 struct dev_context *devc;
695
696 devc = sdi->priv;
697 model_index = -1;
698
699 /* Find the exact model. */
700 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
701 for (j = 0; scope_models[i].name[j]; j++) {
702 if (!strcmp(sdi->model, scope_models[i].name[j])) {
703 model_index = i;
704 break;
705 }
706 }
707 if (model_index != -1)
708 break;
709 }
710
711 if (model_index == -1) {
712 sr_dbg("Unsupported HMO device.");
713 return SR_ERR_NA;
714 }
715
716 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
717 scope_models[model_index].analog_channels);
718
719 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
720 scope_models[model_index].digital_pods);
721
722 /* Add analog channels. */
723 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
724 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
725 (*scope_models[model_index].analog_names)[i]);
726
727 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
728
729 devc->analog_groups[i]->name = g_strdup(
730 (char *)(*scope_models[model_index].analog_names)[i]);
731 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
732
733 sdi->channel_groups = g_slist_append(sdi->channel_groups,
734 devc->analog_groups[i]);
735 }
736
737 /* Add digital channel groups. */
738 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
739 g_snprintf(tmp, 25, "POD%d", i);
740
741 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
742
743 devc->digital_groups[i]->name = g_strdup(tmp);
744 sdi->channel_groups = g_slist_append(sdi->channel_groups,
745 devc->digital_groups[i]);
746 }
747
748 /* Add digital channels. */
749 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
750 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
751 (*scope_models[model_index].digital_names)[i]);
752
753 group = i / 8;
754 devc->digital_groups[group]->channels = g_slist_append(
755 devc->digital_groups[group]->channels, ch);
756 }
757
758 devc->model_config = &scope_models[model_index];
759 devc->frame_limit = 0;
760
761 if (!(devc->model_state = scope_state_new(devc->model_config)))
762 return SR_ERR_MALLOC;
763
764 return SR_OK;
765}
766
767SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
768{
769 struct sr_channel *ch;
770 struct sr_dev_inst *sdi;
771 struct dev_context *devc;
772 struct scope_state *state;
773 struct sr_datafeed_packet packet;
774 GByteArray *data;
775 struct sr_datafeed_analog analog;
776 struct sr_analog_encoding encoding;
777 struct sr_analog_meaning meaning;
778 struct sr_analog_spec spec;
779 struct sr_datafeed_logic logic;
780
781 (void)fd;
782 (void)revents;
783
784 data = NULL;
785
786 if (!(sdi = cb_data))
787 return TRUE;
788
789 if (!(devc = sdi->priv))
790 return TRUE;
791
792 /* Although this is correct in general, the USBTMC libusb implementation
793 * currently does not generate an event prior to the first read. Often
794 * it is ok to start reading just after the 50ms timeout. See bug #785.
795 if (revents != G_IO_IN)
796 return TRUE;
797 */
798
799 ch = devc->current_channel->data;
800 state = devc->model_state;
801
802 /*
803 * Send "frame begin" packet upon reception of data for the
804 * first enabled channel.
805 */
806 if (devc->current_channel == devc->enabled_channels) {
807 packet.type = SR_DF_FRAME_BEGIN;
808 sr_session_send(sdi, &packet);
809 }
810
811 /*
812 * Pass on the received data of the channel(s).
813 */
814 switch (ch->type) {
815 case SR_CHANNEL_ANALOG:
816 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
817 if (data)
818 g_byte_array_free(data, TRUE);
819
820 return TRUE;
821 }
822
823 packet.type = SR_DF_ANALOG;
824
825 analog.data = data->data;
826 analog.num_samples = data->len / sizeof(float);
827 analog.encoding = &encoding;
828 analog.meaning = &meaning;
829 analog.spec = &spec;
830
831 encoding.unitsize = sizeof(float);
832 encoding.is_signed = TRUE;
833 encoding.is_float = TRUE;
834#ifdef WORDS_BIGENDIAN
835 encoding.is_bigendian = TRUE;
836#else
837 encoding.is_bigendian = FALSE;
838#endif
839 /* TODO: Use proper 'digits' value for this device (and its modes). */
840 encoding.digits = 2;
841 encoding.is_digits_decimal = FALSE;
842 encoding.scale.p = 1;
843 encoding.scale.q = 1;
844 encoding.offset.p = 0;
845 encoding.offset.q = 1;
846 if (state->analog_channels[ch->index].probe_unit == 'V') {
847 meaning.mq = SR_MQ_VOLTAGE;
848 meaning.unit = SR_UNIT_VOLT;
849 } else {
850 meaning.mq = SR_MQ_CURRENT;
851 meaning.unit = SR_UNIT_AMPERE;
852 }
853 meaning.mqflags = 0;
854 meaning.channels = g_slist_append(NULL, ch);
855 /* TODO: Use proper 'digits' value for this device (and its modes). */
856 spec.spec_digits = 2;
857 packet.payload = &analog;
858 sr_session_send(sdi, &packet);
859 g_slist_free(meaning.channels);
860 g_byte_array_free(data, TRUE);
861 data = NULL;
862 break;
863 case SR_CHANNEL_LOGIC:
864 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
865 g_free(data);
866 return TRUE;
867 }
868
869
870 logic.length = data->len;
871 logic.unitsize = 1;
872 logic.data = data->data;
873 packet.type = SR_DF_LOGIC;
874 packet.payload = &logic;
875 sr_session_send(sdi, &packet);
876 g_byte_array_free(data, TRUE);
877 data = NULL;
878 break;
879 default:
880 sr_err("Invalid channel type.");
881 break;
882 }
883
884 /*
885 * Advance to the next enabled channel. When data for all enabled
886 * channels was received, then send the "frame end" packet.
887 */
888 if (devc->current_channel->next) {
889 devc->current_channel = devc->current_channel->next;
890 hmo_request_data(sdi);
891 return TRUE;
892 }
893 packet.type = SR_DF_FRAME_END;
894 sr_session_send(sdi, &packet);
895
896 /*
897 * End of frame was reached. Stop acquisition after the specified
898 * number of frames, or continue reception by starting over at
899 * the first enabled channel.
900 */
901 if (++devc->num_frames == devc->frame_limit) {
902 sdi->driver->dev_acquisition_stop(sdi);
903 } else {
904 devc->current_channel = devc->enabled_channels;
905 hmo_request_data(sdi);
906 }
907
908 return TRUE;
909}