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