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