]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add PATTern and BUS1/BUS2 trigger sources
[libsigrok.git] / src / hardware / hameg-hmo / protocol.c
CommitLineData
06a3e78a
DJ
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
6ec6c43b 20#include <config.h>
650847e7
UH
21#include <math.h>
22#include <stdlib.h>
5a1afc09 23#include "scpi.h"
06a3e78a
DJ
24#include "protocol.h"
25
13f2b9d7
DJ
26static const char *hameg_scpi_dialect[] = {
27 [SCPI_CMD_GET_DIG_DATA] = ":POD%d:DATA?",
28 [SCPI_CMD_GET_TIMEBASE] = ":TIM:SCAL?",
965b463d 29 [SCPI_CMD_SET_TIMEBASE] = ":TIM:SCAL %s",
13f2b9d7
DJ
30 [SCPI_CMD_GET_COUPLING] = ":CHAN%d:COUP?",
31 [SCPI_CMD_SET_COUPLING] = ":CHAN%d:COUP %s",
14a2f74d
DJ
32 [SCPI_CMD_GET_SAMPLE_RATE] = ":ACQ:SRAT?",
33 [SCPI_CMD_GET_SAMPLE_RATE_LIVE] = ":%s:DATA:POINTS?",
13f2b9d7
DJ
34 [SCPI_CMD_GET_ANALOG_DATA] = ":CHAN%d:DATA?",
35 [SCPI_CMD_GET_VERTICAL_DIV] = ":CHAN%d:SCAL?",
965b463d 36 [SCPI_CMD_SET_VERTICAL_DIV] = ":CHAN%d:SCAL %s",
13f2b9d7
DJ
37 [SCPI_CMD_GET_DIG_POD_STATE] = ":POD%d:STAT?",
38 [SCPI_CMD_SET_DIG_POD_STATE] = ":POD%d:STAT %d",
39 [SCPI_CMD_GET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP?",
40 [SCPI_CMD_SET_TRIGGER_SLOPE] = ":TRIG:A:EDGE:SLOP %s",
41 [SCPI_CMD_GET_TRIGGER_SOURCE] = ":TRIG:A:SOUR?",
42 [SCPI_CMD_SET_TRIGGER_SOURCE] = ":TRIG:A:SOUR %s",
43 [SCPI_CMD_GET_DIG_CHAN_STATE] = ":LOG%d:STAT?",
44 [SCPI_CMD_SET_DIG_CHAN_STATE] = ":LOG%d:STAT %d",
45 [SCPI_CMD_GET_VERTICAL_OFFSET] = ":CHAN%d:POS?",
46 [SCPI_CMD_GET_HORIZ_TRIGGERPOS] = ":TIM:POS?",
422a1c0d 47 [SCPI_CMD_SET_HORIZ_TRIGGERPOS] = ":TIM:POS %s",
13f2b9d7
DJ
48 [SCPI_CMD_GET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT?",
49 [SCPI_CMD_SET_ANALOG_CHAN_STATE] = ":CHAN%d:STAT %d",
50};
51
f254bc4b 52static const uint32_t hmo_devopts[] = {
13f2b9d7 53 SR_CONF_OSCILLOSCOPE,
a1b61e6e 54 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
5827f61b
BV
55 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
56 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 57 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b
BV
58 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
59 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
60 SR_CONF_SAMPLERATE | SR_CONF_GET,
13f2b9d7
DJ
61};
62
f254bc4b 63static const uint32_t hmo_analog_devopts[] = {
5827f61b
BV
64 SR_CONF_NUM_VDIV | SR_CONF_GET,
65 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
66 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
67};
68
69static const char *hmo_coupling_options[] = {
70 "AC",
71 "ACL",
72 "DC",
53cd1c78 73 "DCL",
13f2b9d7
DJ
74 "GND",
75 NULL,
76};
77
78static const char *scope_trigger_slopes[] = {
79 "POS",
80 "NEG",
356f64f8 81 "EITH",
13f2b9d7
DJ
82 NULL,
83};
84
85static const char *hmo_compact2_trigger_sources[] = {
86 "CH1",
87 "CH2",
88 "LINE",
89 "EXT",
510aa828
SB
90 "PATT",
91 "BUS1",
92 "BUS2",
13f2b9d7
DJ
93 "D0",
94 "D1",
95 "D2",
96 "D3",
97 "D4",
98 "D5",
99 "D6",
100 "D7",
101 NULL,
102};
103
104static const char *hmo_compact4_trigger_sources[] = {
105 "CH1",
106 "CH2",
107 "CH3",
108 "CH4",
109 "LINE",
110 "EXT",
510aa828
SB
111 "PATT",
112 "BUS1",
113 "BUS2",
13f2b9d7
DJ
114 "D0",
115 "D1",
116 "D2",
117 "D3",
118 "D4",
119 "D5",
120 "D6",
121 "D7",
122 NULL,
123};
124
125static const uint64_t hmo_timebases[][2] = {
126 /* nanoseconds */
127 { 2, 1000000000 },
128 { 5, 1000000000 },
129 { 10, 1000000000 },
130 { 20, 1000000000 },
131 { 50, 1000000000 },
132 { 100, 1000000000 },
133 { 200, 1000000000 },
134 { 500, 1000000000 },
135 /* microseconds */
136 { 1, 1000000 },
137 { 2, 1000000 },
138 { 5, 1000000 },
139 { 10, 1000000 },
140 { 20, 1000000 },
141 { 50, 1000000 },
142 { 100, 1000000 },
143 { 200, 1000000 },
144 { 500, 1000000 },
145 /* milliseconds */
146 { 1, 1000 },
147 { 2, 1000 },
148 { 5, 1000 },
149 { 10, 1000 },
150 { 20, 1000 },
151 { 50, 1000 },
152 { 100, 1000 },
153 { 200, 1000 },
154 { 500, 1000 },
155 /* seconds */
156 { 1, 1 },
157 { 2, 1 },
158 { 5, 1 },
159 { 10, 1 },
160 { 20, 1 },
161 { 50, 1 },
162};
163
164static const uint64_t hmo_vdivs[][2] = {
165 /* millivolts */
166 { 1, 1000 },
167 { 2, 1000 },
168 { 5, 1000 },
169 { 10, 1000 },
170 { 20, 1000 },
171 { 50, 1000 },
172 { 100, 1000 },
173 { 200, 1000 },
174 { 500, 1000 },
175 /* volts */
176 { 1, 1 },
177 { 2, 1 },
178 { 5, 1 },
179 { 10, 1 },
fe227d17
SA
180 { 20, 1 },
181 { 50, 1 },
13f2b9d7
DJ
182};
183
ba7dd8bb 184static const char *scope_analog_channel_names[] = {
13f2b9d7
DJ
185 "CH1",
186 "CH2",
187 "CH3",
188 "CH4",
189};
190
ba7dd8bb 191static const char *scope_digital_channel_names[] = {
13f2b9d7
DJ
192 "D0",
193 "D1",
194 "D2",
195 "D3",
196 "D4",
197 "D5",
198 "D6",
199 "D7",
200 "D8",
201 "D9",
202 "D10",
203 "D11",
204 "D12",
205 "D13",
206 "D14",
207 "D15",
208};
209
329733d9 210static const struct scope_config scope_models[] = {
13f2b9d7 211 {
e786b194 212 /* HMO2522/3032/3042/3052 support 16 digital channels but they're not supported yet. */
da1726cc 213 .name = {"HMO1002", "HMO722", "HMO1022", "HMO1522", "HMO2022", "HMO2522",
e786b194 214 "HMO3032", "HMO3042", "HMO3052", NULL},
13f2b9d7
DJ
215 .analog_channels = 2,
216 .digital_channels = 8,
217 .digital_pods = 1,
218
ba7dd8bb
UH
219 .analog_names = &scope_analog_channel_names,
220 .digital_names = &scope_digital_channel_names,
13f2b9d7 221
f254bc4b
BV
222 .devopts = &hmo_devopts,
223 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 224
f254bc4b
BV
225 .analog_devopts = &hmo_analog_devopts,
226 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
227
228 .coupling_options = &hmo_coupling_options,
229 .trigger_sources = &hmo_compact2_trigger_sources,
230 .trigger_slopes = &scope_trigger_slopes,
231
232 .timebases = &hmo_timebases,
233 .num_timebases = ARRAY_SIZE(hmo_timebases),
234
235 .vdivs = &hmo_vdivs,
236 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
237
238 .num_xdivs = 12,
239 .num_ydivs = 8,
240
241 .scpi_dialect = &hameg_scpi_dialect,
242 },
243 {
e786b194
SA
244 /* HMO2524/3034/3044/3054 support 16 digital channels but they're not supported yet. */
245 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", "HMO2524",
246 "HMO3034", "HMO3044", "HMO3054", NULL},
13f2b9d7
DJ
247 .analog_channels = 4,
248 .digital_channels = 8,
249 .digital_pods = 1,
250
ba7dd8bb
UH
251 .analog_names = &scope_analog_channel_names,
252 .digital_names = &scope_digital_channel_names,
13f2b9d7 253
f254bc4b
BV
254 .devopts = &hmo_devopts,
255 .num_devopts = ARRAY_SIZE(hmo_devopts),
13f2b9d7 256
f254bc4b
BV
257 .analog_devopts = &hmo_analog_devopts,
258 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
13f2b9d7
DJ
259
260 .coupling_options = &hmo_coupling_options,
261 .trigger_sources = &hmo_compact4_trigger_sources,
262 .trigger_slopes = &scope_trigger_slopes,
263
264 .timebases = &hmo_timebases,
265 .num_timebases = ARRAY_SIZE(hmo_timebases),
266
267 .vdivs = &hmo_vdivs,
268 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
269
270 .num_xdivs = 12,
271 .num_ydivs = 8,
272
273 .scpi_dialect = &hameg_scpi_dialect,
274 },
275};
276
329733d9 277static void scope_state_dump(const struct scope_config *config,
13f2b9d7
DJ
278 struct scope_state *state)
279{
280 unsigned int i;
8de2dc3b 281 char *tmp;
13f2b9d7 282
0a1f7b09 283 for (i = 0; i < config->analog_channels; i++) {
8de2dc3b
DJ
284 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
285 (*config->vdivs)[state->analog_channels[i].vdiv][1]);
286 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
287 i + 1, state->analog_channels[i].state ? "On" : "Off",
13f2b9d7 288 (*config->coupling_options)[state->analog_channels[i].coupling],
8de2dc3b 289 tmp, state->analog_channels[i].vertical_offset);
13f2b9d7
DJ
290 }
291
0a1f7b09 292 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
293 sr_info("State of digital channel %d -> %s", i,
294 state->digital_channels[i] ? "On" : "Off");
295 }
296
0a1f7b09 297 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
298 sr_info("State of digital POD %d -> %s", i,
299 state->digital_pods[i] ? "On" : "Off");
300 }
301
8de2dc3b
DJ
302 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
303 (*config->timebases)[state->timebase][1]);
304 sr_info("Current timebase: %s", tmp);
305 g_free(tmp);
306
14a2f74d
DJ
307 tmp = sr_samplerate_string(state->sample_rate);
308 sr_info("Current samplerate: %s", tmp);
309 g_free(tmp);
310
422a1c0d 311 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
13f2b9d7
DJ
312 (*config->trigger_sources)[state->trigger_source],
313 (*config->trigger_slopes)[state->trigger_slope],
314 state->horiz_triggerpos);
315}
316
23f43dff 317static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
89280b1a 318 const char *command, const char *(*array)[], int *result)
13f2b9d7
DJ
319{
320 char *tmp;
321 unsigned int i;
322
23f43dff 323 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
89280b1a 324 g_free(tmp);
13f2b9d7
DJ
325 return SR_ERR;
326 }
327
0a1f7b09 328 for (i = 0; (*array)[i]; i++) {
13f2b9d7
DJ
329 if (!g_strcmp0(tmp, (*array)[i])) {
330 *result = i;
331 g_free(tmp);
332 tmp = NULL;
333 break;
334 }
335 }
336
337 if (tmp) {
338 g_free(tmp);
339 return SR_ERR;
340 }
341
342 return SR_OK;
343}
344
8fff7519
SA
345/**
346 * This function takes a value of the form "2.000E-03", converts it to a
347 * significand / factor pair and returns the index of an array where
348 * a matching pair was found.
349 *
350 * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
351 * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
352 * Therefore it's easier to break the number up into two strings and handle
353 * them separately.
354 *
355 * @param value The string to be parsed.
356 * @param array The array of s/f pairs.
357 * @param array_len The number of pairs in the array.
358 * @param result The index at which a matching pair was found.
359 *
360 * @return SR_ERR on any parsing error, SR_OK otherwise.
361 */
362static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 363 int array_len, unsigned int *result)
8fff7519 364{
10c4ca9c
SA
365 int i, e;
366 size_t pos;
8fff7519
SA
367 uint64_t f;
368 float s;
369 unsigned int s_int;
370 gchar ss[10], es[10];
371
372 memset(ss, 0, sizeof(ss));
373 memset(es, 0, sizeof(es));
374
8cccbac8 375 /* Get index of the separating 'E' character and break up the string. */
10c4ca9c 376 pos = strcspn(value, "E");
8cccbac8
SA
377
378 strncpy(ss, value, pos);
379 strncpy(es, &(value[pos+1]), 3);
8fff7519
SA
380
381 if (sr_atof_ascii(ss, &s) != SR_OK)
382 return SR_ERR;
8cccbac8 383 if (sr_atoi(es, &e) != SR_OK)
8fff7519
SA
384 return SR_ERR;
385
386 /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
8cccbac8 387 f = pow(10, abs(e));
8fff7519
SA
388
389 /*
390 * Adjust the significand/factor pair to make sure
391 * that f is a multiple of 1000.
392 */
393 while ((int)fmod(log10(f), 3) > 0) {
394 s *= 10;
8cccbac8
SA
395
396 if (e < 0)
397 f *= 10;
398 else
399 f /= 10;
8fff7519
SA
400 }
401
402 /* Truncate s to circumvent rounding errors. */
403 s_int = (unsigned int)s;
404
405 for (i = 0; i < array_len; i++) {
406 if ((s_int == array[i][0]) && (f == array[i][1])) {
407 *result = i;
408 return SR_OK;
409 }
410 }
411
412 return SR_ERR;
413}
414
23f43dff 415static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 416 const struct scope_config *config,
13f2b9d7
DJ
417 struct scope_state *state)
418{
8de2dc3b 419 unsigned int i, j;
13f2b9d7 420 char command[MAX_COMMAND_SIZE];
8fff7519 421 char *tmp_str;
13f2b9d7 422
0a1f7b09 423 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
424 g_snprintf(command, sizeof(command),
425 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
426 i + 1);
427
23f43dff 428 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
429 &state->analog_channels[i].state) != SR_OK)
430 return SR_ERR;
431
432 g_snprintf(command, sizeof(command),
433 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
434 i + 1);
435
8fff7519 436 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 437 return SR_ERR;
8fff7519
SA
438
439 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
440 &j) != SR_OK) {
441 g_free(tmp_str);
b4e31d2a 442 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 443 return SR_ERR;
b4e31d2a 444 }
13f2b9d7 445
8fff7519
SA
446 g_free(tmp_str);
447 state->analog_channels[i].vdiv = j;
448
13f2b9d7
DJ
449 g_snprintf(command, sizeof(command),
450 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
451 i + 1);
452
23f43dff 453 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
454 &state->analog_channels[i].vertical_offset) != SR_OK)
455 return SR_ERR;
456
457 g_snprintf(command, sizeof(command),
458 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
459 i + 1);
460
23f43dff 461 if (scope_state_get_array_option(scpi, command, config->coupling_options,
13f2b9d7
DJ
462 &state->analog_channels[i].coupling) != SR_OK)
463 return SR_ERR;
464 }
465
466 return SR_OK;
467}
468
23f43dff 469static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 470 const struct scope_config *config,
13f2b9d7
DJ
471 struct scope_state *state)
472{
473 unsigned int i;
474 char command[MAX_COMMAND_SIZE];
475
0a1f7b09 476 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
477 g_snprintf(command, sizeof(command),
478 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
479 i);
480
23f43dff 481 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
482 &state->digital_channels[i]) != SR_OK)
483 return SR_ERR;
484 }
485
0a1f7b09 486 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
487 g_snprintf(command, sizeof(command),
488 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
489 i + 1);
490
23f43dff 491 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
492 &state->digital_pods[i]) != SR_OK)
493 return SR_ERR;
494 }
495
496 return SR_OK;
497}
498
14a2f74d
DJ
499SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
500{
501 struct dev_context *devc;
502 struct scope_state *state;
329733d9 503 const struct scope_config *config;
14a2f74d
DJ
504
505 int tmp;
506 unsigned int i;
507 float tmp_float;
508 gboolean channel_found;
509 char tmp_str[MAX_COMMAND_SIZE];
510 char chan_name[20];
511
512 devc = sdi->priv;
513 config = devc->model_config;
514 state = devc->model_state;
515 channel_found = FALSE;
516
0a1f7b09 517 for (i = 0; i < config->analog_channels; i++) {
14a2f74d
DJ
518 if (state->analog_channels[i].state) {
519 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
520 g_snprintf(tmp_str, sizeof(tmp_str),
521 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
522 chan_name);
523 channel_found = TRUE;
524 break;
525 }
526 }
527
528 if (!channel_found) {
529 for (i = 0; i < config->digital_pods; i++) {
530 if (state->digital_pods[i]) {
531 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
532 g_snprintf(tmp_str, sizeof(tmp_str),
533 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
534 chan_name);
535 channel_found = TRUE;
536 break;
537 }
538 }
539 }
540
541 /* No channel is active, ask the instrument for the sample rate
542 * in single shot mode */
543 if (!channel_found) {
c06c24d2
DJ
544 if (sr_scpi_get_float(sdi->conn,
545 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
546 &tmp_float) != SR_OK)
14a2f74d 547 return SR_ERR;
c06c24d2 548
14a2f74d
DJ
549 state->sample_rate = tmp_float;
550 } else {
551 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
552 return SR_ERR;
553 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
554 (*config->timebases)[state->timebase][1]) *
555 config->num_xdivs);
556 }
557
558 return SR_OK;
559}
560
719eff68 561SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
562{
563 struct dev_context *devc;
564 struct scope_state *state;
329733d9 565 const struct scope_config *config;
8de2dc3b
DJ
566 float tmp_float;
567 unsigned int i;
8cccbac8 568 char *tmp_str;
13f2b9d7
DJ
569
570 devc = sdi->priv;
571 config = devc->model_config;
572 state = devc->model_state;
573
8de2dc3b
DJ
574 sr_info("Fetching scope state");
575
13f2b9d7
DJ
576 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
577 return SR_ERR;
578
579 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
580 return SR_ERR;
581
89280b1a
UH
582 if (sr_scpi_get_float(sdi->conn,
583 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
584 &tmp_float) != SR_OK)
585 return SR_ERR;
586
8cccbac8
SA
587 if (sr_scpi_get_string(sdi->conn,
588 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
589 &tmp_str) != SR_OK)
590 return SR_ERR;
591
592 if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
593 &i) != SR_OK) {
594 g_free(tmp_str);
b4e31d2a 595 sr_err("Could not determine array index for time base.");
13f2b9d7 596 return SR_ERR;
b4e31d2a 597 }
13f2b9d7 598
8cccbac8
SA
599 state->timebase = i;
600
89280b1a
UH
601 if (sr_scpi_get_float(sdi->conn,
602 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 603 &tmp_float) != SR_OK)
13f2b9d7 604 return SR_ERR;
422a1c0d
DJ
605 state->horiz_triggerpos = tmp_float /
606 (((double) (*config->timebases)[state->timebase][0] /
607 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
608 state->horiz_triggerpos -= 0.5;
609 state->horiz_triggerpos *= -1;
13f2b9d7 610
89280b1a
UH
611 if (scope_state_get_array_option(sdi->conn,
612 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
613 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
614 return SR_ERR;
615
89280b1a
UH
616 if (scope_state_get_array_option(sdi->conn,
617 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
618 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
619 return SR_ERR;
620
14a2f74d
DJ
621 if (hmo_update_sample_rate(sdi) != SR_OK)
622 return SR_ERR;
623
8de2dc3b
DJ
624 sr_info("Fetching finished.");
625
13f2b9d7
DJ
626 scope_state_dump(config, state);
627
628 return SR_OK;
629}
630
329733d9 631static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
632{
633 struct scope_state *state;
634
a95f142e
UH
635 state = g_malloc0(sizeof(struct scope_state));
636 state->analog_channels = g_malloc0_n(config->analog_channels,
637 sizeof(struct analog_channel_state));
638 state->digital_channels = g_malloc0_n(
639 config->digital_channels, sizeof(gboolean));
640 state->digital_pods = g_malloc0_n(config->digital_pods,
641 sizeof(gboolean));
13f2b9d7
DJ
642
643 return state;
13f2b9d7
DJ
644}
645
719eff68 646SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
647{
648 g_free(state->analog_channels);
649 g_free(state->digital_channels);
650 g_free(state->digital_pods);
651 g_free(state);
652}
653
654SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
655{
656 char tmp[25];
657 int model_index;
89280b1a 658 unsigned int i, j;
ba7dd8bb 659 struct sr_channel *ch;
13f2b9d7
DJ
660 struct dev_context *devc;
661
662 devc = sdi->priv;
663 model_index = -1;
664
89280b1a 665 /* Find the exact model. */
13f2b9d7
DJ
666 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
667 for (j = 0; scope_models[i].name[j]; j++) {
668 if (!strcmp(sdi->model, scope_models[i].name[j])) {
669 model_index = i;
670 break;
671 }
672 }
673 if (model_index != -1)
674 break;
675 }
676
677 if (model_index == -1) {
89280b1a 678 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
679 return SR_ERR_NA;
680 }
681
562b7ae5
SA
682 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
683 scope_models[model_index].analog_channels);
13f2b9d7 684
562b7ae5
SA
685 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
686 scope_models[model_index].digital_pods);
13f2b9d7 687
89280b1a 688 /* Add analog channels. */
13f2b9d7 689 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 690 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 691 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 692
562b7ae5
SA
693 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
694
695 devc->analog_groups[i]->name = g_strdup(
696 (char *)(*scope_models[model_index].analog_names)[i]);
697 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 698
660e398f 699 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 700 devc->analog_groups[i]);
13f2b9d7
DJ
701 }
702
660e398f 703 /* Add digital channel groups. */
0a1f7b09 704 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
13f2b9d7 705 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
706
707 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
708
709 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 710 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 711 devc->digital_groups[i < 8 ? 0 : 1]);
13f2b9d7
DJ
712 }
713
89280b1a 714 /* Add digital channels. */
13f2b9d7 715 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 716 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 717 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 718
562b7ae5
SA
719 devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append(
720 devc->digital_groups[i < 8 ? 0 : 1]->channels, ch);
13f2b9d7
DJ
721 }
722
723 devc->model_config = &scope_models[model_index];
724 devc->frame_limit = 0;
725
726 if (!(devc->model_state = scope_state_new(devc->model_config)))
727 return SR_ERR_MALLOC;
728
729 return SR_OK;
730}
731
719eff68 732SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 733{
ba7dd8bb 734 struct sr_channel *ch;
13f2b9d7 735 struct sr_dev_inst *sdi;
06a3e78a 736 struct dev_context *devc;
13f2b9d7 737 struct sr_datafeed_packet packet;
89280b1a 738 GArray *data;
5faebab2 739 struct sr_datafeed_analog_old analog;
89280b1a 740 struct sr_datafeed_logic logic;
06a3e78a
DJ
741
742 (void)fd;
f0729866 743 (void)revents;
06a3e78a 744
f62f595b
MK
745 data = NULL;
746
06a3e78a
DJ
747 if (!(sdi = cb_data))
748 return TRUE;
749
750 if (!(devc = sdi->priv))
751 return TRUE;
752
f4f273ce
SB
753 /* Although this is correct in general, the USBTMC libusb implementation
754 * currently does not generate an event prior to the first read. Often
755 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
756 if (revents != G_IO_IN)
757 return TRUE;
f4f273ce 758 */
13f2b9d7 759
dc89faea 760 ch = devc->current_channel->data;
13f2b9d7 761
dc89faea
UH
762 switch (ch->type) {
763 case SR_CHANNEL_ANALOG:
764 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
765 if (data)
766 g_array_free(data, TRUE);
13f2b9d7 767
dc89faea 768 return TRUE;
13f2b9d7
DJ
769 }
770
dc89faea 771 packet.type = SR_DF_FRAME_BEGIN;
13f2b9d7
DJ
772 sr_session_send(sdi, &packet);
773
dc89faea
UH
774 analog.channels = g_slist_append(NULL, ch);
775 analog.num_samples = data->len;
776 analog.data = (float *) data->data;
777 analog.mq = SR_MQ_VOLTAGE;
778 analog.unit = SR_UNIT_VOLT;
779 analog.mqflags = 0;
5faebab2 780 packet.type = SR_DF_ANALOG_OLD;
dc89faea 781 packet.payload = &analog;
695dc859 782 sr_session_send(sdi, &packet);
dc89faea
UH
783 g_slist_free(analog.channels);
784 g_array_free(data, TRUE);
785 data = NULL;
786 break;
787 case SR_CHANNEL_LOGIC:
788 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
789 g_free(data);
790 return TRUE;
13f2b9d7 791 }
dc89faea
UH
792
793 packet.type = SR_DF_FRAME_BEGIN;
794 sr_session_send(sdi, &packet);
795
796 logic.length = data->len;
797 logic.unitsize = 1;
798 logic.data = data->data;
799 packet.type = SR_DF_LOGIC;
800 packet.payload = &logic;
695dc859 801 sr_session_send(sdi, &packet);
dc89faea
UH
802 g_array_free(data, TRUE);
803 data = NULL;
804 break;
805 default:
806 sr_err("Invalid channel type.");
807 break;
808 }
809
810 packet.type = SR_DF_FRAME_END;
811 sr_session_send(sdi, &packet);
812
813 if (devc->current_channel->next) {
814 devc->current_channel = devc->current_channel->next;
815 hmo_request_data(sdi);
816 } else if (++devc->num_frames == devc->frame_limit) {
695dc859 817 sdi->driver->dev_acquisition_stop(sdi);
dc89faea
UH
818 } else {
819 devc->current_channel = devc->enabled_channels;
820 hmo_request_data(sdi);
06a3e78a
DJ
821 }
822
823 return TRUE;
824}