]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Release enabled channels when acquisition start fails
[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 26static const char *hameg_scpi_dialect[] = {
401b83a1 27 [SCPI_CMD_GET_DIG_DATA] = ":FORM UINT,8;:POD%d:DATA?",
13f2b9d7 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?",
401b83a1 34 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM REAL,32;:CHAN%d:DATA?",
13f2b9d7 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[] = {
b05ab7d2
SB
71 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
72 "ACL", // AC with 1 MOhm termination
73 "DC", // DC with 50 Ohm termination
74 "DCL", // DC with 1 MOhm termination
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]);
d9251a2c 287 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 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 }
e5b7eef7 573 g_free(tmp_str);
13f2b9d7 574
8cccbac8
SA
575 state->timebase = i;
576
89280b1a
UH
577 if (sr_scpi_get_float(sdi->conn,
578 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 579 &tmp_float) != SR_OK)
13f2b9d7 580 return SR_ERR;
422a1c0d
DJ
581 state->horiz_triggerpos = tmp_float /
582 (((double) (*config->timebases)[state->timebase][0] /
583 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
584 state->horiz_triggerpos -= 0.5;
585 state->horiz_triggerpos *= -1;
13f2b9d7 586
89280b1a
UH
587 if (scope_state_get_array_option(sdi->conn,
588 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
589 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
590 return SR_ERR;
591
89280b1a
UH
592 if (scope_state_get_array_option(sdi->conn,
593 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
594 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
595 return SR_ERR;
596
14a2f74d
DJ
597 if (hmo_update_sample_rate(sdi) != SR_OK)
598 return SR_ERR;
599
8de2dc3b
DJ
600 sr_info("Fetching finished.");
601
13f2b9d7
DJ
602 scope_state_dump(config, state);
603
604 return SR_OK;
605}
606
329733d9 607static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
608{
609 struct scope_state *state;
610
a95f142e
UH
611 state = g_malloc0(sizeof(struct scope_state));
612 state->analog_channels = g_malloc0_n(config->analog_channels,
613 sizeof(struct analog_channel_state));
614 state->digital_channels = g_malloc0_n(
615 config->digital_channels, sizeof(gboolean));
616 state->digital_pods = g_malloc0_n(config->digital_pods,
617 sizeof(gboolean));
13f2b9d7
DJ
618
619 return state;
13f2b9d7
DJ
620}
621
719eff68 622SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
623{
624 g_free(state->analog_channels);
625 g_free(state->digital_channels);
626 g_free(state->digital_pods);
627 g_free(state);
628}
629
630SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
631{
632 char tmp[25];
633 int model_index;
2d224dba 634 unsigned int i, j, group;
ba7dd8bb 635 struct sr_channel *ch;
13f2b9d7
DJ
636 struct dev_context *devc;
637
638 devc = sdi->priv;
639 model_index = -1;
640
89280b1a 641 /* Find the exact model. */
13f2b9d7
DJ
642 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
643 for (j = 0; scope_models[i].name[j]; j++) {
644 if (!strcmp(sdi->model, scope_models[i].name[j])) {
645 model_index = i;
646 break;
647 }
648 }
649 if (model_index != -1)
650 break;
651 }
652
653 if (model_index == -1) {
89280b1a 654 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
655 return SR_ERR_NA;
656 }
657
562b7ae5
SA
658 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
659 scope_models[model_index].analog_channels);
13f2b9d7 660
562b7ae5
SA
661 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
662 scope_models[model_index].digital_pods);
13f2b9d7 663
89280b1a 664 /* Add analog channels. */
13f2b9d7 665 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 666 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 667 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 668
562b7ae5
SA
669 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
670
671 devc->analog_groups[i]->name = g_strdup(
672 (char *)(*scope_models[model_index].analog_names)[i]);
673 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 674
660e398f 675 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 676 devc->analog_groups[i]);
13f2b9d7
DJ
677 }
678
660e398f 679 /* Add digital channel groups. */
0a1f7b09 680 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
13f2b9d7 681 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
682
683 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
684
685 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 686 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 687 devc->digital_groups[i]);
13f2b9d7
DJ
688 }
689
89280b1a 690 /* Add digital channels. */
13f2b9d7 691 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 692 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 693 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 694
2d224dba
GS
695 group = i / 8;
696 devc->digital_groups[group]->channels = g_slist_append(
697 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
698 }
699
700 devc->model_config = &scope_models[model_index];
701 devc->frame_limit = 0;
702
703 if (!(devc->model_state = scope_state_new(devc->model_config)))
704 return SR_ERR_MALLOC;
705
706 return SR_OK;
707}
708
719eff68 709SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 710{
ba7dd8bb 711 struct sr_channel *ch;
13f2b9d7 712 struct sr_dev_inst *sdi;
06a3e78a 713 struct dev_context *devc;
401b83a1 714 struct scope_state *state;
13f2b9d7 715 struct sr_datafeed_packet packet;
401b83a1
SB
716 GByteArray *data;
717 struct sr_datafeed_analog analog;
718 struct sr_analog_encoding encoding;
719 struct sr_analog_meaning meaning;
720 struct sr_analog_spec spec;
89280b1a 721 struct sr_datafeed_logic logic;
06a3e78a
DJ
722
723 (void)fd;
f0729866 724 (void)revents;
06a3e78a 725
f62f595b
MK
726 data = NULL;
727
06a3e78a
DJ
728 if (!(sdi = cb_data))
729 return TRUE;
730
731 if (!(devc = sdi->priv))
732 return TRUE;
733
f4f273ce
SB
734 /* Although this is correct in general, the USBTMC libusb implementation
735 * currently does not generate an event prior to the first read. Often
736 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
737 if (revents != G_IO_IN)
738 return TRUE;
f4f273ce 739 */
13f2b9d7 740
dc89faea 741 ch = devc->current_channel->data;
401b83a1 742 state = devc->model_state;
13f2b9d7 743
dc89faea
UH
744 switch (ch->type) {
745 case SR_CHANNEL_ANALOG:
401b83a1 746 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 747 if (data)
401b83a1 748 g_byte_array_free(data, TRUE);
13f2b9d7 749
dc89faea 750 return TRUE;
13f2b9d7
DJ
751 }
752
dc89faea 753 packet.type = SR_DF_FRAME_BEGIN;
13f2b9d7
DJ
754 sr_session_send(sdi, &packet);
755
401b83a1
SB
756 packet.type = SR_DF_ANALOG;
757
758 analog.data = data->data;
759 analog.num_samples = data->len / sizeof(float);
760 analog.encoding = &encoding;
761 analog.meaning = &meaning;
762 analog.spec = &spec;
763
764 encoding.unitsize = sizeof(float);
765 encoding.is_signed = TRUE;
766 encoding.is_float = TRUE;
767 encoding.is_bigendian = FALSE;
7dcaddd3
UH
768 /* TODO: Use proper 'digits' value for this device (and its modes). */
769 encoding.digits = 2;
401b83a1
SB
770 encoding.is_digits_decimal = FALSE;
771 encoding.scale.p = 1;
772 encoding.scale.q = 1;
773 encoding.offset.p = 0;
774 encoding.offset.q = 1;
775 if (state->analog_channels[ch->index].probe_unit == 'V') {
776 meaning.mq = SR_MQ_VOLTAGE;
777 meaning.unit = SR_UNIT_VOLT;
778 } else {
779 meaning.mq = SR_MQ_CURRENT;
780 meaning.unit = SR_UNIT_AMPERE;
781 }
782 meaning.mqflags = 0;
783 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
784 /* TODO: Use proper 'digits' value for this device (and its modes). */
785 spec.spec_digits = 2;
dc89faea 786 packet.payload = &analog;
695dc859 787 sr_session_send(sdi, &packet);
401b83a1
SB
788 g_slist_free(meaning.channels);
789 g_byte_array_free(data, TRUE);
dc89faea
UH
790 data = NULL;
791 break;
792 case SR_CHANNEL_LOGIC:
401b83a1 793 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea
UH
794 g_free(data);
795 return TRUE;
13f2b9d7 796 }
dc89faea
UH
797
798 packet.type = SR_DF_FRAME_BEGIN;
799 sr_session_send(sdi, &packet);
800
801 logic.length = data->len;
802 logic.unitsize = 1;
803 logic.data = data->data;
804 packet.type = SR_DF_LOGIC;
805 packet.payload = &logic;
695dc859 806 sr_session_send(sdi, &packet);
401b83a1 807 g_byte_array_free(data, TRUE);
dc89faea
UH
808 data = NULL;
809 break;
810 default:
811 sr_err("Invalid channel type.");
812 break;
813 }
814
815 packet.type = SR_DF_FRAME_END;
816 sr_session_send(sdi, &packet);
817
818 if (devc->current_channel->next) {
819 devc->current_channel = devc->current_channel->next;
820 hmo_request_data(sdi);
821 } else if (++devc->num_frames == devc->frame_limit) {
695dc859 822 sdi->driver->dev_acquisition_stop(sdi);
dc89faea
UH
823 } else {
824 devc->current_channel = devc->enabled_channels;
825 hmo_request_data(sdi);
06a3e78a
DJ
826 }
827
828 return TRUE;
829}