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