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