]> sigrok.org Git - libsigrok.git/blame - src/hardware/hameg-hmo/protocol.c
drivers: Consistently use the name trigger_matches[] everywhere.
[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
4b25cbff 60static const uint32_t devopts[] = {
13f2b9d7 61 SR_CONF_OSCILLOSCOPE,
a1b61e6e 62 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
86621306 63 SR_CONF_SAMPLERATE | SR_CONF_GET,
5827f61b 64 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 65 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 66 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
86621306
UH
67 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
68 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
69};
70
6b82c3e5 71static const uint32_t devopts_cg_analog[] = {
5827f61b 72 SR_CONF_NUM_VDIV | SR_CONF_GET,
5827f61b 73 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
86621306 74 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
13f2b9d7
DJ
75};
76
4b25cbff 77static const char *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
4b25cbff 93static const char *compact2_trigger_sources[] = {
13f2b9d7
DJ
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
4b25cbff 112static const char *compact4_trigger_sources[] = {
13f2b9d7
DJ
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
4b25cbff 133static const char *compact4_dig16_trigger_sources[] = {
74413faf
GS
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
4b25cbff 162static const uint64_t timebases[][2] = {
13f2b9d7
DJ
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
4b25cbff 201static const uint64_t vdivs[][2] = {
13f2b9d7
DJ
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
4b25cbff
UH
259 .devopts = &devopts,
260 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 261
6b82c3e5
UH
262 .devopts_cg_analog = &devopts_cg_analog,
263 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 264
4b25cbff
UH
265 .coupling_options = &coupling_options,
266 .trigger_sources = &compact2_trigger_sources,
13f2b9d7
DJ
267 .trigger_slopes = &scope_trigger_slopes,
268
4b25cbff
UH
269 .timebases = &timebases,
270 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 271
4b25cbff
UH
272 .vdivs = &vdivs,
273 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
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
4b25cbff
UH
289 .devopts = &devopts,
290 .num_devopts = ARRAY_SIZE(devopts),
13f2b9d7 291
6b82c3e5
UH
292 .devopts_cg_analog = &devopts_cg_analog,
293 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
13f2b9d7 294
4b25cbff
UH
295 .coupling_options = &coupling_options,
296 .trigger_sources = &compact4_trigger_sources,
13f2b9d7
DJ
297 .trigger_slopes = &scope_trigger_slopes,
298
4b25cbff
UH
299 .timebases = &timebases,
300 .num_timebases = ARRAY_SIZE(timebases),
13f2b9d7 301
4b25cbff
UH
302 .vdivs = &vdivs,
303 .num_vdivs = ARRAY_SIZE(vdivs),
13f2b9d7
DJ
304
305 .num_xdivs = 12,
306 .num_ydivs = 8,
307
74413faf
GS
308 .scpi_dialect = &hameg_scpi_dialect,
309 },
310 {
bf8a02b6 311 .name = {"HMO2524", "HMO3034", "HMO3044", "HMO3054", "HMO3524", NULL},
74413faf
GS
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
4b25cbff
UH
319 .devopts = &devopts,
320 .num_devopts = ARRAY_SIZE(devopts),
74413faf 321
6b82c3e5
UH
322 .devopts_cg_analog = &devopts_cg_analog,
323 .num_devopts_cg_analog = ARRAY_SIZE(devopts_cg_analog),
74413faf 324
4b25cbff
UH
325 .coupling_options = &coupling_options,
326 .trigger_sources = &compact4_dig16_trigger_sources,
74413faf
GS
327 .trigger_slopes = &scope_trigger_slopes,
328
4b25cbff
UH
329 .timebases = &timebases,
330 .num_timebases = ARRAY_SIZE(timebases),
74413faf 331
4b25cbff
UH
332 .vdivs = &vdivs,
333 .num_vdivs = ARRAY_SIZE(vdivs),
74413faf
GS
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
6984cfb2
SA
367 tmp = sr_period_string((*config->timebases)[state->timebase][0],
368 (*config->timebases)[state->timebase][1]);
8de2dc3b
DJ
369 sr_info("Current timebase: %s", tmp);
370 g_free(tmp);
371
14a2f74d
DJ
372 tmp = sr_samplerate_string(state->sample_rate);
373 sr_info("Current samplerate: %s", tmp);
374 g_free(tmp);
375
422a1c0d 376 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
13f2b9d7
DJ
377 (*config->trigger_sources)[state->trigger_source],
378 (*config->trigger_slopes)[state->trigger_slope],
379 state->horiz_triggerpos);
380}
381
23f43dff 382static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
89280b1a 383 const char *command, const char *(*array)[], int *result)
13f2b9d7
DJ
384{
385 char *tmp;
386 unsigned int i;
387
23f43dff 388 if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
89280b1a 389 g_free(tmp);
13f2b9d7
DJ
390 return SR_ERR;
391 }
392
0a1f7b09 393 for (i = 0; (*array)[i]; i++) {
13f2b9d7
DJ
394 if (!g_strcmp0(tmp, (*array)[i])) {
395 *result = i;
396 g_free(tmp);
397 tmp = NULL;
398 break;
399 }
400 }
401
402 if (tmp) {
403 g_free(tmp);
404 return SR_ERR;
405 }
406
407 return SR_OK;
408}
409
8fff7519 410/**
a53acd7d
SB
411 * This function takes a value of the form "2.000E-03" and returns the index
412 * of an array where a matching pair was found.
8fff7519
SA
413 *
414 * @param value The string to be parsed.
415 * @param array The array of s/f pairs.
416 * @param array_len The number of pairs in the array.
417 * @param result The index at which a matching pair was found.
418 *
419 * @return SR_ERR on any parsing error, SR_OK otherwise.
420 */
421static int array_float_get(gchar *value, const uint64_t array[][2],
650847e7 422 int array_len, unsigned int *result)
8fff7519 423{
a53acd7d
SB
424 struct sr_rational rval;
425 struct sr_rational aval;
8cccbac8 426
a53acd7d 427 if (sr_parse_rational(value, &rval) != SR_OK)
8fff7519
SA
428 return SR_ERR;
429
a53acd7d
SB
430 for (int i = 0; i < array_len; i++) {
431 sr_rational_set(&aval, array[i][0], array[i][1]);
432 if (sr_rational_eq(&rval, &aval)) {
8fff7519
SA
433 *result = i;
434 return SR_OK;
435 }
436 }
437
438 return SR_ERR;
439}
440
23f43dff 441static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 442 const struct scope_config *config,
13f2b9d7
DJ
443 struct scope_state *state)
444{
8de2dc3b 445 unsigned int i, j;
13f2b9d7 446 char command[MAX_COMMAND_SIZE];
8fff7519 447 char *tmp_str;
13f2b9d7 448
0a1f7b09 449 for (i = 0; i < config->analog_channels; i++) {
13f2b9d7
DJ
450 g_snprintf(command, sizeof(command),
451 (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
452 i + 1);
453
23f43dff 454 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
455 &state->analog_channels[i].state) != SR_OK)
456 return SR_ERR;
457
458 g_snprintf(command, sizeof(command),
459 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
460 i + 1);
461
8fff7519 462 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
8de2dc3b 463 return SR_ERR;
8fff7519 464
53012da6 465 if (array_float_get(tmp_str, ARRAY_AND_SIZE(vdivs), &j) != SR_OK) {
8fff7519 466 g_free(tmp_str);
b4e31d2a 467 sr_err("Could not determine array index for vertical div scale.");
13f2b9d7 468 return SR_ERR;
b4e31d2a 469 }
13f2b9d7 470
8fff7519
SA
471 g_free(tmp_str);
472 state->analog_channels[i].vdiv = j;
473
13f2b9d7
DJ
474 g_snprintf(command, sizeof(command),
475 (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
476 i + 1);
477
23f43dff 478 if (sr_scpi_get_float(scpi, command,
13f2b9d7
DJ
479 &state->analog_channels[i].vertical_offset) != SR_OK)
480 return SR_ERR;
481
482 g_snprintf(command, sizeof(command),
483 (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
484 i + 1);
485
23f43dff 486 if (scope_state_get_array_option(scpi, command, config->coupling_options,
13f2b9d7
DJ
487 &state->analog_channels[i].coupling) != SR_OK)
488 return SR_ERR;
448e81b1
SB
489
490 g_snprintf(command, sizeof(command),
491 (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
492 i + 1);
493
494 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
495 return SR_ERR;
496
497 if (tmp_str[0] == 'A')
498 state->analog_channels[i].probe_unit = 'A';
499 else
500 state->analog_channels[i].probe_unit = 'V';
501 g_free(tmp_str);
13f2b9d7
DJ
502 }
503
504 return SR_OK;
505}
506
23f43dff 507static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 508 const struct scope_config *config,
13f2b9d7
DJ
509 struct scope_state *state)
510{
511 unsigned int i;
512 char command[MAX_COMMAND_SIZE];
513
0a1f7b09 514 for (i = 0; i < config->digital_channels; i++) {
13f2b9d7
DJ
515 g_snprintf(command, sizeof(command),
516 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
517 i);
518
23f43dff 519 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
520 &state->digital_channels[i]) != SR_OK)
521 return SR_ERR;
522 }
523
0a1f7b09 524 for (i = 0; i < config->digital_pods; i++) {
13f2b9d7
DJ
525 g_snprintf(command, sizeof(command),
526 (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
527 i + 1);
528
23f43dff 529 if (sr_scpi_get_bool(scpi, command,
13f2b9d7
DJ
530 &state->digital_pods[i]) != SR_OK)
531 return SR_ERR;
532 }
533
534 return SR_OK;
535}
536
14a2f74d
DJ
537SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
538{
539 struct dev_context *devc;
540 struct scope_state *state;
329733d9 541 const struct scope_config *config;
14a2f74d
DJ
542
543 int tmp;
544 unsigned int i;
545 float tmp_float;
546 gboolean channel_found;
547 char tmp_str[MAX_COMMAND_SIZE];
548 char chan_name[20];
549
550 devc = sdi->priv;
551 config = devc->model_config;
552 state = devc->model_state;
553 channel_found = FALSE;
554
0a1f7b09 555 for (i = 0; i < config->analog_channels; i++) {
14a2f74d
DJ
556 if (state->analog_channels[i].state) {
557 g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
558 g_snprintf(tmp_str, sizeof(tmp_str),
559 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
560 chan_name);
561 channel_found = TRUE;
562 break;
563 }
564 }
565
566 if (!channel_found) {
567 for (i = 0; i < config->digital_pods; i++) {
568 if (state->digital_pods[i]) {
569 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
570 g_snprintf(tmp_str, sizeof(tmp_str),
571 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
572 chan_name);
573 channel_found = TRUE;
574 break;
575 }
576 }
577 }
578
579 /* No channel is active, ask the instrument for the sample rate
580 * in single shot mode */
581 if (!channel_found) {
c06c24d2
DJ
582 if (sr_scpi_get_float(sdi->conn,
583 (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
584 &tmp_float) != SR_OK)
14a2f74d 585 return SR_ERR;
c06c24d2 586
14a2f74d
DJ
587 state->sample_rate = tmp_float;
588 } else {
589 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
590 return SR_ERR;
591 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
592 (*config->timebases)[state->timebase][1]) *
593 config->num_xdivs);
594 }
595
596 return SR_OK;
597}
598
719eff68 599SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
13f2b9d7
DJ
600{
601 struct dev_context *devc;
602 struct scope_state *state;
329733d9 603 const struct scope_config *config;
8de2dc3b
DJ
604 float tmp_float;
605 unsigned int i;
8cccbac8 606 char *tmp_str;
13f2b9d7
DJ
607
608 devc = sdi->priv;
609 config = devc->model_config;
610 state = devc->model_state;
611
8de2dc3b
DJ
612 sr_info("Fetching scope state");
613
13f2b9d7
DJ
614 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
615 return SR_ERR;
616
617 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
618 return SR_ERR;
619
89280b1a
UH
620 if (sr_scpi_get_float(sdi->conn,
621 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
8de2dc3b
DJ
622 &tmp_float) != SR_OK)
623 return SR_ERR;
624
8cccbac8
SA
625 if (sr_scpi_get_string(sdi->conn,
626 (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
627 &tmp_str) != SR_OK)
628 return SR_ERR;
629
53012da6 630 if (array_float_get(tmp_str, ARRAY_AND_SIZE(timebases), &i) != SR_OK) {
8cccbac8 631 g_free(tmp_str);
b4e31d2a 632 sr_err("Could not determine array index for time base.");
13f2b9d7 633 return SR_ERR;
b4e31d2a 634 }
e5b7eef7 635 g_free(tmp_str);
13f2b9d7 636
8cccbac8
SA
637 state->timebase = i;
638
89280b1a
UH
639 if (sr_scpi_get_float(sdi->conn,
640 (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
422a1c0d 641 &tmp_float) != SR_OK)
13f2b9d7 642 return SR_ERR;
422a1c0d
DJ
643 state->horiz_triggerpos = tmp_float /
644 (((double) (*config->timebases)[state->timebase][0] /
645 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
646 state->horiz_triggerpos -= 0.5;
647 state->horiz_triggerpos *= -1;
13f2b9d7 648
89280b1a
UH
649 if (scope_state_get_array_option(sdi->conn,
650 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
651 config->trigger_sources, &state->trigger_source) != SR_OK)
13f2b9d7
DJ
652 return SR_ERR;
653
89280b1a
UH
654 if (scope_state_get_array_option(sdi->conn,
655 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
656 config->trigger_slopes, &state->trigger_slope) != SR_OK)
13f2b9d7
DJ
657 return SR_ERR;
658
14a2f74d
DJ
659 if (hmo_update_sample_rate(sdi) != SR_OK)
660 return SR_ERR;
661
8de2dc3b
DJ
662 sr_info("Fetching finished.");
663
13f2b9d7
DJ
664 scope_state_dump(config, state);
665
666 return SR_OK;
667}
668
329733d9 669static struct scope_state *scope_state_new(const struct scope_config *config)
13f2b9d7
DJ
670{
671 struct scope_state *state;
672
a95f142e
UH
673 state = g_malloc0(sizeof(struct scope_state));
674 state->analog_channels = g_malloc0_n(config->analog_channels,
675 sizeof(struct analog_channel_state));
676 state->digital_channels = g_malloc0_n(
677 config->digital_channels, sizeof(gboolean));
678 state->digital_pods = g_malloc0_n(config->digital_pods,
679 sizeof(gboolean));
13f2b9d7
DJ
680
681 return state;
13f2b9d7
DJ
682}
683
719eff68 684SR_PRIV void hmo_scope_state_free(struct scope_state *state)
13f2b9d7
DJ
685{
686 g_free(state->analog_channels);
687 g_free(state->digital_channels);
688 g_free(state->digital_pods);
689 g_free(state);
690}
691
692SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
693{
694 char tmp[25];
695 int model_index;
2d224dba 696 unsigned int i, j, group;
ba7dd8bb 697 struct sr_channel *ch;
13f2b9d7
DJ
698 struct dev_context *devc;
699
700 devc = sdi->priv;
701 model_index = -1;
702
89280b1a 703 /* Find the exact model. */
13f2b9d7
DJ
704 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
705 for (j = 0; scope_models[i].name[j]; j++) {
706 if (!strcmp(sdi->model, scope_models[i].name[j])) {
707 model_index = i;
708 break;
709 }
710 }
711 if (model_index != -1)
712 break;
713 }
714
715 if (model_index == -1) {
89280b1a 716 sr_dbg("Unsupported HMO device.");
13f2b9d7
DJ
717 return SR_ERR_NA;
718 }
719
562b7ae5
SA
720 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
721 scope_models[model_index].analog_channels);
13f2b9d7 722
562b7ae5
SA
723 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
724 scope_models[model_index].digital_pods);
13f2b9d7 725
89280b1a 726 /* Add analog channels. */
13f2b9d7 727 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 728 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 729 (*scope_models[model_index].analog_names)[i]);
13f2b9d7 730
562b7ae5
SA
731 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
732
733 devc->analog_groups[i]->name = g_strdup(
734 (char *)(*scope_models[model_index].analog_names)[i]);
735 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
13f2b9d7 736
660e398f 737 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 738 devc->analog_groups[i]);
13f2b9d7
DJ
739 }
740
660e398f 741 /* Add digital channel groups. */
0a1f7b09 742 for (i = 0; i < scope_models[model_index].digital_pods; i++) {
13f2b9d7 743 g_snprintf(tmp, 25, "POD%d", i);
562b7ae5
SA
744
745 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
746
747 devc->digital_groups[i]->name = g_strdup(tmp);
660e398f 748 sdi->channel_groups = g_slist_append(sdi->channel_groups,
2d224dba 749 devc->digital_groups[i]);
13f2b9d7
DJ
750 }
751
89280b1a 752 /* Add digital channels. */
13f2b9d7 753 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
5e23fcab 754 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 755 (*scope_models[model_index].digital_names)[i]);
13f2b9d7 756
2d224dba
GS
757 group = i / 8;
758 devc->digital_groups[group]->channels = g_slist_append(
759 devc->digital_groups[group]->channels, ch);
13f2b9d7
DJ
760 }
761
762 devc->model_config = &scope_models[model_index];
763 devc->frame_limit = 0;
764
765 if (!(devc->model_state = scope_state_new(devc->model_config)))
766 return SR_ERR_MALLOC;
767
768 return SR_OK;
769}
770
e06875b2
GS
771/* Queue data of one channel group, for later submission. */
772SR_PRIV void hmo_queue_logic_data(struct dev_context *devc,
773 size_t group, GByteArray *pod_data)
774{
775 size_t size;
776 GByteArray *store;
777 uint8_t *logic_data;
778 size_t idx, logic_step;
779
780 /*
781 * Upon first invocation, allocate the array which can hold the
782 * combined logic data for all channels. Assume that each channel
783 * will yield an identical number of samples per receive call.
784 *
785 * As a poor man's safety measure: (Silently) skip processing
786 * for unexpected sample counts, and ignore samples for
787 * unexpected channel groups. Don't bother with complicated
788 * resize logic, considering that many models only support one
789 * pod, and the most capable supported models have two pods of
790 * identical size. We haven't yet seen any "odd" configuration.
791 */
792 if (!devc->logic_data) {
793 size = pod_data->len * devc->pod_count;
794 store = g_byte_array_sized_new(size);
795 memset(store->data, 0, size);
796 store = g_byte_array_set_size(store, size);
797 devc->logic_data = store;
798 } else {
799 store = devc->logic_data;
800 size = store->len / devc->pod_count;
801 if (size != pod_data->len)
802 return;
803 if (group >= devc->pod_count)
804 return;
805 }
806
807 /*
808 * Fold the data of the most recently received channel group into
809 * the storage, where data resides for all channels combined.
810 */
811 logic_data = store->data;
812 logic_data += group;
813 logic_step = devc->pod_count;
814 for (idx = 0; idx < pod_data->len; idx++) {
815 *logic_data = pod_data->data[idx];
816 logic_data += logic_step;
817 }
818}
819
820/* Submit data for all channels, after the individual groups got collected. */
821SR_PRIV void hmo_send_logic_packet(struct sr_dev_inst *sdi,
822 struct dev_context *devc)
823{
824 struct sr_datafeed_packet packet;
825 struct sr_datafeed_logic logic;
826
827 if (!devc->logic_data)
828 return;
829
830 logic.data = devc->logic_data->data;
831 logic.length = devc->logic_data->len;
832 logic.unitsize = devc->pod_count;
833
834 packet.type = SR_DF_LOGIC;
835 packet.payload = &logic;
836
837 sr_session_send(sdi, &packet);
838}
839
840/* Undo previous resource allocation. */
841SR_PRIV void hmo_cleanup_logic_data(struct dev_context *devc)
842{
843
844 if (devc->logic_data) {
845 g_byte_array_free(devc->logic_data, TRUE);
846 devc->logic_data = NULL;
847 }
848 /*
849 * Keep 'pod_count'! It's required when more frames will be
850 * received, and does not harm when kept after acquisition.
851 */
852}
853
719eff68 854SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
06a3e78a 855{
ba7dd8bb 856 struct sr_channel *ch;
13f2b9d7 857 struct sr_dev_inst *sdi;
06a3e78a 858 struct dev_context *devc;
401b83a1 859 struct scope_state *state;
13f2b9d7 860 struct sr_datafeed_packet packet;
401b83a1
SB
861 GByteArray *data;
862 struct sr_datafeed_analog analog;
863 struct sr_analog_encoding encoding;
864 struct sr_analog_meaning meaning;
865 struct sr_analog_spec spec;
89280b1a 866 struct sr_datafeed_logic logic;
e06875b2 867 size_t group;
06a3e78a
DJ
868
869 (void)fd;
f0729866 870 (void)revents;
06a3e78a 871
f62f595b
MK
872 data = NULL;
873
06a3e78a
DJ
874 if (!(sdi = cb_data))
875 return TRUE;
876
877 if (!(devc = sdi->priv))
878 return TRUE;
879
f4f273ce
SB
880 /* Although this is correct in general, the USBTMC libusb implementation
881 * currently does not generate an event prior to the first read. Often
882 * it is ok to start reading just after the 50ms timeout. See bug #785.
dc89faea
UH
883 if (revents != G_IO_IN)
884 return TRUE;
f4f273ce 885 */
13f2b9d7 886
dc89faea 887 ch = devc->current_channel->data;
401b83a1 888 state = devc->model_state;
13f2b9d7 889
b23eb1d4
GS
890 /*
891 * Send "frame begin" packet upon reception of data for the
892 * first enabled channel.
893 */
894 if (devc->current_channel == devc->enabled_channels) {
895 packet.type = SR_DF_FRAME_BEGIN;
896 sr_session_send(sdi, &packet);
897 }
898
899 /*
900 * Pass on the received data of the channel(s).
901 */
dc89faea
UH
902 switch (ch->type) {
903 case SR_CHANNEL_ANALOG:
401b83a1 904 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea 905 if (data)
401b83a1 906 g_byte_array_free(data, TRUE);
13f2b9d7 907
dc89faea 908 return TRUE;
13f2b9d7
DJ
909 }
910
401b83a1
SB
911 packet.type = SR_DF_ANALOG;
912
913 analog.data = data->data;
914 analog.num_samples = data->len / sizeof(float);
915 analog.encoding = &encoding;
916 analog.meaning = &meaning;
917 analog.spec = &spec;
918
919 encoding.unitsize = sizeof(float);
920 encoding.is_signed = TRUE;
921 encoding.is_float = TRUE;
65a6794e
GS
922#ifdef WORDS_BIGENDIAN
923 encoding.is_bigendian = TRUE;
924#else
d1ad8b10 925 encoding.is_bigendian = FALSE;
65a6794e 926#endif
7dcaddd3
UH
927 /* TODO: Use proper 'digits' value for this device (and its modes). */
928 encoding.digits = 2;
401b83a1
SB
929 encoding.is_digits_decimal = FALSE;
930 encoding.scale.p = 1;
931 encoding.scale.q = 1;
932 encoding.offset.p = 0;
933 encoding.offset.q = 1;
934 if (state->analog_channels[ch->index].probe_unit == 'V') {
935 meaning.mq = SR_MQ_VOLTAGE;
936 meaning.unit = SR_UNIT_VOLT;
937 } else {
938 meaning.mq = SR_MQ_CURRENT;
939 meaning.unit = SR_UNIT_AMPERE;
940 }
941 meaning.mqflags = 0;
942 meaning.channels = g_slist_append(NULL, ch);
7dcaddd3
UH
943 /* TODO: Use proper 'digits' value for this device (and its modes). */
944 spec.spec_digits = 2;
dc89faea 945 packet.payload = &analog;
695dc859 946 sr_session_send(sdi, &packet);
401b83a1
SB
947 g_slist_free(meaning.channels);
948 g_byte_array_free(data, TRUE);
dc89faea
UH
949 data = NULL;
950 break;
951 case SR_CHANNEL_LOGIC:
401b83a1 952 if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) {
dc89faea
UH
953 g_free(data);
954 return TRUE;
13f2b9d7 955 }
dc89faea 956
e06875b2
GS
957 /*
958 * If only data from the first pod is involved in the
959 * acquisition, then the raw input bytes can get passed
960 * forward for performance reasons. When the second pod
961 * is involved (either alone, or in combination with the
962 * first pod), then the received bytes need to be put
963 * into memory in such a layout that all channel groups
964 * get combined, and a unitsize larger than a single byte
965 * applies. The "queue" logic transparently copes with
966 * any such configuration. This works around the lack
967 * of support for "meaning" to logic data, which is used
968 * above for analog data.
969 */
970 if (devc->pod_count == 1) {
971 packet.type = SR_DF_LOGIC;
972 logic.data = data->data;
973 logic.length = data->len;
974 logic.unitsize = 1;
975 packet.payload = &logic;
976 sr_session_send(sdi, &packet);
977 } else {
978 group = ch->index / 8;
979 hmo_queue_logic_data(devc, group, data);
980 }
dc89faea 981
401b83a1 982 g_byte_array_free(data, TRUE);
dc89faea
UH
983 data = NULL;
984 break;
985 default:
986 sr_err("Invalid channel type.");
987 break;
988 }
989
b23eb1d4
GS
990 /*
991 * Advance to the next enabled channel. When data for all enabled
e06875b2
GS
992 * channels was received, then flush potentially queued logic data,
993 * and send the "frame end" packet.
b23eb1d4 994 */
dc89faea
UH
995 if (devc->current_channel->next) {
996 devc->current_channel = devc->current_channel->next;
997 hmo_request_data(sdi);
b23eb1d4
GS
998 return TRUE;
999 }
e06875b2
GS
1000 hmo_send_logic_packet(sdi, devc);
1001
1002 /*
1003 * Release the logic data storage after each frame. This copes
1004 * with sample counts that differ in length per frame. -- Is
1005 * this a real constraint when acquiring multiple frames with
1006 * identical device settings?
1007 */
1008 hmo_cleanup_logic_data(devc);
1009
b23eb1d4
GS
1010 packet.type = SR_DF_FRAME_END;
1011 sr_session_send(sdi, &packet);
1012
1013 /*
1014 * End of frame was reached. Stop acquisition after the specified
1015 * number of frames, or continue reception by starting over at
1016 * the first enabled channel.
1017 */
1018 if (++devc->num_frames == devc->frame_limit) {
d2f7c417 1019 sr_dev_acquisition_stop(sdi);
e06875b2 1020 hmo_cleanup_logic_data(devc);
dc89faea
UH
1021 } else {
1022 devc->current_channel = devc->enabled_channels;
1023 hmo_request_data(sdi);
06a3e78a
DJ
1024 }
1025
1026 return TRUE;
1027}