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