]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
Build: Set local include directories in Makefile.am
[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
329733d9 197static const struct scope_config scope_models[] = {
13f2b9d7
DJ
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
329733d9 260static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
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,
329733d9 329 const struct scope_config *config,
13f2b9d7
DJ
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,
329733d9 384 const struct scope_config *config,
13f2b9d7
DJ
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;
329733d9 417 const struct scope_config *config;
14a2f74d
DJ
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;
329733d9 479 const 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
329733d9 542static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
543{
544 struct scope_state *state;
545
a95f142e
UH
546 state = g_malloc0(sizeof(struct scope_state));
547 state->analog_channels = g_malloc0_n(config->analog_channels,
548 sizeof(struct analog_channel_state));
549 state->digital_channels = g_malloc0_n(
550 config->digital_channels, sizeof(gboolean));
551 state->digital_pods = g_malloc0_n(config->digital_pods,
552 sizeof(gboolean));
13f2b9d7
DJ
553
554 return state;
13f2b9d7
DJ
555}
556
719eff68 557SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
558{
559 g_free(state->analog_channels);
560 g_free(state->digital_channels);
561 g_free(state->digital_pods);
562 g_free(state);
563}
564
565SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
566{
567 char tmp[25];
568 int model_index;
89280b1a 569 unsigned int i, j;
ba7dd8bb 570 struct sr_channel *ch;
13f2b9d7
DJ
571 struct dev_context *devc;
572
573 devc = sdi->priv;
574 model_index = -1;
575
89280b1a 576 /* Find the exact model. */
13f2b9d7
DJ
577 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
578 for (j = 0; scope_models[i].name[j]; j++) {
579 if (!strcmp(sdi->model, scope_models[i].name[j])) {
580 model_index = i;
581 break;
582 }
583 }
584 if (model_index != -1)
585 break;
586 }
587
588 if (model_index == -1) {
89280b1a 589 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
590 return SR_ERR_NA;
591 }
592
562b7ae5
SA
593 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
594 scope_models[model_index].analog_channels);
13f2b9d7 595
562b7ae5
SA
596 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
597 scope_models[model_index].digital_pods);
13f2b9d7 598
89280b1a 599 /* Add analog channels. */
13f2b9d7 600 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 601 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 602 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 603
562b7ae5
SA
604 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
605
606 devc->analog_groups[i]->name = g_strdup(
607 (char *)(*scope_models[model_index].analog_names)[i]);
608 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 609
660e398f 610 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 611 devc->analog_groups[i]);
13f2b9d7
DJ
612 }
613
660e398f 614 /* Add digital channel groups. */
13f2b9d7
DJ
615 for (i = 0; i < scope_models[model_index].digital_pods; ++i) {
616 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
617
618 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
619
620 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 621 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 622 devc->digital_groups[i < 8 ? 0 : 1]);
13f2b9d7
DJ
623 }
624
89280b1a 625 /* Add digital channels. */
13f2b9d7 626 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 627 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 628 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 629
562b7ae5
SA
630 devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append(
631 devc->digital_groups[i < 8 ? 0 : 1]->channels, ch);
13f2b9d7
DJ
632 }
633
634 devc->model_config = &scope_models[model_index];
635 devc->frame_limit = 0;
636
637 if (!(devc->model_state = scope_state_new(devc->model_config)))
638 return SR_ERR_MALLOC;
639
640 return SR_OK;
641}
642
719eff68 643SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 644{
ba7dd8bb 645 struct sr_channel *ch;
13f2b9d7 646 struct sr_dev_inst *sdi;
06a3e78a 647 struct dev_context *devc;
13f2b9d7 648 struct sr_datafeed_packet packet;
89280b1a
UH
649 GArray *data;
650 struct sr_datafeed_analog analog;
651 struct sr_datafeed_logic logic;
06a3e78a
DJ
652
653 (void)fd;
654
f62f595b
MK
655 data = NULL;
656
06a3e78a
DJ
657 if (!(sdi = cb_data))
658 return TRUE;
659
660 if (!(devc = sdi->priv))
661 return TRUE;
662
dc89faea
UH
663 if (revents != G_IO_IN)
664 return TRUE;
13f2b9d7 665
dc89faea 666 ch = devc->current_channel->data;
13f2b9d7 667
dc89faea
UH
668 switch (ch->type) {
669 case SR_CHANNEL_ANALOG:
670 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
671 if (data)
672 g_array_free(data, TRUE);
13f2b9d7 673
dc89faea 674 return TRUE;
13f2b9d7
DJ
675 }
676
dc89faea 677 packet.type = SR_DF_FRAME_BEGIN;
13f2b9d7
DJ
678 sr_session_send(sdi, &packet);
679
dc89faea
UH
680 analog.channels = g_slist_append(NULL, ch);
681 analog.num_samples = data->len;
682 analog.data = (float *) data->data;
683 analog.mq = SR_MQ_VOLTAGE;
684 analog.unit = SR_UNIT_VOLT;
685 analog.mqflags = 0;
686 packet.type = SR_DF_ANALOG;
687 packet.payload = &analog;
688 sr_session_send(cb_data, &packet);
689 g_slist_free(analog.channels);
690 g_array_free(data, TRUE);
691 data = NULL;
692 break;
693 case SR_CHANNEL_LOGIC:
694 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
695 g_free(data);
696 return TRUE;
13f2b9d7 697 }
dc89faea
UH
698
699 packet.type = SR_DF_FRAME_BEGIN;
700 sr_session_send(sdi, &packet);
701
702 logic.length = data->len;
703 logic.unitsize = 1;
704 logic.data = data->data;
705 packet.type = SR_DF_LOGIC;
706 packet.payload = &logic;
707 sr_session_send(cb_data, &packet);
708 g_array_free(data, TRUE);
709 data = NULL;
710 break;
711 default:
712 sr_err("Invalid channel type.");
713 break;
714 }
715
716 packet.type = SR_DF_FRAME_END;
717 sr_session_send(sdi, &packet);
718
719 if (devc->current_channel->next) {
720 devc->current_channel = devc->current_channel->next;
721 hmo_request_data(sdi);
722 } else if (++devc->num_frames == devc->frame_limit) {
723 sdi->driver->dev_acquisition_stop(sdi, cb_data);
724 } else {
725 devc->current_channel = devc->enabled_channels;
726 hmo_request_data(sdi);
06a3e78a
DJ
727 }
728
729 return TRUE;
730}