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