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