]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add comment clarifying coupling options
[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]);
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;
401b83a1 712 struct scope_state *state;
13f2b9d7 713 struct sr_datafeed_packet packet;
401b83a1
SB
714 GByteArray *data;
715 struct sr_datafeed_analog analog;
716 struct sr_analog_encoding encoding;
717 struct sr_analog_meaning meaning;
718 struct sr_analog_spec spec;
89280b1a 719 struct sr_datafeed_logic logic;
06a3e78a
DJ
720
721 (void)fd;
f0729866 722 (void)revents;
06a3e78a 723
f62f595b
MK
724 data = NULL;
725
06a3e78a
DJ
726 if (!(sdi = cb_data))
727 return TRUE;
728
729 if (!(devc = sdi->priv))
730 return TRUE;
731
f4f273ce
SB
732 /* Although this is correct in general, the USBTMC libusb implementation
733 * currently does not generate an event prior to the first read. Often
734 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
735 if (revents != G_IO_IN)
736 return TRUE;
f4f273ce 737 */
13f2b9d7 738
dc89faea 739 ch = devc->current_channel->data;
401b83a1 740 state = devc->model_state;
13f2b9d7 741
dc89faea
UH
742 switch (ch->type) {
743 case SR_CHANNEL_ANALOG:
401b83a1 744 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 745 if (data)
401b83a1 746 g_byte_array_free(data, TRUE);
13f2b9d7 747
dc89faea 748 return TRUE;
13f2b9d7
DJ
749 }
750
dc89faea 751 packet.type = SR_DF_FRAME_BEGIN;
13f2b9d7
DJ
752 sr_session_send(sdi, &packet);
753
401b83a1
SB
754 packet.type = SR_DF_ANALOG;
755
756 analog.data = data->data;
757 analog.num_samples = data->len / sizeof(float);
758 analog.encoding = &encoding;
759 analog.meaning = &meaning;
760 analog.spec = &spec;
761
762 encoding.unitsize = sizeof(float);
763 encoding.is_signed = TRUE;
764 encoding.is_float = TRUE;
765 encoding.is_bigendian = FALSE;
766 encoding.digits = 0;
767 encoding.is_digits_decimal = FALSE;
768 encoding.scale.p = 1;
769 encoding.scale.q = 1;
770 encoding.offset.p = 0;
771 encoding.offset.q = 1;
772 if (state->analog_channels[ch->index].probe_unit == 'V') {
773 meaning.mq = SR_MQ_VOLTAGE;
774 meaning.unit = SR_UNIT_VOLT;
775 } else {
776 meaning.mq = SR_MQ_CURRENT;
777 meaning.unit = SR_UNIT_AMPERE;
778 }
779 meaning.mqflags = 0;
780 meaning.channels = g_slist_append(NULL, ch);
781 spec.spec_digits = 0;
dc89faea 782 packet.payload = &analog;
695dc859 783 sr_session_send(sdi, &packet);
401b83a1
SB
784 g_slist_free(meaning.channels);
785 g_byte_array_free(data, TRUE);
dc89faea
UH
786 data = NULL;
787 break;
788 case SR_CHANNEL_LOGIC:
401b83a1 789 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea
UH
790 g_free(data);
791 return TRUE;
13f2b9d7 792 }
dc89faea
UH
793
794 packet.type = SR_DF_FRAME_BEGIN;
795 sr_session_send(sdi, &packet);
796
797 logic.length = data->len;
798 logic.unitsize = 1;
799 logic.data = data->data;
800 packet.type = SR_DF_LOGIC;
801 packet.payload = &logic;
695dc859 802 sr_session_send(sdi, &packet);
401b83a1 803 g_byte_array_free(data, TRUE);
dc89faea
UH
804 data = NULL;
805 break;
806 default:
807 sr_err("Invalid channel type.");
808 break;
809 }
810
811 packet.type = SR_DF_FRAME_END;
812 sr_session_send(sdi, &packet);
813
814 if (devc->current_channel->next) {
815 devc->current_channel = devc->current_channel->next;
816 hmo_request_data(sdi);
817 } else if (++devc->num_frames == devc->frame_limit) {
695dc859 818 sdi->driver->dev_acquisition_stop(sdi);
dc89faea
UH
819 } else {
820 devc->current_channel = devc->enabled_channels;
821 hmo_request_data(sdi);
06a3e78a
DJ
822 }
823
824 return TRUE;
825}