]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add PATTern and BUS1/BUS2 trigger sources
[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", converts it to a
347 * significand / factor pair and returns the index of an array where
348 * a matching pair was found.
349 *
350 * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
351 * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
352 * Therefore it's easier to break the number up into two strings and handle
353 * them separately.
354 *
355 * @param value The string to be parsed.
356 * @param array The array of s/f pairs.
357 * @param array_len The number of pairs in the array.
358 * @param result The index at which a matching pair was found.
359 *
360 * @return SR_ERR on any parsing error, SR_OK otherwise.
361 */
362static int array_float_get(gchar *value, const uint64_t array[][2],
363 int array_len, unsigned int *result)
364{
365 int i, e;
366 size_t pos;
367 uint64_t f;
368 float s;
369 unsigned int s_int;
370 gchar ss[10], es[10];
371
372 memset(ss, 0, sizeof(ss));
373 memset(es, 0, sizeof(es));
374
375 /* Get index of the separating 'E' character and break up the string. */
376 pos = strcspn(value, "E");
377
378 strncpy(ss, value, pos);
379 strncpy(es, &(value[pos+1]), 3);
380
381 if (sr_atof_ascii(ss, &s) != SR_OK)
382 return SR_ERR;
383 if (sr_atoi(es, &e) != SR_OK)
384 return SR_ERR;
385
386 /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
387 f = pow(10, abs(e));
388
389 /*
390 * Adjust the significand/factor pair to make sure
391 * that f is a multiple of 1000.
392 */
393 while ((int)fmod(log10(f), 3) > 0) {
394 s *= 10;
395
396 if (e < 0)
397 f *= 10;
398 else
399 f /= 10;
400 }
401
402 /* Truncate s to circumvent rounding errors. */
403 s_int = (unsigned int)s;
404
405 for (i = 0; i < array_len; i++) {
406 if ((s_int == array[i][0]) && (f == array[i][1])) {
407 *result = i;
408 return SR_OK;
409 }
410 }
411
412 return SR_ERR;
413}
414
415static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
416 const struct scope_config *config,
417 struct scope_state *state)
418{
419 unsigned int i, j;
420 char command[MAX_COMMAND_SIZE];
421 char *tmp_str;
422
423 for (i = 0; i < config->analog_channels; i++) {
424 g_snprintf(command, sizeof(command),
425 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
426 i + 1);
427
428 if (sr_scpi_get_bool(scpi, command,
429 &state->analog_channels[i].state) != SR_OK)
430 return SR_ERR;
431
432 g_snprintf(command, sizeof(command),
433 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
434 i + 1);
435
436 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
437 return SR_ERR;
438
439 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
440 &j) != SR_OK) {
441 g_free(tmp_str);
442 sr_err("Could not determine array index for vertical div scale.");
443 return SR_ERR;
444 }
445
446 g_free(tmp_str);
447 state->analog_channels[i].vdiv = j;
448
449 g_snprintf(command, sizeof(command),
450 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
451 i + 1);
452
453 if (sr_scpi_get_float(scpi, command,
454 &state->analog_channels[i].vertical_offset) != SR_OK)
455 return SR_ERR;
456
457 g_snprintf(command, sizeof(command),
458 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
459 i + 1);
460
461 if (scope_state_get_array_option(scpi, command, config->coupling_options,
462 &state->analog_channels[i].coupling) != SR_OK)
463 return SR_ERR;
464 }
465
466 return SR_OK;
467}
468
469static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
470 const struct scope_config *config,
471 struct scope_state *state)
472{
473 unsigned int i;
474 char command[MAX_COMMAND_SIZE];
475
476 for (i = 0; i < config->digital_channels; i++) {
477 g_snprintf(command, sizeof(command),
478 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
479 i);
480
481 if (sr_scpi_get_bool(scpi, command,
482 &state->digital_channels[i]) != SR_OK)
483 return SR_ERR;
484 }
485
486 for (i = 0; i < config->digital_pods; i++) {
487 g_snprintf(command, sizeof(command),
488 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
489 i + 1);
490
491 if (sr_scpi_get_bool(scpi, command,
492 &state->digital_pods[i]) != SR_OK)
493 return SR_ERR;
494 }
495
496 return SR_OK;
497}
498
499SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
500{
501 struct dev_context *devc;
502 struct scope_state *state;
503 const struct scope_config *config;
504
505 int tmp;
506 unsigned int i;
507 float tmp_float;
508 gboolean channel_found;
509 char tmp_str[MAX_COMMAND_SIZE];
510 char chan_name[20];
511
512 devc = sdi->priv;
513 config = devc->model_config;
514 state = devc->model_state;
515 channel_found = FALSE;
516
517 for (i = 0; i < config->analog_channels; i++) {
518 if (state->analog_channels[i].state) {
519 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
520 g_snprintf(tmp_str, sizeof(tmp_str),
521 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
522 chan_name);
523 channel_found = TRUE;
524 break;
525 }
526 }
527
528 if (!channel_found) {
529 for (i = 0; i < config->digital_pods; i++) {
530 if (state->digital_pods[i]) {
531 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
532 g_snprintf(tmp_str, sizeof(tmp_str),
533 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
534 chan_name);
535 channel_found = TRUE;
536 break;
537 }
538 }
539 }
540
541 /* No channel is active, ask the instrument for the sample rate
542 * in single shot mode */
543 if (!channel_found) {
544 if (sr_scpi_get_float(sdi->conn,
545 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
546 &tmp_float) != SR_OK)
547 return SR_ERR;
548
549 state->sample_rate = tmp_float;
550 } else {
551 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
552 return SR_ERR;
553 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
554 (*config->timebases)[state->timebase][1]) *
555 config->num_xdivs);
556 }
557
558 return SR_OK;
559}
560
561SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
562{
563 struct dev_context *devc;
564 struct scope_state *state;
565 const struct scope_config *config;
566 float tmp_float;
567 unsigned int i;
568 char *tmp_str;
569
570 devc = sdi->priv;
571 config = devc->model_config;
572 state = devc->model_state;
573
574 sr_info("Fetching scope state");
575
576 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
577 return SR_ERR;
578
579 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
580 return SR_ERR;
581
582 if (sr_scpi_get_float(sdi->conn,
583 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
584 &tmp_float) != SR_OK)
585 return SR_ERR;
586
587 if (sr_scpi_get_string(sdi->conn,
588 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
589 &tmp_str) != SR_OK)
590 return SR_ERR;
591
592 if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
593 &i) != SR_OK) {
594 g_free(tmp_str);
595 sr_err("Could not determine array index for time base.");
596 return SR_ERR;
597 }
598
599 state->timebase = i;
600
601 if (sr_scpi_get_float(sdi->conn,
602 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
603 &tmp_float) != SR_OK)
604 return SR_ERR;
605 state->horiz_triggerpos = tmp_float /
606 (((double) (*config->timebases)[state->timebase][0] /
607 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
608 state->horiz_triggerpos -= 0.5;
609 state->horiz_triggerpos *= -1;
610
611 if (scope_state_get_array_option(sdi->conn,
612 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
613 config->trigger_sources, &state->trigger_source) != SR_OK)
614 return SR_ERR;
615
616 if (scope_state_get_array_option(sdi->conn,
617 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
618 config->trigger_slopes, &state->trigger_slope) != SR_OK)
619 return SR_ERR;
620
621 if (hmo_update_sample_rate(sdi) != SR_OK)
622 return SR_ERR;
623
624 sr_info("Fetching finished.");
625
626 scope_state_dump(config, state);
627
628 return SR_OK;
629}
630
631static struct scope_state *scope_state_new(const struct scope_config *config)
632{
633 struct scope_state *state;
634
635 state = g_malloc0(sizeof(struct scope_state));
636 state->analog_channels = g_malloc0_n(config->analog_channels,
637 sizeof(struct analog_channel_state));
638 state->digital_channels = g_malloc0_n(
639 config->digital_channels, sizeof(gboolean));
640 state->digital_pods = g_malloc0_n(config->digital_pods,
641 sizeof(gboolean));
642
643 return state;
644}
645
646SR_PRIV void hmo_scope_state_free(struct scope_state *state)
647{
648 g_free(state->analog_channels);
649 g_free(state->digital_channels);
650 g_free(state->digital_pods);
651 g_free(state);
652}
653
654SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
655{
656 char tmp[25];
657 int model_index;
658 unsigned int i, j;
659 struct sr_channel *ch;
660 struct dev_context *devc;
661
662 devc = sdi->priv;
663 model_index = -1;
664
665 /* Find the exact model. */
666 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
667 for (j = 0; scope_models[i].name[j]; j++) {
668 if (!strcmp(sdi->model, scope_models[i].name[j])) {
669 model_index = i;
670 break;
671 }
672 }
673 if (model_index != -1)
674 break;
675 }
676
677 if (model_index == -1) {
678 sr_dbg("Unsupported HMO device.");
679 return SR_ERR_NA;
680 }
681
682 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
683 scope_models[model_index].analog_channels);
684
685 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
686 scope_models[model_index].digital_pods);
687
688 /* Add analog channels. */
689 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
690 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
691 (*scope_models[model_index].analog_names)[i]);
692
693 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
694
695 devc->analog_groups[i]->name = g_strdup(
696 (char *)(*scope_models[model_index].analog_names)[i]);
697 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
698
699 sdi->channel_groups = g_slist_append(sdi->channel_groups,
700 devc->analog_groups[i]);
701 }
702
703 /* Add digital channel groups. */
704 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
705 g_snprintf(tmp, 25, "POD%d", i);
706
707 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
708
709 devc->digital_groups[i]->name = g_strdup(tmp);
710 sdi->channel_groups = g_slist_append(sdi->channel_groups,
711 devc->digital_groups[i < 8 ? 0 : 1]);
712 }
713
714 /* Add digital channels. */
715 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
716 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
717 (*scope_models[model_index].digital_names)[i]);
718
719 devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append(
720 devc->digital_groups[i < 8 ? 0 : 1]->channels, ch);
721 }
722
723 devc->model_config = &scope_models[model_index];
724 devc->frame_limit = 0;
725
726 if (!(devc->model_state = scope_state_new(devc->model_config)))
727 return SR_ERR_MALLOC;
728
729 return SR_OK;
730}
731
732SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
733{
734 struct sr_channel *ch;
735 struct sr_dev_inst *sdi;
736 struct dev_context *devc;
737 struct sr_datafeed_packet packet;
738 GArray *data;
739 struct sr_datafeed_analog_old analog;
740 struct sr_datafeed_logic logic;
741
742 (void)fd;
743 (void)revents;
744
745 data = NULL;
746
747 if (!(sdi = cb_data))
748 return TRUE;
749
750 if (!(devc = sdi->priv))
751 return TRUE;
752
753 /* Although this is correct in general, the USBTMC libusb implementation
754 * currently does not generate an event prior to the first read. Often
755 * it is ok to start reading just after the 50ms timeout. See bug #785.
756 if (revents != G_IO_IN)
757 return TRUE;
758 */
759
760 ch = devc->current_channel->data;
761
762 switch (ch->type) {
763 case SR_CHANNEL_ANALOG:
764 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
765 if (data)
766 g_array_free(data, TRUE);
767
768 return TRUE;
769 }
770
771 packet.type = SR_DF_FRAME_BEGIN;
772 sr_session_send(sdi, &packet);
773
774 analog.channels = g_slist_append(NULL, ch);
775 analog.num_samples = data->len;
776 analog.data = (float *) data->data;
777 analog.mq = SR_MQ_VOLTAGE;
778 analog.unit = SR_UNIT_VOLT;
779 analog.mqflags = 0;
780 packet.type = SR_DF_ANALOG_OLD;
781 packet.payload = &analog;
782 sr_session_send(sdi, &packet);
783 g_slist_free(analog.channels);
784 g_array_free(data, TRUE);
785 data = NULL;
786 break;
787 case SR_CHANNEL_LOGIC:
788 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
789 g_free(data);
790 return TRUE;
791 }
792
793 packet.type = SR_DF_FRAME_BEGIN;
794 sr_session_send(sdi, &packet);
795
796 logic.length = data->len;
797 logic.unitsize = 1;
798 logic.data = data->data;
799 packet.type = SR_DF_LOGIC;
800 packet.payload = &logic;
801 sr_session_send(sdi, &packet);
802 g_array_free(data, TRUE);
803 data = NULL;
804 break;
805 default:
806 sr_err("Invalid channel type.");
807 break;
808 }
809
810 packet.type = SR_DF_FRAME_END;
811 sr_session_send(sdi, &packet);
812
813 if (devc->current_channel->next) {
814 devc->current_channel = devc->current_channel->next;
815 hmo_request_data(sdi);
816 } else if (++devc->num_frames == devc->frame_limit) {
817 sdi->driver->dev_acquisition_stop(sdi);
818 } else {
819 devc->current_channel = devc->enabled_channels;
820 hmo_request_data(sdi);
821 }
822
823 return TRUE;
824}