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