]> sigrok.org Git - libsigrok.git/blame - hardware/hameg-hmo/protocol.c
Replace 'probe' with 'channel' in most places.
[libsigrok.git] / hardware / hameg-hmo / protocol.c
CommitLineData
06a3e78a
DJ
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 "protocol.h"
21
13f2b9d7
DJ
22static const char *hameg_scpi_dialect[] = {
23 [SCPI_CMD_GET_DIG_DATA] = ":POD%d:DATA?",
24 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
965b463d 25 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
13f2b9d7
DJ
26 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
27 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
14a2f74d
DJ
28 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
29 [SCPI_CMD_GET_SAMPLE_RATE_LIVE] = ":%s:DATA:POINTS?",
13f2b9d7
DJ
30 [SCPI_CMD_GET_ANALOG_DATA] = ":CHAN%d:DATA?",
31 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
965b463d 32 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
13f2b9d7
DJ
33 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
34 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
35 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
36 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP %s",
37 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
38 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
39 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
40 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
41 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
42 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
422a1c0d 43 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
13f2b9d7
DJ
44 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
45 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
46};
47
48static const int32_t hmo_hwcaps[] = {
49 SR_CONF_OSCILLOSCOPE,
50 SR_CONF_TRIGGER_SOURCE,
51 SR_CONF_TIMEBASE,
52 SR_CONF_NUM_TIMEBASE,
53 SR_CONF_TRIGGER_SLOPE,
54 SR_CONF_HORIZ_TRIGGERPOS,
14a2f74d 55 SR_CONF_SAMPLERATE,
eff1ee03 56 SR_CONF_LIMIT_FRAMES,
13f2b9d7
DJ
57};
58
59static const int32_t hmo_analog_caps[] = {
60 SR_CONF_NUM_VDIV,
61 SR_CONF_COUPLING,
62 SR_CONF_VDIV,
63};
64
65static const char *hmo_coupling_options[] = {
66 "AC",
67 "ACL",
68 "DC",
53cd1c78 69 "DCL",
13f2b9d7
DJ
70 "GND",
71 NULL,
72};
73
74static const char *scope_trigger_slopes[] = {
75 "POS",
76 "NEG",
77 NULL,
78};
79
80static const char *hmo_compact2_trigger_sources[] = {
81 "CH1",
82 "CH2",
83 "LINE",
84 "EXT",
85 "D0",
86 "D1",
87 "D2",
88 "D3",
89 "D4",
90 "D5",
91 "D6",
92 "D7",
93 NULL,
94};
95
96static const char *hmo_compact4_trigger_sources[] = {
97 "CH1",
98 "CH2",
99 "CH3",
100 "CH4",
101 "LINE",
102 "EXT",
103 "D0",
104 "D1",
105 "D2",
106 "D3",
107 "D4",
108 "D5",
109 "D6",
110 "D7",
111 NULL,
112};
113
114static const uint64_t hmo_timebases[][2] = {
115 /* nanoseconds */
116 { 2, 1000000000 },
117 { 5, 1000000000 },
118 { 10, 1000000000 },
119 { 20, 1000000000 },
120 { 50, 1000000000 },
121 { 100, 1000000000 },
122 { 200, 1000000000 },
123 { 500, 1000000000 },
124 /* microseconds */
125 { 1, 1000000 },
126 { 2, 1000000 },
127 { 5, 1000000 },
128 { 10, 1000000 },
129 { 20, 1000000 },
130 { 50, 1000000 },
131 { 100, 1000000 },
132 { 200, 1000000 },
133 { 500, 1000000 },
134 /* milliseconds */
135 { 1, 1000 },
136 { 2, 1000 },
137 { 5, 1000 },
138 { 10, 1000 },
139 { 20, 1000 },
140 { 50, 1000 },
141 { 100, 1000 },
142 { 200, 1000 },
143 { 500, 1000 },
144 /* seconds */
145 { 1, 1 },
146 { 2, 1 },
147 { 5, 1 },
148 { 10, 1 },
149 { 20, 1 },
150 { 50, 1 },
151};
152
153static const uint64_t hmo_vdivs[][2] = {
154 /* millivolts */
155 { 1, 1000 },
156 { 2, 1000 },
157 { 5, 1000 },
158 { 10, 1000 },
159 { 20, 1000 },
160 { 50, 1000 },
161 { 100, 1000 },
162 { 200, 1000 },
163 { 500, 1000 },
164 /* volts */
165 { 1, 1 },
166 { 2, 1 },
167 { 5, 1 },
168 { 10, 1 },
169};
170
ba7dd8bb 171static const char *scope_analog_channel_names[] = {
13f2b9d7
DJ
172 "CH1",
173 "CH2",
174 "CH3",
175 "CH4",
176};
177
ba7dd8bb 178static const char *scope_digital_channel_names[] = {
13f2b9d7
DJ
179 "D0",
180 "D1",
181 "D2",
182 "D3",
183 "D4",
184 "D5",
185 "D6",
186 "D7",
187 "D8",
188 "D9",
189 "D10",
190 "D11",
191 "D12",
192 "D13",
193 "D14",
194 "D15",
195};
196
197static struct scope_config scope_models[] = {
198 {
199 .name = {"HMO722", "HMO1022", "HMO1522", "HMO2022", NULL},
200 .analog_channels = 2,
201 .digital_channels = 8,
202 .digital_pods = 1,
203
ba7dd8bb
UH
204 .analog_names = &scope_analog_channel_names,
205 .digital_names = &scope_digital_channel_names,
13f2b9d7
DJ
206
207 .hw_caps = &hmo_hwcaps,
208 .num_hwcaps = ARRAY_SIZE(hmo_hwcaps),
209
210 .analog_hwcaps = &hmo_analog_caps,
211 .num_analog_hwcaps = ARRAY_SIZE(hmo_analog_caps),
212
213 .coupling_options = &hmo_coupling_options,
214 .trigger_sources = &hmo_compact2_trigger_sources,
215 .trigger_slopes = &scope_trigger_slopes,
216
217 .timebases = &hmo_timebases,
218 .num_timebases = ARRAY_SIZE(hmo_timebases),
219
220 .vdivs = &hmo_vdivs,
221 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
222
223 .num_xdivs = 12,
224 .num_ydivs = 8,
225
226 .scpi_dialect = &hameg_scpi_dialect,
227 },
228 {
229 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
230 .analog_channels = 4,
231 .digital_channels = 8,
232 .digital_pods = 1,
233
ba7dd8bb
UH
234 .analog_names = &scope_analog_channel_names,
235 .digital_names = &scope_digital_channel_names,
13f2b9d7
DJ
236
237 .hw_caps = &hmo_hwcaps,
238 .num_hwcaps = ARRAY_SIZE(hmo_hwcaps),
239
240 .analog_hwcaps = &hmo_analog_caps,
241 .num_analog_hwcaps = ARRAY_SIZE(hmo_analog_caps),
242
243 .coupling_options = &hmo_coupling_options,
244 .trigger_sources = &hmo_compact4_trigger_sources,
245 .trigger_slopes = &scope_trigger_slopes,
246
247 .timebases = &hmo_timebases,
248 .num_timebases = ARRAY_SIZE(hmo_timebases),
249
250 .vdivs = &hmo_vdivs,
251 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
252
253 .num_xdivs = 12,
254 .num_ydivs = 8,
255
256 .scpi_dialect = &hameg_scpi_dialect,
257 },
258};
259
13f2b9d7
DJ
260static void scope_state_dump(struct scope_config *config,
261 struct scope_state *state)
262{
263 unsigned int i;
8de2dc3b 264 char *tmp;
13f2b9d7
DJ
265
266 for (i = 0; i < config->analog_channels; ++i) {
8de2dc3b
DJ
267 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
268 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
269 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
270 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 271 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 272 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
273 }
274
275 for (i = 0; i < config->digital_channels; ++i) {
276 sr_info("State of digital channel %d -> %s", i,
277 state->digital_channels[i] ? "On" : "Off");
278 }
279
280 for (i = 0; i < config->digital_pods; ++i) {
281 sr_info("State of digital POD %d -> %s", i,
282 state->digital_pods[i] ? "On" : "Off");
283 }
284
8de2dc3b
DJ
285 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
286 (*config->timebases)[state->timebase][1]);
287 sr_info("Current timebase: %s", tmp);
288 g_free(tmp);
289
14a2f74d
DJ
290 tmp = sr_samplerate_string(state->sample_rate);
291 sr_info("Current samplerate: %s", tmp);
292 g_free(tmp);
293
422a1c0d 294 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
13f2b9d7
DJ
295 (*config->trigger_sources)[state->trigger_source],
296 (*config->trigger_slopes)[state->trigger_slope],
297 state->horiz_triggerpos);
298}
299
23f43dff 300static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
89280b1a 301 const char *command, const char *(*array)[], int *result)
13f2b9d7
DJ
302{
303 char *tmp;
304 unsigned int i;
305
23f43dff 306 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
89280b1a 307 g_free(tmp);
13f2b9d7
DJ
308 return SR_ERR;
309 }
310
311 for (i = 0; (*array)[i]; ++i) {
312 if (!g_strcmp0(tmp, (*array)[i])) {
313 *result = i;
314 g_free(tmp);
315 tmp = NULL;
316 break;
317 }
318 }
319
320 if (tmp) {
321 g_free(tmp);
322 return SR_ERR;
323 }
324
325 return SR_OK;
326}
327
23f43dff 328static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
13f2b9d7
DJ
329 struct scope_config *config,
330 struct scope_state *state)
331{
8de2dc3b
DJ
332 unsigned int i, j;
333 float tmp_float;
13f2b9d7
DJ
334 char command[MAX_COMMAND_SIZE];
335
336 for (i = 0; i < config->analog_channels; ++i) {
337 g_snprintf(command, sizeof(command),
338 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
339 i + 1);
340
23f43dff 341 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
342 &state->analog_channels[i].state) != SR_OK)
343 return SR_ERR;
344
345 g_snprintf(command, sizeof(command),
346 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
347 i + 1);
348
8de2dc3b
DJ
349 if (sr_scpi_get_float(scpi, command, &tmp_float) != SR_OK)
350 return SR_ERR;
351 for (j = 0; j < config->num_vdivs; j++) {
352 if (tmp_float == ((float) (*config->vdivs)[j][0] /
353 (*config->vdivs)[j][1])) {
354 state->analog_channels[i].vdiv = j;
355 break;
356 }
357 }
358 if (i == config->num_vdivs)
13f2b9d7
DJ
359 return SR_ERR;
360
361 g_snprintf(command, sizeof(command),
362 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
363 i + 1);
364
23f43dff 365 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
366 &state->analog_channels[i].vertical_offset) != SR_OK)
367 return SR_ERR;
368
369 g_snprintf(command, sizeof(command),
370 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
371 i + 1);
372
23f43dff 373 if (scope_state_get_array_option(scpi, command, config->coupling_options,
13f2b9d7
DJ
374 &state->analog_channels[i].coupling) != SR_OK)
375 return SR_ERR;
376 }
377
378 return SR_OK;
379}
380
23f43dff 381static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
13f2b9d7
DJ
382 struct scope_config *config,
383 struct scope_state *state)
384{
385 unsigned int i;
386 char command[MAX_COMMAND_SIZE];
387
388 for (i = 0; i < config->digital_channels; ++i) {
389 g_snprintf(command, sizeof(command),
390 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
391 i);
392
23f43dff 393 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
394 &state->digital_channels[i]) != SR_OK)
395 return SR_ERR;
396 }
397
398 for (i = 0; i < config->digital_pods; ++i) {
399 g_snprintf(command, sizeof(command),
400 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
401 i + 1);
402
23f43dff 403 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
404 &state->digital_pods[i]) != SR_OK)
405 return SR_ERR;
406 }
407
408 return SR_OK;
409}
410
14a2f74d
DJ
411SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
412{
413 struct dev_context *devc;
414 struct scope_state *state;
415 struct scope_config *config;
416
417 int tmp;
418 unsigned int i;
419 float tmp_float;
420 gboolean channel_found;
421 char tmp_str[MAX_COMMAND_SIZE];
422 char chan_name[20];
423
424 devc = sdi->priv;
425 config = devc->model_config;
426 state = devc->model_state;
427 channel_found = FALSE;
428
429 for (i = 0; i < config->analog_channels; ++i) {
430 if (state->analog_channels[i].state) {
431 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
432 g_snprintf(tmp_str, sizeof(tmp_str),
433 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
434 chan_name);
435 channel_found = TRUE;
436 break;
437 }
438 }
439
440 if (!channel_found) {
441 for (i = 0; i < config->digital_pods; i++) {
442 if (state->digital_pods[i]) {
443 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
444 g_snprintf(tmp_str, sizeof(tmp_str),
445 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
446 chan_name);
447 channel_found = TRUE;
448 break;
449 }
450 }
451 }
452
453 /* No channel is active, ask the instrument for the sample rate
454 * in single shot mode */
455 if (!channel_found) {
c06c24d2
DJ
456 if (sr_scpi_get_float(sdi->conn,
457 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
458 &tmp_float) != SR_OK)
14a2f74d 459 return SR_ERR;
c06c24d2 460
14a2f74d
DJ
461 state->sample_rate = tmp_float;
462 } else {
463 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
464 return SR_ERR;
465 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
466 (*config->timebases)[state->timebase][1]) *
467 config->num_xdivs);
468 }
469
470 return SR_OK;
471}
472
719eff68 473SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
474{
475 struct dev_context *devc;
476 struct scope_state *state;
477 struct scope_config *config;
8de2dc3b
DJ
478 float tmp_float;
479 unsigned int i;
13f2b9d7
DJ
480
481 devc = sdi->priv;
482 config = devc->model_config;
483 state = devc->model_state;
484
8de2dc3b
DJ
485 sr_info("Fetching scope state");
486
13f2b9d7
DJ
487 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
488 return SR_ERR;
489
490 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
491 return SR_ERR;
492
89280b1a
UH
493 if (sr_scpi_get_float(sdi->conn,
494 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
495 &tmp_float) != SR_OK)
496 return SR_ERR;
497
498 for (i = 0; i < config->num_timebases; i++) {
499 if (tmp_float == ((float) (*config->timebases)[i][0] /
500 (*config->timebases)[i][1])) {
501 state->timebase = i;
502 break;
503 }
504 }
505 if (i == config->num_timebases)
13f2b9d7
DJ
506 return SR_ERR;
507
89280b1a
UH
508 if (sr_scpi_get_float(sdi->conn,
509 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 510 &tmp_float) != SR_OK)
13f2b9d7 511 return SR_ERR;
422a1c0d
DJ
512 state->horiz_triggerpos = tmp_float /
513 (((double) (*config->timebases)[state->timebase][0] /
514 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
515 state->horiz_triggerpos -= 0.5;
516 state->horiz_triggerpos *= -1;
13f2b9d7 517
89280b1a
UH
518 if (scope_state_get_array_option(sdi->conn,
519 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
520 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
521 return SR_ERR;
522
89280b1a
UH
523 if (scope_state_get_array_option(sdi->conn,
524 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
525 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
526 return SR_ERR;
527
14a2f74d
DJ
528 if (hmo_update_sample_rate(sdi) != SR_OK)
529 return SR_ERR;
530
8de2dc3b
DJ
531 sr_info("Fetching finished.");
532
13f2b9d7
DJ
533 scope_state_dump(config, state);
534
535 return SR_OK;
536}
537
d87c1766 538static struct scope_state *scope_state_new(struct scope_config *config)
13f2b9d7
DJ
539{
540 struct scope_state *state;
541
542 if (!(state = g_try_malloc0(sizeof(struct scope_state))))
543 return NULL;
544
545 if (!(state->analog_channels = g_try_malloc0_n(config->analog_channels,
89280b1a 546 sizeof(struct analog_channel_state))))
13f2b9d7
DJ
547 goto fail;
548
89280b1a
UH
549 if (!(state->digital_channels = g_try_malloc0_n(
550 config->digital_channels, sizeof(gboolean))))
13f2b9d7
DJ
551 goto fail;
552
553 if (!(state->digital_pods = g_try_malloc0_n(config->digital_pods,
89280b1a 554 sizeof(gboolean))))
13f2b9d7
DJ
555 goto fail;
556
557 return state;
558
559fail:
560 if (state->analog_channels)
561 g_free(state->analog_channels);
562 if (state->digital_channels)
563 g_free(state->digital_channels);
564 if (state->digital_pods)
565 g_free(state->digital_pods);
566 g_free(state);
567
568 return NULL;
569}
570
719eff68 571SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
572{
573 g_free(state->analog_channels);
574 g_free(state->digital_channels);
575 g_free(state->digital_pods);
576 g_free(state);
577}
578
579SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
580{
581 char tmp[25];
582 int model_index;
89280b1a 583 unsigned int i, j;
ba7dd8bb 584 struct sr_channel *ch;
13f2b9d7
DJ
585 struct dev_context *devc;
586
587 devc = sdi->priv;
588 model_index = -1;
589
89280b1a 590 /* Find the exact model. */
13f2b9d7
DJ
591 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
592 for (j = 0; scope_models[i].name[j]; j++) {
593 if (!strcmp(sdi->model, scope_models[i].name[j])) {
594 model_index = i;
595 break;
596 }
597 }
598 if (model_index != -1)
599 break;
600 }
601
602 if (model_index == -1) {
89280b1a 603 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
604 return SR_ERR_NA;
605 }
606
660e398f 607 if (!(devc->analog_groups = g_try_malloc0(sizeof(struct sr_channel_group) *
13f2b9d7
DJ
608 scope_models[model_index].analog_channels)))
609 return SR_ERR_MALLOC;
610
660e398f 611 if (!(devc->digital_groups = g_try_malloc0(sizeof(struct sr_channel_group) *
13f2b9d7
DJ
612 scope_models[model_index].digital_pods)))
613 return SR_ERR_MALLOC;
614
89280b1a 615 /* Add analog channels. */
13f2b9d7 616 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
ba7dd8bb 617 if (!(ch = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
89280b1a 618 (*scope_models[model_index].analog_names)[i])))
13f2b9d7 619 return SR_ERR_MALLOC;
ba7dd8bb 620 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 621
89280b1a
UH
622 devc->analog_groups[i].name =
623 (char *)(*scope_models[model_index].analog_names)[i];
ba7dd8bb 624 devc->analog_groups[i].channels = g_slist_append(NULL, ch);
13f2b9d7 625
660e398f 626 sdi->channel_groups = g_slist_append(sdi->channel_groups,
13f2b9d7
DJ
627 &devc->analog_groups[i]);
628 }
629
660e398f 630 /* Add digital channel groups. */
13f2b9d7
DJ
631 for (i = 0; i < scope_models[model_index].digital_pods; ++i) {
632 g_snprintf(tmp, 25, "POD%d", i);
633 devc->digital_groups[i].name = g_strdup(tmp);
660e398f 634 sdi->channel_groups = g_slist_append(sdi->channel_groups,
89280b1a 635 &devc->digital_groups[i < 8 ? 0 : 1]);
13f2b9d7
DJ
636 }
637
89280b1a 638 /* Add digital channels. */
13f2b9d7 639 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
ba7dd8bb 640 if (!(ch = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
89280b1a 641 (*scope_models[model_index].digital_names)[i])))
13f2b9d7 642 return SR_ERR_MALLOC;
ba7dd8bb 643 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 644
a68bf88e 645 devc->digital_groups[i < 8 ? 0 : 1].channels = g_slist_append(
ba7dd8bb 646 devc->digital_groups[i < 8 ? 0 : 1].channels, ch);
13f2b9d7
DJ
647 }
648
649 devc->model_config = &scope_models[model_index];
650 devc->frame_limit = 0;
651
652 if (!(devc->model_state = scope_state_new(devc->model_config)))
653 return SR_ERR_MALLOC;
654
655 return SR_OK;
656}
657
719eff68 658SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 659{
ba7dd8bb 660 struct sr_channel *ch;
13f2b9d7 661 struct sr_dev_inst *sdi;
06a3e78a 662 struct dev_context *devc;
13f2b9d7 663 struct sr_datafeed_packet packet;
89280b1a
UH
664 GArray *data;
665 struct sr_datafeed_analog analog;
666 struct sr_datafeed_logic logic;
06a3e78a
DJ
667
668 (void)fd;
669
670 if (!(sdi = cb_data))
671 return TRUE;
672
673 if (!(devc = sdi->priv))
674 return TRUE;
675
676 if (revents == G_IO_IN) {
ba7dd8bb 677 ch = devc->current_channel->data;
13f2b9d7 678
ba7dd8bb 679 switch (ch->type) {
13f2b9d7 680 case SR_PROBE_ANALOG:
13f2b9d7
DJ
681 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
682 if (data)
683 g_array_free(data, TRUE);
684
685 return TRUE;
686 }
687
688 packet.type = SR_DF_FRAME_BEGIN;
689 sr_session_send(sdi, &packet);
690
ba7dd8bb 691 analog.channels = g_slist_append(NULL, ch);
13f2b9d7
DJ
692 analog.num_samples = data->len;
693 analog.data = (float *) data->data;
694 analog.mq = SR_MQ_VOLTAGE;
695 analog.unit = SR_UNIT_VOLT;
696 analog.mqflags = 0;
697 packet.type = SR_DF_ANALOG;
698 packet.payload = &analog;
699 sr_session_send(cb_data, &packet);
ba7dd8bb 700 g_slist_free(analog.channels);
13f2b9d7 701 g_array_free(data, TRUE);
89280b1a 702 break;
13f2b9d7 703 case SR_PROBE_LOGIC:
13f2b9d7
DJ
704 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
705 if (data)
706 g_free(data);
707 return TRUE;
708 }
709
710 packet.type = SR_DF_FRAME_BEGIN;
711 sr_session_send(sdi, &packet);
712
713 logic.length = data->len;
714 logic.unitsize = 1;
715 logic.data = data->data;
716 packet.type = SR_DF_LOGIC;
717 packet.payload = &logic;
718 sr_session_send(cb_data, &packet);
719 g_array_free(data, TRUE);
89280b1a 720 break;
13f2b9d7 721 default:
ba7dd8bb 722 sr_err("Invalid channel type.");
13f2b9d7
DJ
723 break;
724 }
725
726 packet.type = SR_DF_FRAME_END;
727 sr_session_send(sdi, &packet);
728
ba7dd8bb
UH
729 if (devc->current_channel->next) {
730 devc->current_channel = devc->current_channel->next;
13f2b9d7
DJ
731 hmo_request_data(sdi);
732 } else if (++devc->num_frames == devc->frame_limit) {
13f2b9d7
DJ
733 sdi->driver->dev_acquisition_stop(sdi, cb_data);
734 } else {
ba7dd8bb 735 devc->current_channel = devc->enabled_channels;
13f2b9d7
DJ
736 hmo_request_data(sdi);
737 }
06a3e78a
DJ
738 }
739
740 return TRUE;
741}