]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
Rename SR_CONF_NUM_TIMEBASE to SR_CONF_NUM_HDIV.
[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
f254bc4b 48static const uint32_t hmo_devopts[] = {
13f2b9d7 49 SR_CONF_OSCILLOSCOPE,
a1b61e6e 50 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
5827f61b
BV
51 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
52 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 53 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b
BV
54 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
55 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
56 SR_CONF_SAMPLERATE | SR_CONF_GET,
13f2b9d7
DJ
57};
58
f254bc4b 59static const uint32_t hmo_analog_devopts[] = {
5827f61b
BV
60 SR_CONF_NUM_VDIV | SR_CONF_GET,
61 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
62 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
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 206
f254bc4b
BV
207 .devopts = &hmo_devopts,
208 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 209
f254bc4b
BV
210 .analog_devopts = &hmo_analog_devopts,
211 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
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 236
f254bc4b
BV
237 .devopts = &hmo_devopts,
238 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 239
f254bc4b
BV
240 .analog_devopts = &hmo_analog_devopts,
241 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
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
562b7ae5
SA
611 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
612 scope_models[model_index].analog_channels);
13f2b9d7 613
562b7ae5
SA
614 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
615 scope_models[model_index].digital_pods);
13f2b9d7 616
89280b1a 617 /* Add analog channels. */
13f2b9d7 618 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
c368e6f3
UH
619 ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE,
620 (*scope_models[model_index].analog_names)[i]);
ba7dd8bb 621 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 622
562b7ae5
SA
623 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
624
625 devc->analog_groups[i]->name = g_strdup(
626 (char *)(*scope_models[model_index].analog_names)[i]);
627 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 628
660e398f 629 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 630 devc->analog_groups[i]);
13f2b9d7
DJ
631 }
632
660e398f 633 /* Add digital channel groups. */
13f2b9d7
DJ
634 for (i = 0; i < scope_models[model_index].digital_pods; ++i) {
635 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
636
637 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
638
639 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 640 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 641 devc->digital_groups[i < 8 ? 0 : 1]);
13f2b9d7
DJ
642 }
643
89280b1a 644 /* Add digital channels. */
13f2b9d7 645 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
c368e6f3
UH
646 ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE,
647 (*scope_models[model_index].digital_names)[i]);
ba7dd8bb 648 sdi->channels = g_slist_append(sdi->channels, ch);
13f2b9d7 649
562b7ae5
SA
650 devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append(
651 devc->digital_groups[i < 8 ? 0 : 1]->channels, ch);
13f2b9d7
DJ
652 }
653
654 devc->model_config = &scope_models[model_index];
655 devc->frame_limit = 0;
656
657 if (!(devc->model_state = scope_state_new(devc->model_config)))
658 return SR_ERR_MALLOC;
659
660 return SR_OK;
661}
662
719eff68 663SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 664{
ba7dd8bb 665 struct sr_channel *ch;
13f2b9d7 666 struct sr_dev_inst *sdi;
06a3e78a 667 struct dev_context *devc;
13f2b9d7 668 struct sr_datafeed_packet packet;
89280b1a
UH
669 GArray *data;
670 struct sr_datafeed_analog analog;
671 struct sr_datafeed_logic logic;
06a3e78a
DJ
672
673 (void)fd;
674
f62f595b
MK
675 data = NULL;
676
06a3e78a
DJ
677 if (!(sdi = cb_data))
678 return TRUE;
679
680 if (!(devc = sdi->priv))
681 return TRUE;
682
683 if (revents == G_IO_IN) {
ba7dd8bb 684 ch = devc->current_channel->data;
13f2b9d7 685
ba7dd8bb 686 switch (ch->type) {
3f239f08 687 case SR_CHANNEL_ANALOG:
13f2b9d7
DJ
688 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
689 if (data)
690 g_array_free(data, TRUE);
691
692 return TRUE;
693 }
694
695 packet.type = SR_DF_FRAME_BEGIN;
696 sr_session_send(sdi, &packet);
697
ba7dd8bb 698 analog.channels = g_slist_append(NULL, ch);
13f2b9d7
DJ
699 analog.num_samples = data->len;
700 analog.data = (float *) data->data;
701 analog.mq = SR_MQ_VOLTAGE;
702 analog.unit = SR_UNIT_VOLT;
703 analog.mqflags = 0;
704 packet.type = SR_DF_ANALOG;
705 packet.payload = &analog;
706 sr_session_send(cb_data, &packet);
ba7dd8bb 707 g_slist_free(analog.channels);
13f2b9d7 708 g_array_free(data, TRUE);
f62f595b 709 data = NULL;
89280b1a 710 break;
3f239f08 711 case SR_CHANNEL_LOGIC:
13f2b9d7
DJ
712 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
713 if (data)
714 g_free(data);
715 return TRUE;
716 }
717
718 packet.type = SR_DF_FRAME_BEGIN;
719 sr_session_send(sdi, &packet);
720
721 logic.length = data->len;
722 logic.unitsize = 1;
723 logic.data = data->data;
724 packet.type = SR_DF_LOGIC;
725 packet.payload = &logic;
726 sr_session_send(cb_data, &packet);
727 g_array_free(data, TRUE);
f62f595b 728 data = NULL;
89280b1a 729 break;
13f2b9d7 730 default:
ba7dd8bb 731 sr_err("Invalid channel type.");
13f2b9d7
DJ
732 break;
733 }
734
735 packet.type = SR_DF_FRAME_END;
736 sr_session_send(sdi, &packet);
737
ba7dd8bb
UH
738 if (devc->current_channel->next) {
739 devc->current_channel = devc->current_channel->next;
13f2b9d7
DJ
740 hmo_request_data(sdi);
741 } else if (++devc->num_frames == devc->frame_limit) {
13f2b9d7
DJ
742 sdi->driver->dev_acquisition_stop(sdi, cb_data);
743 } else {
ba7dd8bb 744 devc->current_channel = devc->enabled_channels;
13f2b9d7
DJ
745 hmo_request_data(sdi);
746 }
06a3e78a
DJ
747 }
748
749 return TRUE;
750}