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