]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
rigol-ds: Fix duplicated vendor string for Agilent devices.
[libsigrok.git] / src / 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 }
b4e31d2a
SA
358 if (j == config->num_vdivs) {
359 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 360 return SR_ERR;
b4e31d2a 361 }
13f2b9d7
DJ
362
363 g_snprintf(command, sizeof(command),
364 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
365 i + 1);
366
23f43dff 367 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
368 &state->analog_channels[i].vertical_offset) != SR_OK)
369 return SR_ERR;
370
371 g_snprintf(command, sizeof(command),
372 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
373 i + 1);
374
23f43dff 375 if (scope_state_get_array_option(scpi, command, config->coupling_options,
13f2b9d7
DJ
376 &state->analog_channels[i].coupling) != SR_OK)
377 return SR_ERR;
378 }
379
380 return SR_OK;
381}
382
23f43dff 383static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
13f2b9d7
DJ
384 struct scope_config *config,
385 struct scope_state *state)
386{
387 unsigned int i;
388 char command[MAX_COMMAND_SIZE];
389
390 for (i = 0; i < config->digital_channels; ++i) {
391 g_snprintf(command, sizeof(command),
392 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
393 i);
394
23f43dff 395 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
396 &state->digital_channels[i]) != SR_OK)
397 return SR_ERR;
398 }
399
400 for (i = 0; i < config->digital_pods; ++i) {
401 g_snprintf(command, sizeof(command),
402 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
403 i + 1);
404
23f43dff 405 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
406 &state->digital_pods[i]) != SR_OK)
407 return SR_ERR;
408 }
409
410 return SR_OK;
411}
412
14a2f74d
DJ
413SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
414{
415 struct dev_context *devc;
416 struct scope_state *state;
417 struct scope_config *config;
418
419 int tmp;
420 unsigned int i;
421 float tmp_float;
422 gboolean channel_found;
423 char tmp_str[MAX_COMMAND_SIZE];
424 char chan_name[20];
425
426 devc = sdi->priv;
427 config = devc->model_config;
428 state = devc->model_state;
429 channel_found = FALSE;
430
431 for (i = 0; i < config->analog_channels; ++i) {
432 if (state->analog_channels[i].state) {
433 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
434 g_snprintf(tmp_str, sizeof(tmp_str),
435 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
436 chan_name);
437 channel_found = TRUE;
438 break;
439 }
440 }
441
442 if (!channel_found) {
443 for (i = 0; i < config->digital_pods; i++) {
444 if (state->digital_pods[i]) {
445 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
446 g_snprintf(tmp_str, sizeof(tmp_str),
447 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
448 chan_name);
449 channel_found = TRUE;
450 break;
451 }
452 }
453 }
454
455 /* No channel is active, ask the instrument for the sample rate
456 * in single shot mode */
457 if (!channel_found) {
c06c24d2
DJ
458 if (sr_scpi_get_float(sdi->conn,
459 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
460 &tmp_float) != SR_OK)
14a2f74d 461 return SR_ERR;
c06c24d2 462
14a2f74d
DJ
463 state->sample_rate = tmp_float;
464 } else {
465 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
466 return SR_ERR;
467 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
468 (*config->timebases)[state->timebase][1]) *
469 config->num_xdivs);
470 }
471
472 return SR_OK;
473}
474
719eff68 475SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
476{
477 struct dev_context *devc;
478 struct scope_state *state;
479 struct scope_config *config;
8de2dc3b
DJ
480 float tmp_float;
481 unsigned int i;
13f2b9d7
DJ
482
483 devc = sdi->priv;
484 config = devc->model_config;
485 state = devc->model_state;
486
8de2dc3b
DJ
487 sr_info("Fetching scope state");
488
13f2b9d7
DJ
489 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
490 return SR_ERR;
491
492 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
493 return SR_ERR;
494
89280b1a
UH
495 if (sr_scpi_get_float(sdi->conn,
496 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
497 &tmp_float) != SR_OK)
498 return SR_ERR;
499
500 for (i = 0; i < config->num_timebases; i++) {
501 if (tmp_float == ((float) (*config->timebases)[i][0] /
502 (*config->timebases)[i][1])) {
503 state->timebase = i;
504 break;
505 }
506 }
b4e31d2a
SA
507 if (i == config->num_timebases) {
508 sr_err("Could not determine array index for time base.");
13f2b9d7 509 return SR_ERR;
b4e31d2a 510 }
13f2b9d7 511
89280b1a
UH
512 if (sr_scpi_get_float(sdi->conn,
513 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 514 &tmp_float) != SR_OK)
13f2b9d7 515 return SR_ERR;
422a1c0d
DJ
516 state->horiz_triggerpos = tmp_float /
517 (((double) (*config->timebases)[state->timebase][0] /
518 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
519 state->horiz_triggerpos -= 0.5;
520 state->horiz_triggerpos *= -1;
13f2b9d7 521
89280b1a
UH
522 if (scope_state_get_array_option(sdi->conn,
523 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
524 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
525 return SR_ERR;
526
89280b1a
UH
527 if (scope_state_get_array_option(sdi->conn,
528 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
529 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
530 return SR_ERR;
531
14a2f74d
DJ
532 if (hmo_update_sample_rate(sdi) != SR_OK)
533 return SR_ERR;
534
8de2dc3b
DJ
535 sr_info("Fetching finished.");
536
13f2b9d7
DJ
537 scope_state_dump(config, state);
538
539 return SR_OK;
540}
541
d87c1766 542static struct scope_state *scope_state_new(struct scope_config *config)
13f2b9d7
DJ
543{
544 struct scope_state *state;
545
546 if (!(state = g_try_malloc0(sizeof(struct scope_state))))
547 return NULL;
548
549 if (!(state->analog_channels = g_try_malloc0_n(config->analog_channels,
89280b1a 550 sizeof(struct analog_channel_state))))
13f2b9d7
DJ
551 goto fail;
552
89280b1a
UH
553 if (!(state->digital_channels = g_try_malloc0_n(
554 config->digital_channels, sizeof(gboolean))))
13f2b9d7
DJ
555 goto fail;
556
557 if (!(state->digital_pods = g_try_malloc0_n(config->digital_pods,
89280b1a 558 sizeof(gboolean))))
13f2b9d7
DJ
559 goto fail;
560
561 return state;
562
563fail:
564 if (state->analog_channels)
565 g_free(state->analog_channels);
566 if (state->digital_channels)
567 g_free(state->digital_channels);
568 if (state->digital_pods)
569 g_free(state->digital_pods);
570 g_free(state);
571
572 return NULL;
573}
574
719eff68 575SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
576{
577 g_free(state->analog_channels);
578 g_free(state->digital_channels);
579 g_free(state->digital_pods);
580 g_free(state);
581}
582
583SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
584{
585 char tmp[25];
586 int model_index;
89280b1a 587 unsigned int i, j;
ba7dd8bb 588 struct sr_channel *ch;
13f2b9d7
DJ
589 struct dev_context *devc;
590
591 devc = sdi->priv;
592 model_index = -1;
593
89280b1a 594 /* Find the exact model. */
13f2b9d7
DJ
595 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
596 for (j = 0; scope_models[i].name[j]; j++) {
597 if (!strcmp(sdi->model, scope_models[i].name[j])) {
598 model_index = i;
599 break;
600 }
601 }
602 if (model_index != -1)
603 break;
604 }
605
606 if (model_index == -1) {
89280b1a 607 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
608 return SR_ERR_NA;
609 }
610
660e398f 611 if (!(devc->analog_groups = g_try_malloc0(sizeof(struct sr_channel_group) *
13f2b9d7
DJ
612 scope_models[model_index].analog_channels)))
613 return SR_ERR_MALLOC;
614
660e398f 615 if (!(devc->digital_groups = g_try_malloc0(sizeof(struct sr_channel_group) *
13f2b9d7
DJ
616 scope_models[model_index].digital_pods)))
617 return SR_ERR_MALLOC;
618
89280b1a 619 /* Add analog channels. */
13f2b9d7 620 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
3f239f08 621 if (!(ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE,
89280b1a 622 (*scope_models[model_index].analog_names)[i])))
13f2b9d7 623 return SR_ERR_MALLOC;
ba7dd8bb 624 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 625
89280b1a
UH
626 devc->analog_groups[i].name =
627 (char *)(*scope_models[model_index].analog_names)[i];
ba7dd8bb 628 devc->analog_groups[i].channels = g_slist_append(NULL, ch);
13f2b9d7 629
660e398f 630 sdi->channel_groups = g_slist_append(sdi->channel_groups,
13f2b9d7
DJ
631 &devc->analog_groups[i]);
632 }
633
660e398f 634 /* Add digital channel groups. */
13f2b9d7
DJ
635 for (i = 0; i < scope_models[model_index].digital_pods; ++i) {
636 g_snprintf(tmp, 25, "POD%d", i);
637 devc->digital_groups[i].name = g_strdup(tmp);
660e398f 638 sdi->channel_groups = g_slist_append(sdi->channel_groups,
89280b1a 639 &devc->digital_groups[i < 8 ? 0 : 1]);
13f2b9d7
DJ
640 }
641
89280b1a 642 /* Add digital channels. */
13f2b9d7 643 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
3f239f08 644 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE,
89280b1a 645 (*scope_models[model_index].digital_names)[i])))
13f2b9d7 646 return SR_ERR_MALLOC;
ba7dd8bb 647 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 648
a68bf88e 649 devc->digital_groups[i < 8 ? 0 : 1].channels = g_slist_append(
ba7dd8bb 650 devc->digital_groups[i < 8 ? 0 : 1].channels, ch);
13f2b9d7
DJ
651 }
652
653 devc->model_config = &scope_models[model_index];
654 devc->frame_limit = 0;
655
656 if (!(devc->model_state = scope_state_new(devc->model_config)))
657 return SR_ERR_MALLOC;
658
659 return SR_OK;
660}
661
719eff68 662SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 663{
ba7dd8bb 664 struct sr_channel *ch;
13f2b9d7 665 struct sr_dev_inst *sdi;
06a3e78a 666 struct dev_context *devc;
13f2b9d7 667 struct sr_datafeed_packet packet;
89280b1a
UH
668 GArray *data;
669 struct sr_datafeed_analog analog;
670 struct sr_datafeed_logic logic;
06a3e78a
DJ
671
672 (void)fd;
673
674 if (!(sdi = cb_data))
675 return TRUE;
676
677 if (!(devc = sdi->priv))
678 return TRUE;
679
680 if (revents == G_IO_IN) {
ba7dd8bb 681 ch = devc->current_channel->data;
13f2b9d7 682
ba7dd8bb 683 switch (ch->type) {
3f239f08 684 case SR_CHANNEL_ANALOG:
13f2b9d7
DJ
685 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
686 if (data)
687 g_array_free(data, TRUE);
688
689 return TRUE;
690 }
691
692 packet.type = SR_DF_FRAME_BEGIN;
693 sr_session_send(sdi, &packet);
694
ba7dd8bb 695 analog.channels = g_slist_append(NULL, ch);
13f2b9d7
DJ
696 analog.num_samples = data->len;
697 analog.data = (float *) data->data;
698 analog.mq = SR_MQ_VOLTAGE;
699 analog.unit = SR_UNIT_VOLT;
700 analog.mqflags = 0;
701 packet.type = SR_DF_ANALOG;
702 packet.payload = &analog;
703 sr_session_send(cb_data, &packet);
ba7dd8bb 704 g_slist_free(analog.channels);
13f2b9d7 705 g_array_free(data, TRUE);
89280b1a 706 break;
3f239f08 707 case SR_CHANNEL_LOGIC:
13f2b9d7
DJ
708 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
709 if (data)
710 g_free(data);
711 return TRUE;
712 }
713
714 packet.type = SR_DF_FRAME_BEGIN;
715 sr_session_send(sdi, &packet);
716
717 logic.length = data->len;
718 logic.unitsize = 1;
719 logic.data = data->data;
720 packet.type = SR_DF_LOGIC;
721 packet.payload = &logic;
722 sr_session_send(cb_data, &packet);
723 g_array_free(data, TRUE);
89280b1a 724 break;
13f2b9d7 725 default:
ba7dd8bb 726 sr_err("Invalid channel type.");
13f2b9d7
DJ
727 break;
728 }
729
730 packet.type = SR_DF_FRAME_END;
731 sr_session_send(sdi, &packet);
732
ba7dd8bb
UH
733 if (devc->current_channel->next) {
734 devc->current_channel = devc->current_channel->next;
13f2b9d7
DJ
735 hmo_request_data(sdi);
736 } else if (++devc->num_frames == devc->frame_limit) {
13f2b9d7
DJ
737 sdi->driver->dev_acquisition_stop(sdi, cb_data);
738 } else {
ba7dd8bb 739 devc->current_channel = devc->enabled_channels;
13f2b9d7
DJ
740 hmo_request_data(sdi);
741 }
06a3e78a
DJ
742 }
743
744 return TRUE;
745}