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