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