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