]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Send exactly one sigrok frame per scope frame
[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?",
65a6794e
GS
34 [SCPI_CMD_GET_ANALOG_DATA] = ":FORM:BORD %s;" \
35 ":FORM REAL,32;:CHAN%d:DATA?",
13f2b9d7 36 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
965b463d 37 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
13f2b9d7
DJ
38 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
39 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
40 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
41 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP %s",
42 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
43 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
44 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
45 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
46 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
47 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
422a1c0d 48 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
13f2b9d7
DJ
49 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
50 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
448e81b1 51 [SCPI_CMD_GET_PROBE_UNIT] = ":PROB%d:SET:ATT:UNIT?",
13f2b9d7
DJ
52};
53
f254bc4b 54static const uint32_t hmo_devopts[] = {
13f2b9d7 55 SR_CONF_OSCILLOSCOPE,
a1b61e6e 56 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
5827f61b
BV
57 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
58 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 59 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b
BV
60 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
61 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
62 SR_CONF_SAMPLERATE | SR_CONF_GET,
13f2b9d7
DJ
63};
64
f254bc4b 65static const uint32_t hmo_analog_devopts[] = {
5827f61b
BV
66 SR_CONF_NUM_VDIV | SR_CONF_GET,
67 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
68 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
69};
70
71static const char *hmo_coupling_options[] = {
b05ab7d2
SB
72 "AC", // AC with 50 Ohm termination (152x, 202x, 30xx, 1202)
73 "ACL", // AC with 1 MOhm termination
74 "DC", // DC with 50 Ohm termination
75 "DCL", // DC with 1 MOhm termination
13f2b9d7
DJ
76 "GND",
77 NULL,
78};
79
80static const char *scope_trigger_slopes[] = {
81 "POS",
82 "NEG",
356f64f8 83 "EITH",
13f2b9d7
DJ
84 NULL,
85};
86
87static const char *hmo_compact2_trigger_sources[] = {
88 "CH1",
89 "CH2",
90 "LINE",
91 "EXT",
510aa828
SB
92 "PATT",
93 "BUS1",
94 "BUS2",
13f2b9d7
DJ
95 "D0",
96 "D1",
97 "D2",
98 "D3",
99 "D4",
100 "D5",
101 "D6",
102 "D7",
103 NULL,
104};
105
106static const char *hmo_compact4_trigger_sources[] = {
107 "CH1",
108 "CH2",
109 "CH3",
110 "CH4",
111 "LINE",
112 "EXT",
510aa828
SB
113 "PATT",
114 "BUS1",
115 "BUS2",
13f2b9d7
DJ
116 "D0",
117 "D1",
118 "D2",
119 "D3",
120 "D4",
121 "D5",
122 "D6",
123 "D7",
124 NULL,
125};
126
74413faf
GS
127static const char *hmo_compact4_dig16_trigger_sources[] = {
128 "CH1",
129 "CH2",
130 "CH3",
131 "CH4",
132 "LINE",
133 "EXT",
134 "PATT",
135 "BUS1",
136 "BUS2",
137 "D0",
138 "D1",
139 "D2",
140 "D3",
141 "D4",
142 "D5",
143 "D6",
144 "D7",
145 "D8",
146 "D9",
147 "D10",
148 "D11",
149 "D12",
150 "D13",
151 "D14",
152 "D15",
153 NULL,
154};
155
13f2b9d7
DJ
156static const uint64_t hmo_timebases[][2] = {
157 /* nanoseconds */
158 { 2, 1000000000 },
159 { 5, 1000000000 },
160 { 10, 1000000000 },
161 { 20, 1000000000 },
162 { 50, 1000000000 },
163 { 100, 1000000000 },
164 { 200, 1000000000 },
165 { 500, 1000000000 },
166 /* microseconds */
167 { 1, 1000000 },
168 { 2, 1000000 },
169 { 5, 1000000 },
170 { 10, 1000000 },
171 { 20, 1000000 },
172 { 50, 1000000 },
173 { 100, 1000000 },
174 { 200, 1000000 },
175 { 500, 1000000 },
176 /* milliseconds */
177 { 1, 1000 },
178 { 2, 1000 },
179 { 5, 1000 },
180 { 10, 1000 },
181 { 20, 1000 },
182 { 50, 1000 },
183 { 100, 1000 },
184 { 200, 1000 },
185 { 500, 1000 },
186 /* seconds */
187 { 1, 1 },
188 { 2, 1 },
189 { 5, 1 },
190 { 10, 1 },
191 { 20, 1 },
192 { 50, 1 },
193};
194
195static const uint64_t hmo_vdivs[][2] = {
196 /* millivolts */
197 { 1, 1000 },
198 { 2, 1000 },
199 { 5, 1000 },
200 { 10, 1000 },
201 { 20, 1000 },
202 { 50, 1000 },
203 { 100, 1000 },
204 { 200, 1000 },
205 { 500, 1000 },
206 /* volts */
207 { 1, 1 },
208 { 2, 1 },
209 { 5, 1 },
210 { 10, 1 },
fe227d17
SA
211 { 20, 1 },
212 { 50, 1 },
13f2b9d7
DJ
213};
214
ba7dd8bb 215static const char *scope_analog_channel_names[] = {
13f2b9d7
DJ
216 "CH1",
217 "CH2",
218 "CH3",
219 "CH4",
220};
221
ba7dd8bb 222static const char *scope_digital_channel_names[] = {
13f2b9d7
DJ
223 "D0",
224 "D1",
225 "D2",
226 "D3",
227 "D4",
228 "D5",
229 "D6",
230 "D7",
231 "D8",
232 "D9",
233 "D10",
234 "D11",
235 "D12",
236 "D13",
237 "D14",
238 "D15",
239};
240
329733d9 241static const struct scope_config scope_models[] = {
13f2b9d7 242 {
e786b194 243 /* HMO2522/3032/3042/3052 support 16 digital channels but they're not supported yet. */
da1726cc 244 .name = {"HMO1002", "HMO722", "HMO1022", "HMO1522", "HMO2022", "HMO2522",
e786b194 245 "HMO3032", "HMO3042", "HMO3052", NULL},
13f2b9d7
DJ
246 .analog_channels = 2,
247 .digital_channels = 8,
248 .digital_pods = 1,
249
ba7dd8bb
UH
250 .analog_names = &scope_analog_channel_names,
251 .digital_names = &scope_digital_channel_names,
13f2b9d7 252
f254bc4b
BV
253 .devopts = &hmo_devopts,
254 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 255
f254bc4b
BV
256 .analog_devopts = &hmo_analog_devopts,
257 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
258
259 .coupling_options = &hmo_coupling_options,
260 .trigger_sources = &hmo_compact2_trigger_sources,
261 .trigger_slopes = &scope_trigger_slopes,
262
263 .timebases = &hmo_timebases,
264 .num_timebases = ARRAY_SIZE(hmo_timebases),
265
266 .vdivs = &hmo_vdivs,
267 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
268
269 .num_xdivs = 12,
270 .num_ydivs = 8,
271
272 .scpi_dialect = &hameg_scpi_dialect,
273 },
274 {
74413faf 275 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
13f2b9d7
DJ
276 .analog_channels = 4,
277 .digital_channels = 8,
278 .digital_pods = 1,
279
ba7dd8bb
UH
280 .analog_names = &scope_analog_channel_names,
281 .digital_names = &scope_digital_channel_names,
13f2b9d7 282
f254bc4b
BV
283 .devopts = &hmo_devopts,
284 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 285
f254bc4b
BV
286 .analog_devopts = &hmo_analog_devopts,
287 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
288
289 .coupling_options = &hmo_coupling_options,
290 .trigger_sources = &hmo_compact4_trigger_sources,
291 .trigger_slopes = &scope_trigger_slopes,
292
293 .timebases = &hmo_timebases,
294 .num_timebases = ARRAY_SIZE(hmo_timebases),
295
296 .vdivs = &hmo_vdivs,
297 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
298
299 .num_xdivs = 12,
300 .num_ydivs = 8,
301
74413faf
GS
302 .scpi_dialect = &hameg_scpi_dialect,
303 },
304 {
305 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", NULL},
306 .analog_channels = 4,
307 .digital_channels = 16,
308 .digital_pods = 2,
309
310 .analog_names = &scope_analog_channel_names,
311 .digital_names = &scope_digital_channel_names,
312
313 .devopts = &hmo_devopts,
314 .num_devopts = ARRAY_SIZE(hmo_devopts),
315
316 .analog_devopts = &hmo_analog_devopts,
317 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
318
319 .coupling_options = &hmo_coupling_options,
320 .trigger_sources = &hmo_compact4_dig16_trigger_sources,
321 .trigger_slopes = &scope_trigger_slopes,
322
323 .timebases = &hmo_timebases,
324 .num_timebases = ARRAY_SIZE(hmo_timebases),
325
326 .vdivs = &hmo_vdivs,
327 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
328
329 .num_xdivs = 12,
330 .num_ydivs = 8,
331
13f2b9d7
DJ
332 .scpi_dialect = &hameg_scpi_dialect,
333 },
334};
335
329733d9 336static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
337 struct scope_state *state)
338{
339 unsigned int i;
8de2dc3b 340 char *tmp;
13f2b9d7 341
0a1f7b09 342 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
343 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
344 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
d9251a2c 345 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
8de2dc3b 346 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 347 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 348 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
349 }
350
0a1f7b09 351 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
352 sr_info("State of digital channel %d -> %s", i,
353 state->digital_channels[i] ? "On" : "Off");
354 }
355
0a1f7b09 356 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
357 sr_info("State of digital POD %d -> %s", i,
358 state->digital_pods[i] ? "On" : "Off");
359 }
360
8de2dc3b
DJ
361 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
362 (*config->timebases)[state->timebase][1]);
363 sr_info("Current timebase: %s", tmp);
364 g_free(tmp);
365
14a2f74d
DJ
366 tmp = sr_samplerate_string(state->sample_rate);
367 sr_info("Current samplerate: %s", tmp);
368 g_free(tmp);
369
422a1c0d 370 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
13f2b9d7
DJ
371 (*config->trigger_sources)[state->trigger_source],
372 (*config->trigger_slopes)[state->trigger_slope],
373 state->horiz_triggerpos);
374}
375
23f43dff 376static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
89280b1a 377 const char *command, const char *(*array)[], int *result)
13f2b9d7
DJ
378{
379 char *tmp;
380 unsigned int i;
381
23f43dff 382 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
89280b1a 383 g_free(tmp);
13f2b9d7
DJ
384 return SR_ERR;
385 }
386
0a1f7b09 387 for (i = 0; (*array)[i]; i++) {
13f2b9d7
DJ
388 if (!g_strcmp0(tmp, (*array)[i])) {
389 *result = i;
390 g_free(tmp);
391 tmp = NULL;
392 break;
393 }
394 }
395
396 if (tmp) {
397 g_free(tmp);
398 return SR_ERR;
399 }
400
401 return SR_OK;
402}
403
8fff7519 404/**
a53acd7d
SB
405 * This function takes a value of the form "2.000E-03" and returns the index
406 * of an array where a matching pair was found.
8fff7519
SA
407 *
408 * @param value The string to be parsed.
409 * @param array The array of s/f pairs.
410 * @param array_len The number of pairs in the array.
411 * @param result The index at which a matching pair was found.
412 *
413 * @return SR_ERR on any parsing error, SR_OK otherwise.
414 */
415static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 416 int array_len, unsigned int *result)
8fff7519 417{
a53acd7d
SB
418 struct sr_rational rval;
419 struct sr_rational aval;
8cccbac8 420
a53acd7d 421 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
422 return SR_ERR;
423
a53acd7d
SB
424 for (int i = 0; i < array_len; i++) {
425 sr_rational_set(&aval, array[i][0], array[i][1]);
426 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
427 *result = i;
428 return SR_OK;
429 }
430 }
431
432 return SR_ERR;
433}
434
23f43dff 435static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 436 const struct scope_config *config,
13f2b9d7
DJ
437 struct scope_state *state)
438{
8de2dc3b 439 unsigned int i, j;
13f2b9d7 440 char command[MAX_COMMAND_SIZE];
8fff7519 441 char *tmp_str;
13f2b9d7 442
0a1f7b09 443 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
444 g_snprintf(command, sizeof(command),
445 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
446 i + 1);
447
23f43dff 448 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
449 &state->analog_channels[i].state) != SR_OK)
450 return SR_ERR;
451
452 g_snprintf(command, sizeof(command),
453 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
454 i + 1);
455
8fff7519 456 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 457 return SR_ERR;
8fff7519
SA
458
459 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
460 &j) != SR_OK) {
461 g_free(tmp_str);
b4e31d2a 462 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 463 return SR_ERR;
b4e31d2a 464 }
13f2b9d7 465
8fff7519
SA
466 g_free(tmp_str);
467 state->analog_channels[i].vdiv = j;
468
13f2b9d7
DJ
469 g_snprintf(command, sizeof(command),
470 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
471 i + 1);
472
23f43dff 473 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
474 &state->analog_channels[i].vertical_offset) != SR_OK)
475 return SR_ERR;
476
477 g_snprintf(command, sizeof(command),
478 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
479 i + 1);
480
23f43dff 481 if (scope_state_get_array_option(scpi, command, config->coupling_options,
13f2b9d7
DJ
482 &state->analog_channels[i].coupling) != SR_OK)
483 return SR_ERR;
448e81b1
SB
484
485 g_snprintf(command, sizeof(command),
486 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
487 i + 1);
488
489 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
490 return SR_ERR;
491
492 if (tmp_str[0] == 'A')
493 state->analog_channels[i].probe_unit = 'A';
494 else
495 state->analog_channels[i].probe_unit = 'V';
496 g_free(tmp_str);
13f2b9d7
DJ
497 }
498
499 return SR_OK;
500}
501
23f43dff 502static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 503 const struct scope_config *config,
13f2b9d7
DJ
504 struct scope_state *state)
505{
506 unsigned int i;
507 char command[MAX_COMMAND_SIZE];
508
0a1f7b09 509 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
510 g_snprintf(command, sizeof(command),
511 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
512 i);
513
23f43dff 514 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
515 &state->digital_channels[i]) != SR_OK)
516 return SR_ERR;
517 }
518
0a1f7b09 519 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
520 g_snprintf(command, sizeof(command),
521 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
522 i + 1);
523
23f43dff 524 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
525 &state->digital_pods[i]) != SR_OK)
526 return SR_ERR;
527 }
528
529 return SR_OK;
530}
531
14a2f74d
DJ
532SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
533{
534 struct dev_context *devc;
535 struct scope_state *state;
329733d9 536 const struct scope_config *config;
14a2f74d
DJ
537
538 int tmp;
539 unsigned int i;
540 float tmp_float;
541 gboolean channel_found;
542 char tmp_str[MAX_COMMAND_SIZE];
543 char chan_name[20];
544
545 devc = sdi->priv;
546 config = devc->model_config;
547 state = devc->model_state;
548 channel_found = FALSE;
549
0a1f7b09 550 for (i = 0; i < config->analog_channels; i++) {
14a2f74d
DJ
551 if (state->analog_channels[i].state) {
552 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
553 g_snprintf(tmp_str, sizeof(tmp_str),
554 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
555 chan_name);
556 channel_found = TRUE;
557 break;
558 }
559 }
560
561 if (!channel_found) {
562 for (i = 0; i < config->digital_pods; i++) {
563 if (state->digital_pods[i]) {
564 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
565 g_snprintf(tmp_str, sizeof(tmp_str),
566 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
567 chan_name);
568 channel_found = TRUE;
569 break;
570 }
571 }
572 }
573
574 /* No channel is active, ask the instrument for the sample rate
575 * in single shot mode */
576 if (!channel_found) {
c06c24d2
DJ
577 if (sr_scpi_get_float(sdi->conn,
578 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
579 &tmp_float) != SR_OK)
14a2f74d 580 return SR_ERR;
c06c24d2 581
14a2f74d
DJ
582 state->sample_rate = tmp_float;
583 } else {
584 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
585 return SR_ERR;
586 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
587 (*config->timebases)[state->timebase][1]) *
588 config->num_xdivs);
589 }
590
591 return SR_OK;
592}
593
719eff68 594SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
595{
596 struct dev_context *devc;
597 struct scope_state *state;
329733d9 598 const struct scope_config *config;
8de2dc3b
DJ
599 float tmp_float;
600 unsigned int i;
8cccbac8 601 char *tmp_str;
13f2b9d7
DJ
602
603 devc = sdi->priv;
604 config = devc->model_config;
605 state = devc->model_state;
606
8de2dc3b
DJ
607 sr_info("Fetching scope state");
608
13f2b9d7
DJ
609 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
610 return SR_ERR;
611
612 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
613 return SR_ERR;
614
89280b1a
UH
615 if (sr_scpi_get_float(sdi->conn,
616 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
617 &tmp_float) != SR_OK)
618 return SR_ERR;
619
8cccbac8
SA
620 if (sr_scpi_get_string(sdi->conn,
621 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
622 &tmp_str) != SR_OK)
623 return SR_ERR;
624
625 if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
626 &i) != SR_OK) {
627 g_free(tmp_str);
b4e31d2a 628 sr_err("Could not determine array index for time base.");
13f2b9d7 629 return SR_ERR;
b4e31d2a 630 }
e5b7eef7 631 g_free(tmp_str);
13f2b9d7 632
8cccbac8
SA
633 state->timebase = i;
634
89280b1a
UH
635 if (sr_scpi_get_float(sdi->conn,
636 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 637 &tmp_float) != SR_OK)
13f2b9d7 638 return SR_ERR;
422a1c0d
DJ
639 state->horiz_triggerpos = tmp_float /
640 (((double) (*config->timebases)[state->timebase][0] /
641 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
642 state->horiz_triggerpos -= 0.5;
643 state->horiz_triggerpos *= -1;
13f2b9d7 644
89280b1a
UH
645 if (scope_state_get_array_option(sdi->conn,
646 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
647 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
648 return SR_ERR;
649
89280b1a
UH
650 if (scope_state_get_array_option(sdi->conn,
651 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
652 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
653 return SR_ERR;
654
14a2f74d
DJ
655 if (hmo_update_sample_rate(sdi) != SR_OK)
656 return SR_ERR;
657
8de2dc3b
DJ
658 sr_info("Fetching finished.");
659
13f2b9d7
DJ
660 scope_state_dump(config, state);
661
662 return SR_OK;
663}
664
329733d9 665static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
666{
667 struct scope_state *state;
668
a95f142e
UH
669 state = g_malloc0(sizeof(struct scope_state));
670 state->analog_channels = g_malloc0_n(config->analog_channels,
671 sizeof(struct analog_channel_state));
672 state->digital_channels = g_malloc0_n(
673 config->digital_channels, sizeof(gboolean));
674 state->digital_pods = g_malloc0_n(config->digital_pods,
675 sizeof(gboolean));
13f2b9d7
DJ
676
677 return state;
13f2b9d7
DJ
678}
679
719eff68 680SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
681{
682 g_free(state->analog_channels);
683 g_free(state->digital_channels);
684 g_free(state->digital_pods);
685 g_free(state);
686}
687
688SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
689{
690 char tmp[25];
691 int model_index;
2d224dba 692 unsigned int i, j, group;
ba7dd8bb 693 struct sr_channel *ch;
13f2b9d7
DJ
694 struct dev_context *devc;
695
696 devc = sdi->priv;
697 model_index = -1;
698
89280b1a 699 /* Find the exact model. */
13f2b9d7
DJ
700 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
701 for (j = 0; scope_models[i].name[j]; j++) {
702 if (!strcmp(sdi->model, scope_models[i].name[j])) {
703 model_index = i;
704 break;
705 }
706 }
707 if (model_index != -1)
708 break;
709 }
710
711 if (model_index == -1) {
89280b1a 712 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
713 return SR_ERR_NA;
714 }
715
562b7ae5
SA
716 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
717 scope_models[model_index].analog_channels);
13f2b9d7 718
562b7ae5
SA
719 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
720 scope_models[model_index].digital_pods);
13f2b9d7 721
89280b1a 722 /* Add analog channels. */
13f2b9d7 723 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 724 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 725 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 726
562b7ae5
SA
727 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
728
729 devc->analog_groups[i]->name = g_strdup(
730 (char *)(*scope_models[model_index].analog_names)[i]);
731 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 732
660e398f 733 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 734 devc->analog_groups[i]);
13f2b9d7
DJ
735 }
736
660e398f 737 /* Add digital channel groups. */
0a1f7b09 738 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
13f2b9d7 739 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
740
741 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
742
743 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 744 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 745 devc->digital_groups[i]);
13f2b9d7
DJ
746 }
747
89280b1a 748 /* Add digital channels. */
13f2b9d7 749 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 750 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 751 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 752
2d224dba
GS
753 group = i / 8;
754 devc->digital_groups[group]->channels = g_slist_append(
755 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
756 }
757
758 devc->model_config = &scope_models[model_index];
759 devc->frame_limit = 0;
760
761 if (!(devc->model_state = scope_state_new(devc->model_config)))
762 return SR_ERR_MALLOC;
763
764 return SR_OK;
765}
766
719eff68 767SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 768{
ba7dd8bb 769 struct sr_channel *ch;
13f2b9d7 770 struct sr_dev_inst *sdi;
06a3e78a 771 struct dev_context *devc;
401b83a1 772 struct scope_state *state;
13f2b9d7 773 struct sr_datafeed_packet packet;
401b83a1
SB
774 GByteArray *data;
775 struct sr_datafeed_analog analog;
776 struct sr_analog_encoding encoding;
777 struct sr_analog_meaning meaning;
778 struct sr_analog_spec spec;
89280b1a 779 struct sr_datafeed_logic logic;
06a3e78a
DJ
780
781 (void)fd;
f0729866 782 (void)revents;
06a3e78a 783
f62f595b
MK
784 data = NULL;
785
06a3e78a
DJ
786 if (!(sdi = cb_data))
787 return TRUE;
788
789 if (!(devc = sdi->priv))
790 return TRUE;
791
f4f273ce
SB
792 /* Although this is correct in general, the USBTMC libusb implementation
793 * currently does not generate an event prior to the first read. Often
794 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
795 if (revents != G_IO_IN)
796 return TRUE;
f4f273ce 797 */
13f2b9d7 798
dc89faea 799 ch = devc->current_channel->data;
401b83a1 800 state = devc->model_state;
13f2b9d7 801
b23eb1d4
GS
802 /*
803 * Send "frame begin" packet upon reception of data for the
804 * first enabled channel.
805 */
806 if (devc->current_channel == devc->enabled_channels) {
807 packet.type = SR_DF_FRAME_BEGIN;
808 sr_session_send(sdi, &packet);
809 }
810
811 /*
812 * Pass on the received data of the channel(s).
813 */
dc89faea
UH
814 switch (ch->type) {
815 case SR_CHANNEL_ANALOG:
401b83a1 816 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 817 if (data)
401b83a1 818 g_byte_array_free(data, TRUE);
13f2b9d7 819
dc89faea 820 return TRUE;
13f2b9d7
DJ
821 }
822
401b83a1
SB
823 packet.type = SR_DF_ANALOG;
824
825 analog.data = data->data;
826 analog.num_samples = data->len / sizeof(float);
827 analog.encoding = &encoding;
828 analog.meaning = &meaning;
829 analog.spec = &spec;
830
831 encoding.unitsize = sizeof(float);
832 encoding.is_signed = TRUE;
833 encoding.is_float = TRUE;
65a6794e
GS
834#ifdef WORDS_BIGENDIAN
835 encoding.is_bigendian = TRUE;
836#else
d1ad8b10 837 encoding.is_bigendian = FALSE;
65a6794e 838#endif
7dcaddd3
UH
839 /* TODO: Use proper 'digits' value for this device (and its modes). */
840 encoding.digits = 2;
401b83a1
SB
841 encoding.is_digits_decimal = FALSE;
842 encoding.scale.p = 1;
843 encoding.scale.q = 1;
844 encoding.offset.p = 0;
845 encoding.offset.q = 1;
846 if (state->analog_channels[ch->index].probe_unit == 'V') {
847 meaning.mq = SR_MQ_VOLTAGE;
848 meaning.unit = SR_UNIT_VOLT;
849 } else {
850 meaning.mq = SR_MQ_CURRENT;
851 meaning.unit = SR_UNIT_AMPERE;
852 }
853 meaning.mqflags = 0;
854 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
855 /* TODO: Use proper 'digits' value for this device (and its modes). */
856 spec.spec_digits = 2;
dc89faea 857 packet.payload = &analog;
695dc859 858 sr_session_send(sdi, &packet);
401b83a1
SB
859 g_slist_free(meaning.channels);
860 g_byte_array_free(data, TRUE);
dc89faea
UH
861 data = NULL;
862 break;
863 case SR_CHANNEL_LOGIC:
401b83a1 864 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea
UH
865 g_free(data);
866 return TRUE;
13f2b9d7 867 }
dc89faea 868
dc89faea
UH
869
870 logic.length = data->len;
871 logic.unitsize = 1;
872 logic.data = data->data;
873 packet.type = SR_DF_LOGIC;
874 packet.payload = &logic;
695dc859 875 sr_session_send(sdi, &packet);
401b83a1 876 g_byte_array_free(data, TRUE);
dc89faea
UH
877 data = NULL;
878 break;
879 default:
880 sr_err("Invalid channel type.");
881 break;
882 }
883
b23eb1d4
GS
884 /*
885 * Advance to the next enabled channel. When data for all enabled
886 * channels was received, then send the "frame end" packet.
887 */
dc89faea
UH
888 if (devc->current_channel->next) {
889 devc->current_channel = devc->current_channel->next;
890 hmo_request_data(sdi);
b23eb1d4
GS
891 return TRUE;
892 }
893 packet.type = SR_DF_FRAME_END;
894 sr_session_send(sdi, &packet);
895
896 /*
897 * End of frame was reached. Stop acquisition after the specified
898 * number of frames, or continue reception by starting over at
899 * the first enabled channel.
900 */
901 if (++devc->num_frames == devc->frame_limit) {
695dc859 902 sdi->driver->dev_acquisition_stop(sdi);
dc89faea
UH
903 } else {
904 devc->current_channel = devc->enabled_channels;
905 hmo_request_data(sdi);
06a3e78a
DJ
906 }
907
908 return TRUE;
909}