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