]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Support BE format for SCPI sample downloads
[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?",
d431e4ec 51 [SCPI_CMD_GET_BYTE_ORDER] = ":FORM:BORD?",
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
d431e4ec
GS
499 /*
500 * Determine the byte order which will be used for data blocks.
501 * A ":FORM:BORD?" request will yield either an "MSBF" or "LSBF"
502 * response.
503 */
504 state->byteorder = '?';
505 if (sr_scpi_get_string(scpi,
506 (*config->scpi_dialect)[SCPI_CMD_GET_BYTE_ORDER],
507 &tmp_str) != SR_OK)
508 return SR_ERR;
509 if (tmp_str[0] == 'M')
510 state->byteorder = 'b';
511 else if (tmp_str[0] == 'L')
512 state->byteorder = 'l';
513 g_free(tmp_str);
514
13f2b9d7
DJ
515 return SR_OK;
516}
517
23f43dff 518static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 519 const struct scope_config *config,
13f2b9d7
DJ
520 struct scope_state *state)
521{
522 unsigned int i;
523 char command[MAX_COMMAND_SIZE];
524
0a1f7b09 525 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
526 g_snprintf(command, sizeof(command),
527 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
528 i);
529
23f43dff 530 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
531 &state->digital_channels[i]) != SR_OK)
532 return SR_ERR;
533 }
534
0a1f7b09 535 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
536 g_snprintf(command, sizeof(command),
537 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
538 i + 1);
539
23f43dff 540 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
541 &state->digital_pods[i]) != SR_OK)
542 return SR_ERR;
543 }
544
545 return SR_OK;
546}
547
14a2f74d
DJ
548SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
549{
550 struct dev_context *devc;
551 struct scope_state *state;
329733d9 552 const struct scope_config *config;
14a2f74d
DJ
553
554 int tmp;
555 unsigned int i;
556 float tmp_float;
557 gboolean channel_found;
558 char tmp_str[MAX_COMMAND_SIZE];
559 char chan_name[20];
560
561 devc = sdi->priv;
562 config = devc->model_config;
563 state = devc->model_state;
564 channel_found = FALSE;
565
0a1f7b09 566 for (i = 0; i < config->analog_channels; i++) {
14a2f74d
DJ
567 if (state->analog_channels[i].state) {
568 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
569 g_snprintf(tmp_str, sizeof(tmp_str),
570 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
571 chan_name);
572 channel_found = TRUE;
573 break;
574 }
575 }
576
577 if (!channel_found) {
578 for (i = 0; i < config->digital_pods; i++) {
579 if (state->digital_pods[i]) {
580 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
581 g_snprintf(tmp_str, sizeof(tmp_str),
582 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
583 chan_name);
584 channel_found = TRUE;
585 break;
586 }
587 }
588 }
589
590 /* No channel is active, ask the instrument for the sample rate
591 * in single shot mode */
592 if (!channel_found) {
c06c24d2
DJ
593 if (sr_scpi_get_float(sdi->conn,
594 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
595 &tmp_float) != SR_OK)
14a2f74d 596 return SR_ERR;
c06c24d2 597
14a2f74d
DJ
598 state->sample_rate = tmp_float;
599 } else {
600 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
601 return SR_ERR;
602 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
603 (*config->timebases)[state->timebase][1]) *
604 config->num_xdivs);
605 }
606
607 return SR_OK;
608}
609
719eff68 610SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
611{
612 struct dev_context *devc;
613 struct scope_state *state;
329733d9 614 const struct scope_config *config;
8de2dc3b
DJ
615 float tmp_float;
616 unsigned int i;
8cccbac8 617 char *tmp_str;
13f2b9d7
DJ
618
619 devc = sdi->priv;
620 config = devc->model_config;
621 state = devc->model_state;
622
8de2dc3b
DJ
623 sr_info("Fetching scope state");
624
13f2b9d7
DJ
625 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
626 return SR_ERR;
627
628 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
629 return SR_ERR;
630
89280b1a
UH
631 if (sr_scpi_get_float(sdi->conn,
632 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
633 &tmp_float) != SR_OK)
634 return SR_ERR;
635
8cccbac8
SA
636 if (sr_scpi_get_string(sdi->conn,
637 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
638 &tmp_str) != SR_OK)
639 return SR_ERR;
640
641 if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
642 &i) != SR_OK) {
643 g_free(tmp_str);
b4e31d2a 644 sr_err("Could not determine array index for time base.");
13f2b9d7 645 return SR_ERR;
b4e31d2a 646 }
e5b7eef7 647 g_free(tmp_str);
13f2b9d7 648
8cccbac8
SA
649 state->timebase = i;
650
89280b1a
UH
651 if (sr_scpi_get_float(sdi->conn,
652 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 653 &tmp_float) != SR_OK)
13f2b9d7 654 return SR_ERR;
422a1c0d
DJ
655 state->horiz_triggerpos = tmp_float /
656 (((double) (*config->timebases)[state->timebase][0] /
657 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
658 state->horiz_triggerpos -= 0.5;
659 state->horiz_triggerpos *= -1;
13f2b9d7 660
89280b1a
UH
661 if (scope_state_get_array_option(sdi->conn,
662 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
663 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
664 return SR_ERR;
665
89280b1a
UH
666 if (scope_state_get_array_option(sdi->conn,
667 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
668 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
669 return SR_ERR;
670
14a2f74d
DJ
671 if (hmo_update_sample_rate(sdi) != SR_OK)
672 return SR_ERR;
673
8de2dc3b
DJ
674 sr_info("Fetching finished.");
675
13f2b9d7
DJ
676 scope_state_dump(config, state);
677
678 return SR_OK;
679}
680
329733d9 681static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
682{
683 struct scope_state *state;
684
a95f142e
UH
685 state = g_malloc0(sizeof(struct scope_state));
686 state->analog_channels = g_malloc0_n(config->analog_channels,
687 sizeof(struct analog_channel_state));
688 state->digital_channels = g_malloc0_n(
689 config->digital_channels, sizeof(gboolean));
690 state->digital_pods = g_malloc0_n(config->digital_pods,
691 sizeof(gboolean));
13f2b9d7
DJ
692
693 return state;
13f2b9d7
DJ
694}
695
719eff68 696SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
697{
698 g_free(state->analog_channels);
699 g_free(state->digital_channels);
700 g_free(state->digital_pods);
701 g_free(state);
702}
703
704SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
705{
706 char tmp[25];
707 int model_index;
2d224dba 708 unsigned int i, j, group;
ba7dd8bb 709 struct sr_channel *ch;
13f2b9d7
DJ
710 struct dev_context *devc;
711
712 devc = sdi->priv;
713 model_index = -1;
714
89280b1a 715 /* Find the exact model. */
13f2b9d7
DJ
716 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
717 for (j = 0; scope_models[i].name[j]; j++) {
718 if (!strcmp(sdi->model, scope_models[i].name[j])) {
719 model_index = i;
720 break;
721 }
722 }
723 if (model_index != -1)
724 break;
725 }
726
727 if (model_index == -1) {
89280b1a 728 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
729 return SR_ERR_NA;
730 }
731
562b7ae5
SA
732 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
733 scope_models[model_index].analog_channels);
13f2b9d7 734
562b7ae5
SA
735 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
736 scope_models[model_index].digital_pods);
13f2b9d7 737
89280b1a 738 /* Add analog channels. */
13f2b9d7 739 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 740 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 741 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 742
562b7ae5
SA
743 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
744
745 devc->analog_groups[i]->name = g_strdup(
746 (char *)(*scope_models[model_index].analog_names)[i]);
747 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 748
660e398f 749 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 750 devc->analog_groups[i]);
13f2b9d7
DJ
751 }
752
660e398f 753 /* Add digital channel groups. */
0a1f7b09 754 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
13f2b9d7 755 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
756
757 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
758
759 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 760 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 761 devc->digital_groups[i]);
13f2b9d7
DJ
762 }
763
89280b1a 764 /* Add digital channels. */
13f2b9d7 765 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 766 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 767 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 768
2d224dba
GS
769 group = i / 8;
770 devc->digital_groups[group]->channels = g_slist_append(
771 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
772 }
773
774 devc->model_config = &scope_models[model_index];
775 devc->frame_limit = 0;
776
777 if (!(devc->model_state = scope_state_new(devc->model_config)))
778 return SR_ERR_MALLOC;
779
780 return SR_OK;
781}
782
719eff68 783SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 784{
ba7dd8bb 785 struct sr_channel *ch;
13f2b9d7 786 struct sr_dev_inst *sdi;
06a3e78a 787 struct dev_context *devc;
401b83a1 788 struct scope_state *state;
13f2b9d7 789 struct sr_datafeed_packet packet;
401b83a1
SB
790 GByteArray *data;
791 struct sr_datafeed_analog analog;
792 struct sr_analog_encoding encoding;
793 struct sr_analog_meaning meaning;
794 struct sr_analog_spec spec;
89280b1a 795 struct sr_datafeed_logic logic;
06a3e78a
DJ
796
797 (void)fd;
f0729866 798 (void)revents;
06a3e78a 799
f62f595b
MK
800 data = NULL;
801
06a3e78a
DJ
802 if (!(sdi = cb_data))
803 return TRUE;
804
805 if (!(devc = sdi->priv))
806 return TRUE;
807
f4f273ce
SB
808 /* Although this is correct in general, the USBTMC libusb implementation
809 * currently does not generate an event prior to the first read. Often
810 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
811 if (revents != G_IO_IN)
812 return TRUE;
f4f273ce 813 */
13f2b9d7 814
dc89faea 815 ch = devc->current_channel->data;
401b83a1 816 state = devc->model_state;
13f2b9d7 817
dc89faea
UH
818 switch (ch->type) {
819 case SR_CHANNEL_ANALOG:
401b83a1 820 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 821 if (data)
401b83a1 822 g_byte_array_free(data, TRUE);
13f2b9d7 823
dc89faea 824 return TRUE;
13f2b9d7
DJ
825 }
826
dc89faea 827 packet.type = SR_DF_FRAME_BEGIN;
13f2b9d7
DJ
828 sr_session_send(sdi, &packet);
829
401b83a1
SB
830 packet.type = SR_DF_ANALOG;
831
832 analog.data = data->data;
833 analog.num_samples = data->len / sizeof(float);
834 analog.encoding = &encoding;
835 analog.meaning = &meaning;
836 analog.spec = &spec;
837
838 encoding.unitsize = sizeof(float);
839 encoding.is_signed = TRUE;
840 encoding.is_float = TRUE;
d431e4ec
GS
841 /* Assume LE format when unknown for backwards compat. */
842 encoding.is_bigendian = (state->byteorder == 'b') ? TRUE : FALSE;
7dcaddd3
UH
843 /* TODO: Use proper 'digits' value for this device (and its modes). */
844 encoding.digits = 2;
401b83a1
SB
845 encoding.is_digits_decimal = FALSE;
846 encoding.scale.p = 1;
847 encoding.scale.q = 1;
848 encoding.offset.p = 0;
849 encoding.offset.q = 1;
850 if (state->analog_channels[ch->index].probe_unit == 'V') {
851 meaning.mq = SR_MQ_VOLTAGE;
852 meaning.unit = SR_UNIT_VOLT;
853 } else {
854 meaning.mq = SR_MQ_CURRENT;
855 meaning.unit = SR_UNIT_AMPERE;
856 }
857 meaning.mqflags = 0;
858 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
859 /* TODO: Use proper 'digits' value for this device (and its modes). */
860 spec.spec_digits = 2;
dc89faea 861 packet.payload = &analog;
695dc859 862 sr_session_send(sdi, &packet);
401b83a1
SB
863 g_slist_free(meaning.channels);
864 g_byte_array_free(data, TRUE);
dc89faea
UH
865 data = NULL;
866 break;
867 case SR_CHANNEL_LOGIC:
401b83a1 868 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea
UH
869 g_free(data);
870 return TRUE;
13f2b9d7 871 }
dc89faea
UH
872
873 packet.type = SR_DF_FRAME_BEGIN;
874 sr_session_send(sdi, &packet);
875
876 logic.length = data->len;
877 logic.unitsize = 1;
878 logic.data = data->data;
879 packet.type = SR_DF_LOGIC;
880 packet.payload = &logic;
695dc859 881 sr_session_send(sdi, &packet);
401b83a1 882 g_byte_array_free(data, TRUE);
dc89faea
UH
883 data = NULL;
884 break;
885 default:
886 sr_err("Invalid channel type.");
887 break;
888 }
889
890 packet.type = SR_DF_FRAME_END;
891 sr_session_send(sdi, &packet);
892
893 if (devc->current_channel->next) {
894 devc->current_channel = devc->current_channel->next;
895 hmo_request_data(sdi);
896 } else if (++devc->num_frames == devc->frame_limit) {
695dc859 897 sdi->driver->dev_acquisition_stop(sdi);
dc89faea
UH
898 } else {
899 devc->current_channel = devc->enabled_channels;
900 hmo_request_data(sdi);
06a3e78a
DJ
901 }
902
903 return TRUE;
904}