]> sigrok.org Git - libsigrok.git/blame - src/hardware/yokogawa-dlm/protocol.c
yokogawa-dlm: Fix number of digital groups
[libsigrok.git] / src / hardware / yokogawa-dlm / protocol.c
CommitLineData
10763937
SA
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2014 abraxa (Soeren Apel) <soeren@apelpie.net>
5 * Based on the Hameg HMO driver by poljar (Damir Jelić) <poljarinho@gmail.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
8ab929d6
SA
21/** @file
22 * <em>Yokogawa DL/DLM series</em> oscilloscope driver
23 * @internal
24 */
25
10763937
SA
26#include "protocol.h"
27
f254bc4b 28static const uint32_t dlm_devopts[] = {
8ab929d6
SA
29 SR_CONF_LOGIC_ANALYZER,
30 SR_CONF_OSCILLOSCOPE,
5827f61b
BV
31 SR_CONF_LIMIT_FRAMES | SR_CONF_SET,
32 SR_CONF_SAMPLERATE | SR_CONF_GET,
33 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
34 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
35 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
bf622e6d 36 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 37 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
8ab929d6
SA
38};
39
f254bc4b 40static const uint32_t dlm_analog_devopts[] = {
5827f61b
BV
41 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
42 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
43 SR_CONF_NUM_VDIV | SR_CONF_GET,
8ab929d6
SA
44};
45
46static const char *dlm_coupling_options[] = {
47 "AC",
48 "DC",
49 "DC50",
50 "GND",
51 NULL,
52};
53
54/* Note: Values must correlate to the trigger_slopes values */
55static const char *dlm_trigger_slopes[] = {
56 "r",
57 "f",
58 NULL,
59};
60
61static const char *dlm_2ch_trigger_sources[] = {
62 "1",
63 "2",
64 "LINE",
65 "EXT",
66 NULL,
67};
68
69/* TODO: Is BITx handled correctly or is Dx required? */
70static const char *dlm_4ch_trigger_sources[] = {
71 "1",
72 "2",
73 "3",
74 "4",
75 "LINE",
76 "EXT",
77 "BIT1",
78 "BIT2",
79 "BIT3",
80 "BIT4",
81 "BIT5",
82 "BIT6",
83 "BIT7",
84 "BIT8",
85 NULL,
86};
87
88static const uint64_t dlm_timebases[][2] = {
89 /* nanoseconds */
90 { 1, 1000000000 },
91 { 2, 1000000000 },
92 { 5, 1000000000 },
93 { 10, 1000000000 },
94 { 20, 1000000000 },
95 { 50, 1000000000 },
96 { 100, 1000000000 },
97 { 200, 1000000000 },
98 { 500, 1000000000 },
99 /* microseconds */
100 { 1, 1000000 },
101 { 2, 1000000 },
102 { 5, 1000000 },
103 { 10, 1000000 },
104 { 20, 1000000 },
105 { 50, 1000000 },
106 { 100, 1000000 },
107 { 200, 1000000 },
108 { 500, 1000000 },
109 /* milliseconds */
110 { 1, 1000 },
111 { 2, 1000 },
112 { 5, 1000 },
113 { 10, 1000 },
114 { 20, 1000 },
115 { 50, 1000 },
116 { 100, 1000 },
117 { 200, 1000 },
118 { 500, 1000 },
119 /* seconds */
120 { 1, 1 },
121 { 2, 1 },
122 { 5, 1 },
123 { 10, 1 },
124 { 20, 1 },
125 { 50, 1 },
126 { 100, 1 },
127 { 200, 1 },
128 { 500, 1 },
129};
130
131static const uint64_t dlm_vdivs[][2] = {
132 /* millivolts */
133 { 2, 1000 },
134 { 5, 1000 },
135 { 10, 1000 },
136 { 20, 1000 },
137 { 50, 1000 },
138 { 100, 1000 },
139 { 200, 1000 },
140 { 500, 1000 },
141 /* volts */
142 { 1, 1 },
143 { 2, 1 },
144 { 5, 1 },
145 { 10, 1 },
146 { 20, 1 },
147 { 50, 1 },
148 { 100, 1 },
149 { 200, 1 },
150 { 500, 1 },
151};
152
153static const char *scope_analog_channel_names[] = {
154 "1",
155 "2",
156 "3",
157 "4"
158};
159
7048bb1f 160static const char *scope_digital_channel_names_8[] = {
8ab929d6
SA
161 "D0",
162 "D1",
163 "D2",
164 "D3",
165 "D4",
166 "D5",
167 "D6",
168 "D7"
169};
170
7048bb1f
SA
171static const char *scope_digital_channel_names_32[] = {
172 "A0",
173 "A1",
174 "A2",
175 "A3",
176 "A4",
177 "A5",
178 "A6",
179 "A7",
180 "B0",
181 "B1",
182 "B2",
183 "B3",
184 "B4",
185 "B5",
186 "B6",
187 "B7",
188 "C0",
189 "C1",
190 "C2",
191 "C3",
192 "C4",
193 "C5",
194 "C6",
195 "C7",
196 "D0",
197 "D1",
198 "D2",
199 "D3",
200 "D4",
201 "D5",
202 "D6",
203 "D7",
204};
205
329733d9 206static const struct scope_config scope_models[] = {
8ab929d6
SA
207 {
208 .model_id = {"710105", "710115", "710125", NULL},
209 .model_name = {"DLM2022", "DLM2032", "DLM2052", NULL},
210 .analog_channels = 2,
211 .digital_channels = 0,
212 .pods = 0,
213
214 .analog_names = &scope_analog_channel_names,
7048bb1f 215 .digital_names = &scope_digital_channel_names_8,
8ab929d6 216
f254bc4b
BV
217 .devopts = &dlm_devopts,
218 .num_devopts = ARRAY_SIZE(dlm_devopts),
8ab929d6 219
f254bc4b
BV
220 .analog_devopts = &dlm_analog_devopts,
221 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
8ab929d6
SA
222
223 .coupling_options = &dlm_coupling_options,
224 .trigger_sources = &dlm_2ch_trigger_sources,
225 .trigger_slopes = &dlm_trigger_slopes,
226
227 .timebases = &dlm_timebases,
228 .num_timebases = ARRAY_SIZE(dlm_timebases),
229
230 .vdivs = &dlm_vdivs,
231 .num_vdivs = ARRAY_SIZE(dlm_vdivs),
232
233 .num_xdivs = 10,
234 .num_ydivs = 8,
235 },
236 {
237 .model_id = {"710110", "710120", "710130", NULL},
238 .model_name = {"DLM2024", "DLM2034", "DLM2054", NULL},
239 .analog_channels = 4,
240 .digital_channels = 8,
241 .pods = 1,
242
243 .analog_names = &scope_analog_channel_names,
7048bb1f
SA
244 .digital_names = &scope_digital_channel_names_8,
245
246 .devopts = &dlm_devopts,
247 .num_devopts = ARRAY_SIZE(dlm_devopts),
248
249 .analog_devopts = &dlm_analog_devopts,
250 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
251
252 .coupling_options = &dlm_coupling_options,
253 .trigger_sources = &dlm_4ch_trigger_sources,
254 .trigger_slopes = &dlm_trigger_slopes,
255
256 .timebases = &dlm_timebases,
257 .num_timebases = ARRAY_SIZE(dlm_timebases),
258
259 .vdivs = &dlm_vdivs,
260 .num_vdivs = ARRAY_SIZE(dlm_vdivs),
261
262 .num_xdivs = 10,
263 .num_ydivs = 8,
264 },
265 {
266 .model_id = {"701307", "701308", "701310", "701311",
267 "701312", "701313", NULL},
268 .model_name = {"DL9040", "DL9040L", "DL9140", "DL9140L",
269 "DL9240", "DL9240L", NULL},
270 .analog_channels = 4,
271 .digital_channels = 0,
272 .pods = 0,
273
274 .analog_names = &scope_analog_channel_names,
275 .digital_names = NULL,
276
277 .devopts = &dlm_devopts,
278 .num_devopts = ARRAY_SIZE(dlm_devopts),
279
280 .analog_devopts = &dlm_analog_devopts,
281 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
282
283 .coupling_options = &dlm_coupling_options,
284 .trigger_sources = &dlm_4ch_trigger_sources,
285 .trigger_slopes = &dlm_trigger_slopes,
286
287 .timebases = &dlm_timebases,
288 .num_timebases = ARRAY_SIZE(dlm_timebases),
289
290 .vdivs = &dlm_vdivs,
291 .num_vdivs = ARRAY_SIZE(dlm_vdivs),
292
293 .num_xdivs = 10,
294 .num_ydivs = 8,
295 },
296 {
297 .model_id = {"701320", "701321", NULL},
298 .model_name = {"DL9505L", "DL9510L", NULL},
299 .analog_channels = 4,
300 .digital_channels = 16,
301 .pods = 4,
302
303 .analog_names = &scope_analog_channel_names,
304 .digital_names = &scope_digital_channel_names_32,
305
306 .devopts = &dlm_devopts,
307 .num_devopts = ARRAY_SIZE(dlm_devopts),
308
309 .analog_devopts = &dlm_analog_devopts,
310 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
311
312 .coupling_options = &dlm_coupling_options,
313 .trigger_sources = &dlm_4ch_trigger_sources,
314 .trigger_slopes = &dlm_trigger_slopes,
315
316 .timebases = &dlm_timebases,
317 .num_timebases = ARRAY_SIZE(dlm_timebases),
318
319 .vdivs = &dlm_vdivs,
320 .num_vdivs = ARRAY_SIZE(dlm_vdivs),
321
322 .num_xdivs = 10,
323 .num_ydivs = 8,
324 },
325 {
326 .model_id = {"701330", "701331", NULL},
327 .model_name = {"DL9705L", "DL9710L", NULL},
328 .analog_channels = 4,
329 .digital_channels = 32,
330 .pods = 4,
331
332 .analog_names = &scope_analog_channel_names,
333 .digital_names = &scope_digital_channel_names_32,
8ab929d6 334
f254bc4b
BV
335 .devopts = &dlm_devopts,
336 .num_devopts = ARRAY_SIZE(dlm_devopts),
8ab929d6 337
f254bc4b
BV
338 .analog_devopts = &dlm_analog_devopts,
339 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
8ab929d6
SA
340
341 .coupling_options = &dlm_coupling_options,
342 .trigger_sources = &dlm_4ch_trigger_sources,
343 .trigger_slopes = &dlm_trigger_slopes,
344
345 .timebases = &dlm_timebases,
346 .num_timebases = ARRAY_SIZE(dlm_timebases),
347
348 .vdivs = &dlm_vdivs,
349 .num_vdivs = ARRAY_SIZE(dlm_vdivs),
350
351 .num_xdivs = 10,
352 .num_ydivs = 8,
353 },
354};
355
356/**
357 * Prints out the state of the device as we currently know it.
358 *
359 * @param config This is the scope configuration.
360 * @param state The current scope state to print.
361 */
329733d9 362static void scope_state_dump(const struct scope_config *config,
8ab929d6
SA
363 struct scope_state *state)
364{
365 unsigned int i;
366 char *tmp;
367
368 for (i = 0; i < config->analog_channels; ++i) {
369 tmp = sr_voltage_string((*config->vdivs)[state->analog_states[i].vdiv][0],
ac10a927 370 (*config->vdivs)[state->analog_states[i].vdiv][1]);
8ab929d6 371 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
ac10a927
SA
372 i + 1, state->analog_states[i].state ? "On" : "Off",
373 (*config->coupling_options)[state->analog_states[i].coupling],
374 tmp, state->analog_states[i].vertical_offset);
8ab929d6
SA
375 }
376
377 for (i = 0; i < config->digital_channels; ++i) {
378 sr_info("State of digital channel %d -> %s", i,
ac10a927 379 state->digital_states[i] ? "On" : "Off");
8ab929d6
SA
380 }
381
382 for (i = 0; i < config->pods; ++i) {
383 sr_info("State of digital POD %d -> %s", i,
ac10a927 384 state->pod_states[i] ? "On" : "Off");
8ab929d6
SA
385 }
386
387 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
ac10a927 388 (*config->timebases)[state->timebase][1]);
8ab929d6
SA
389 sr_info("Current timebase: %s", tmp);
390 g_free(tmp);
391
392 tmp = sr_samplerate_string(state->sample_rate);
393 sr_info("Current samplerate: %s", tmp);
394 g_free(tmp);
395
af3487ec 396 sr_info("Current samples per acquisition (i.e. frame): %d",
ac10a927 397 state->samples_per_frame);
af3487ec 398
8ab929d6 399 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
ac10a927
SA
400 (*config->trigger_sources)[state->trigger_source],
401 (*config->trigger_slopes)[state->trigger_slope],
402 state->horiz_triggerpos);
8ab929d6
SA
403}
404
405/**
406 * Searches through an array of strings and returns the index to the
407 * array where a given string is located.
408 *
409 * @param value The string to search for.
410 * @param array The array of strings.
411 * @param result The index at which value is located in array. -1 on error.
412 *
413 * @return SR_ERR when value couldn't be found, SR_OK otherwise.
414 */
415static int array_option_get(char *value, const char *(*array)[],
416 int *result)
417{
418 unsigned int i;
419
420 *result = -1;
421
422 for (i = 0; (*array)[i]; ++i)
423 if (!g_strcmp0(value, (*array)[i])) {
424 *result = i;
425 break;
426 }
427
428 if (*result == -1)
429 return SR_ERR;
430
431 return SR_OK;
432}
433
434/**
435 * This function takes a value of the form "2.000E-03", converts it to a
436 * significand / factor pair and returns the index of an array where
437 * a matching pair was found.
438 *
439 * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
440 * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
441 * Therefore it's easier to break the number up into two strings and handle
442 * them separately.
443 *
444 * @param value The string to be parsed.
445 * @param array The array of s/f pairs.
446 * @param array_len The number of pairs in the array.
447 * @param result The index at which a matching pair was found.
448 *
449 * @return SR_ERR on any parsing error, SR_OK otherwise.
450 */
451static int array_float_get(gchar *value, const uint64_t array[][2],
452 int array_len, int *result)
453{
454 int i;
455 uint64_t f;
456 float s;
ac10a927 457 unsigned int s_int;
8ab929d6
SA
458 gchar ss[10], es[10];
459
460 memset(ss, 0, sizeof(ss));
461 memset(es, 0, sizeof(es));
462
463 strncpy(ss, value, 5);
464 strncpy(es, &(value[6]), 3);
465
466 if (sr_atof_ascii(ss, &s) != SR_OK)
467 return SR_ERR;
468 if (sr_atoi(es, &i) != SR_OK)
469 return SR_ERR;
470
471 /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
472 f = pow(10, abs(i));
473
474 /* Adjust the significand/factor pair to make sure
475 * that f is a multiple of 1000.
476 */
477 while ((int)fmod(log10(f), 3) > 0) { s *= 10; f *= 10; }
478
479 /* Truncate s to circumvent rounding errors. */
ac10a927 480 s_int = (unsigned int)s;
8ab929d6
SA
481
482 for (i = 0; i < array_len; i++) {
ac10a927 483 if ( (s_int == array[i][0]) && (f == array[i][1]) ) {
8ab929d6
SA
484 *result = i;
485 return SR_OK;
486 }
487 }
488
489 return SR_ERR;
490}
491
492/**
493 * Obtains information about all analog channels from the oscilloscope.
494 * The internal state information is updated accordingly.
495 *
496 * @param scpi An open SCPI connection.
497 * @param config The device's device configuration.
498 * @param state The device's state information.
499 *
500 * @return SR_ERR on error, SR_OK otherwise.
501 */
502static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 503 const struct scope_config *config,
ac10a927 504 struct scope_state *state)
8ab929d6
SA
505{
506 int i, j;
507 gchar *response;
508
509 for (i = 0; i < config->analog_channels; ++i) {
510
511 if (dlm_analog_chan_state_get(scpi, i + 1,
ac10a927 512 &state->analog_states[i].state) != SR_OK)
8ab929d6
SA
513 return SR_ERR;
514
515 if (dlm_analog_chan_vdiv_get(scpi, i + 1, &response) != SR_OK)
516 return SR_ERR;
517
518 if (array_float_get(response, *config->vdivs, config->num_vdivs,
ac10a927 519 &j) != SR_OK) {
8ab929d6
SA
520 g_free(response);
521 return SR_ERR;
522 }
523
524 g_free(response);
525 state->analog_states[i].vdiv = j;
526
527 if (dlm_analog_chan_voffs_get(scpi, i + 1,
ac10a927 528 &state->analog_states[i].vertical_offset) != SR_OK)
8ab929d6
SA
529 return SR_ERR;
530
531 if (dlm_analog_chan_wrange_get(scpi, i + 1,
ac10a927 532 &state->analog_states[i].waveform_range) != SR_OK)
8ab929d6
SA
533 return SR_ERR;
534
535 if (dlm_analog_chan_woffs_get(scpi, i + 1,
ac10a927 536 &state->analog_states[i].waveform_offset) != SR_OK)
8ab929d6
SA
537 return SR_ERR;
538
539 if (dlm_analog_chan_coupl_get(scpi, i + 1, &response) != SR_OK) {
540 g_free(response);
541 return SR_ERR;
542 }
543
544 if (array_option_get(response, config->coupling_options,
ac10a927 545 &state->analog_states[i].coupling) != SR_OK) {
8ab929d6
SA
546 g_free(response);
547 return SR_ERR;
548 }
549 g_free(response);
550 }
551
552 return SR_OK;
553}
554
555/**
556 * Obtains information about all digital channels from the oscilloscope.
557 * The internal state information is updated accordingly.
558 *
559 * @param scpi An open SCPI connection.
560 * @param config The device's device configuration.
561 * @param state The device's state information.
562 *
563 * @return SR_ERR on error, SR_OK otherwise.
564 */
565static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
329733d9 566 const struct scope_config *config,
ac10a927 567 struct scope_state *state)
8ab929d6
SA
568{
569 unsigned int i;
570
571 if (!config->digital_channels)
572 {
573 sr_warn("Tried obtaining digital channel states on a " \
ac10a927 574 "model without digital inputs.");
8ab929d6
SA
575 return SR_OK;
576 }
577
578 for (i = 0; i < config->digital_channels; ++i) {
579 if (dlm_digital_chan_state_get(scpi, i + 1,
580 &state->digital_states[i]) != SR_OK) {
581 return SR_ERR;
582 }
583 }
584
585 if (!config->pods)
586 {
587 sr_warn("Tried obtaining pod states on a model without pods.");
588 return SR_OK;
589 }
590
591 for (i = 0; i < config->pods; ++i) {
592 if (dlm_digital_pod_state_get(scpi, i + 'A',
593 &state->pod_states[i]) != SR_OK)
594 return SR_ERR;
595 }
596
597 return SR_OK;
598}
599
600/**
601 * Obtains information about the sample rate from the oscilloscope.
602 * The internal state information is updated accordingly.
603 *
604 * @param sdi The device instance.
605 *
606 * @return SR_ERR on error, SR_OK otherwise.
607 */
608SR_PRIV int dlm_sample_rate_query(const struct sr_dev_inst *sdi)
609{
610 struct dev_context *devc;
611 struct scope_state *state;
612 float tmp_float;
613
614 devc = sdi->priv;
615 state = devc->model_state;
616
617 /* No need to find an active channel to query the sample rate:
618 * querying any channel will do, so we use channel 1 all the time.
619 */
620 if (dlm_analog_chan_srate_get(sdi->conn, 1, &tmp_float) != SR_OK)
621 return SR_ERR;
622
623 state->sample_rate = tmp_float;
624
625 return SR_OK;
626}
627
628/**
629 * Obtains information about the current device state from the oscilloscope,
630 * including all analog and digital channel configurations.
631 * The internal state information is updated accordingly.
632 *
633 * @param sdi The device instance.
634 *
635 * @return SR_ERR on error, SR_OK otherwise.
636 */
637SR_PRIV int dlm_scope_state_query(struct sr_dev_inst *sdi)
638{
639 struct dev_context *devc;
640 struct scope_state *state;
329733d9 641 const struct scope_config *config;
8ab929d6
SA
642 float tmp_float;
643 gchar *response;
644 int i;
645
646 devc = sdi->priv;
647 config = devc->model_config;
648 state = devc->model_state;
649
650 if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
651 return SR_ERR;
652
653 if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
654 return SR_ERR;
655
656 if (dlm_timebase_get(sdi->conn, &response) != SR_OK)
657 return SR_ERR;
658
659 if (array_float_get(response, *config->timebases,
ac10a927 660 config->num_timebases, &i) != SR_OK) {
8ab929d6
SA
661 g_free(response);
662 return SR_ERR;
663 }
664
665 g_free(response);
666 state->timebase = i;
667
668 if (dlm_horiz_trigger_pos_get(sdi->conn, &tmp_float) != SR_OK)
669 return SR_ERR;
670
671 /* TODO: Check if the calculation makes sense for the DLM. */
672 state->horiz_triggerpos = tmp_float /
ac10a927
SA
673 (((double)(*config->timebases)[state->timebase][0] /
674 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
8ab929d6
SA
675 state->horiz_triggerpos -= 0.5;
676 state->horiz_triggerpos *= -1;
677
678 if (dlm_trigger_source_get(sdi->conn, &response) != SR_OK) {
679 g_free(response);
680 return SR_ERR;
681 }
682
683 if (array_option_get(response, config->trigger_sources,
ac10a927 684 &state->trigger_source) != SR_OK) {
8ab929d6
SA
685 g_free(response);
686 return SR_ERR;
687 }
688
689 g_free(response);
690
691 if (dlm_trigger_slope_get(sdi->conn, &i) != SR_OK)
692 return SR_ERR;
693
694 state->trigger_slope = i;
695
af3487ec
SA
696 if (dlm_acq_length_get(sdi->conn, &state->samples_per_frame) != SR_OK) {
697 sr_err("Failed to query acquisition length.");
698 return SR_ERR;
699 }
700
8ab929d6
SA
701 dlm_sample_rate_query(sdi);
702
703 scope_state_dump(config, state);
704
705 return SR_OK;
706}
707
708/**
709 * Creates a new device state structure.
710 *
711 * @param config The device configuration to use.
712 *
ac10a927 713 * @return The newly allocated scope_state struct.
8ab929d6 714 */
329733d9 715static struct scope_state *dlm_scope_state_new(const struct scope_config *config)
8ab929d6
SA
716{
717 struct scope_state *state;
718
ac10a927 719 state = g_malloc0(sizeof(struct scope_state));
8ab929d6
SA
720
721 state->analog_states = g_malloc0(config->analog_channels *
ac10a927 722 sizeof(struct analog_channel_state));
8ab929d6
SA
723
724 state->digital_states = g_malloc0(config->digital_channels *
ac10a927 725 sizeof(gboolean));
8ab929d6
SA
726
727 state->pod_states = g_malloc0(config->pods * sizeof(gboolean));
728
729 return state;
730}
731
732/**
733 * Frees the memory that was allocated by a call to dlm_scope_state_new().
734 *
735 * @param state The device state structure whose memory is to be freed.
736 */
737SR_PRIV void dlm_scope_state_destroy(struct scope_state *state)
738{
739 g_free(state->analog_states);
740 g_free(state->digital_states);
741 g_free(state->pod_states);
742 g_free(state);
743}
744
745SR_PRIV int dlm_model_get(char *model_id, char **model_name, int *model_index)
746{
747 unsigned int i, j;
748
749 *model_index = -1;
750 *model_name = NULL;
751
752 for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
753 for (j = 0; scope_models[i].model_id[j]; j++) {
754 if (!strcmp(model_id, scope_models[i].model_id[j])) {
755 *model_index = i;
756 *model_name = (char *)scope_models[i].model_name[j];
757 break;
758 }
759 }
760 if (*model_index != -1)
761 break;
762 }
763
764 if (*model_index == -1) {
765 sr_err("Found unsupported DLM device with model identifier %s.",
ac10a927 766 model_id);
8ab929d6
SA
767 return SR_ERR_NA;
768 }
769
770 return SR_OK;
771}
772
773/**
774 * Attempts to initialize a DL/DLM device and prepares internal structures
775 * if a suitable device was found.
776 *
777 * @param sdi The device instance.
778 */
779SR_PRIV int dlm_device_init(struct sr_dev_inst *sdi, int model_index)
780{
781 char tmp[25];
782 int i;
783 struct sr_channel *ch;
784 struct dev_context *devc;
785
786 devc = sdi->priv;
787
788 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
ac10a927 789 scope_models[model_index].analog_channels);
8ab929d6
SA
790
791 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
f77afcf0 792 scope_models[model_index].pods);
8ab929d6 793
6fd78a9f 794 /* Add analog channels, each in its own group. */
8ab929d6 795 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 796 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 797 (*scope_models[model_index].analog_names)[i]);
8ab929d6
SA
798
799 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
800
801 devc->analog_groups[i]->name = g_strdup(
ac10a927 802 (char *)(*scope_models[model_index].analog_names)[i]);
8ab929d6
SA
803 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
804
805 sdi->channel_groups = g_slist_append(sdi->channel_groups,
ac10a927 806 devc->analog_groups[i]);
8ab929d6
SA
807 }
808
809 /* Add digital channel groups. */
810 for (i = 0; i < scope_models[model_index].pods; ++i) {
811 g_snprintf(tmp, sizeof(tmp), "POD%d", i);
812
813 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
814 if (!devc->digital_groups[i])
815 return SR_ERR_MALLOC;
816
817 devc->digital_groups[i]->name = g_strdup(tmp);
818 sdi->channel_groups = g_slist_append(sdi->channel_groups,
819 devc->digital_groups[i]);
820 }
821
822 /* Add digital channels. */
823 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
6fd78a9f
SA
824 ch = sr_channel_new(sdi, DLM_DIG_CHAN_INDEX_OFFS + i,
825 SR_CHANNEL_LOGIC, TRUE,
c368e6f3 826 (*scope_models[model_index].digital_names)[i]);
8ab929d6
SA
827
828 devc->digital_groups[i / 8]->channels = g_slist_append(
ac10a927 829 devc->digital_groups[i / 8]->channels, ch);
8ab929d6
SA
830 }
831 devc->model_config = &scope_models[model_index];
832 devc->frame_limit = 0;
833
834 if (!(devc->model_state = dlm_scope_state_new(devc->model_config)))
835 return SR_ERR_MALLOC;
836
837 /* Disable non-standard response behavior. */
838 if (dlm_response_headers_set(sdi->conn, FALSE) != SR_OK)
839 return SR_ERR;
840
841 return SR_OK;
842}
843
af3487ec 844SR_PRIV int dlm_channel_data_request(const struct sr_dev_inst *sdi)
8ab929d6 845{
af3487ec
SA
846 struct dev_context *devc;
847 struct sr_channel *ch;
848 int result;
8ab929d6 849
af3487ec
SA
850 devc = sdi->priv;
851 ch = devc->current_channel->data;
8ab929d6 852
af3487ec
SA
853 switch (ch->type) {
854 case SR_CHANNEL_ANALOG:
855 result = dlm_analog_data_get(sdi->conn, ch->index + 1);
856 break;
857 case SR_CHANNEL_LOGIC:
858 result = dlm_digital_data_get(sdi->conn);
859 break;
860 default:
861 sr_err("Invalid channel type encountered (%d).",
862 ch->type);
863 result = SR_ERR;
8ab929d6
SA
864 }
865
af3487ec
SA
866 if (result == SR_OK)
867 devc->data_pending = TRUE;
868 else
869 devc->data_pending = FALSE;
870
871 return result;
8ab929d6
SA
872}
873
874/**
875 * Reads and removes the block data header from a given data input.
876 * Format is #ndddd... with n being the number of decimal digits d.
877 * The string dddd... contains the decimal-encoded length of the data.
878 * Example: #9000000013 would yield a length of 13 bytes.
879 *
880 * @param data The input data.
881 * @param len The determined input data length.
882 */
883static int dlm_block_data_header_process(GArray *data, int *len)
884{
885 int i, n;
886 gchar s[20];
887
888 if (g_array_index(data, gchar, 0) != '#')
889 return SR_ERR;
890
891 n = (uint8_t)(g_array_index(data, gchar, 1) - '0');
892
893 for (i = 0; i < n; i++)
894 s[i] = g_array_index(data, gchar, 2 + i);
895 s[i] = 0;
896
897 if (sr_atoi(s, len) != SR_OK)
898 return SR_ERR;
899
900 g_array_remove_range(data, 0, 2 + n);
901
902 return SR_OK;
903}
904
905/**
906 * Turns raw sample data into voltages and sends them off to the session bus.
907 *
908 * @param data The raw sample data.
8ab929d6
SA
909 * @ch_state Pointer to the state of the channel whose data we're processing.
910 * @sdi The device instance.
911 *
912 * @return SR_ERR when data is trucated, SR_OK otherwise.
913 */
af3487ec 914static int dlm_analog_samples_send(GArray *data,
ac10a927
SA
915 struct analog_channel_state *ch_state,
916 struct sr_dev_inst *sdi)
8ab929d6 917{
af3487ec 918 uint32_t i, samples;
8ab929d6
SA
919 float voltage, range, offset;
920 GArray *float_data;
921 struct dev_context *devc;
af3487ec 922 struct scope_state *model_state;
8ab929d6
SA
923 struct sr_channel *ch;
924 struct sr_datafeed_analog analog;
925 struct sr_datafeed_packet packet;
926
af3487ec
SA
927 devc = sdi->priv;
928 model_state = devc->model_state;
929 samples = model_state->samples_per_frame;
930 ch = devc->current_channel->data;
931
8ab929d6
SA
932 if (data->len < samples * sizeof(uint8_t)) {
933 sr_err("Truncated waveform data packet received.");
934 return SR_ERR;
935 }
936
8ab929d6
SA
937 range = ch_state->waveform_range;
938 offset = ch_state->waveform_offset;
939
940 /* Convert byte sample to voltage according to
941 * page 269 of the Communication Interface User's Manual.
942 */
943 float_data = g_array_new(FALSE, FALSE, sizeof(float));
944 for (i = 0; i < samples; i++) {
945 voltage = (float)g_array_index(data, int8_t, i);
946 voltage = (range * voltage /
ac10a927 947 DLM_DIVISION_FOR_BYTE_FORMAT) + offset;
8ab929d6
SA
948 g_array_append_val(float_data, voltage);
949 }
950
951 analog.channels = g_slist_append(NULL, ch);
952 analog.num_samples = float_data->len;
953 analog.data = (float*)float_data->data;
954 analog.mq = SR_MQ_VOLTAGE;
955 analog.unit = SR_UNIT_VOLT;
956 analog.mqflags = 0;
957 packet.type = SR_DF_ANALOG;
958 packet.payload = &analog;
959 sr_session_send(sdi, &packet);
960 g_slist_free(analog.channels);
961
962 g_array_free(float_data, TRUE);
963 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
964
965 return SR_OK;
966}
967
968/**
969 * Sends logic sample data off to the session bus.
970 *
971 * @param data The raw sample data.
8ab929d6
SA
972 * @ch_state Pointer to the state of the channel whose data we're processing.
973 * @sdi The device instance.
974 *
975 * @return SR_ERR when data is trucated, SR_OK otherwise.
976 */
af3487ec 977static int dlm_digital_samples_send(GArray *data,
ac10a927 978 struct sr_dev_inst *sdi)
8ab929d6 979{
af3487ec
SA
980 struct dev_context *devc;
981 struct scope_state *model_state;
982 uint32_t samples;
8ab929d6
SA
983 struct sr_datafeed_logic logic;
984 struct sr_datafeed_packet packet;
985
af3487ec
SA
986 devc = sdi->priv;
987 model_state = devc->model_state;
988 samples = model_state->samples_per_frame;
989
8ab929d6
SA
990 if (data->len < samples * sizeof(uint8_t)) {
991 sr_err("Truncated waveform data packet received.");
992 return SR_ERR;
993 }
994
995 logic.length = samples;
996 logic.unitsize = 1;
997 logic.data = data->data;
998 packet.type = SR_DF_LOGIC;
999 packet.payload = &logic;
1000 sr_session_send(sdi, &packet);
1001
1002 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
1003
1004 return SR_OK;
1005}
1006
1007/**
1008 * Attempts to query sample data from the oscilloscope in order to send it
1009 * to the session bus for further processing.
1010 *
1011 * @param fd The file descriptor used as the event source.
1012 * @param revents The received events.
1013 * @param cb_data Callback data, in this case our device instance.
1014 *
1015 * @return TRUE in case of success or a recoverable error,
1016 * FALSE when a fatal error was encountered.
1017 */
1018SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
1019{
8ab929d6
SA
1020 struct sr_dev_inst *sdi;
1021 struct scope_state *model_state;
1022 struct dev_context *devc;
af3487ec 1023 struct sr_channel *ch;
8ab929d6 1024 struct sr_datafeed_packet packet;
af3487ec
SA
1025 int chunk_len, num_bytes;
1026 static GArray *data = NULL;
8ab929d6
SA
1027
1028 (void)fd;
1029 (void)revents;
1030
1031 if (!(sdi = cb_data))
1032 return FALSE;
1033
1034 if (!(devc = sdi->priv))
1035 return FALSE;
1036
1037 if (!(model_state = (struct scope_state*)devc->model_state))
1038 return FALSE;
1039
af3487ec
SA
1040 /* Are we waiting for a response from the device? */
1041 if (!devc->data_pending)
8ab929d6 1042 return TRUE;
af3487ec
SA
1043
1044 /* Check if a new query response is coming our way. */
1045 if (!data) {
1046 if (sr_scpi_read_begin(sdi->conn) == SR_OK)
1047 /* The 16 here accounts for the header and EOL. */
1048 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
ac10a927 1049 16 + model_state->samples_per_frame);
af3487ec
SA
1050 else
1051 return TRUE;
8ab929d6
SA
1052 }
1053
af3487ec
SA
1054 /* Store incoming data. */
1055 chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
ac10a927 1056 RECEIVE_BUFFER_SIZE);
af3487ec
SA
1057 if (chunk_len < 0) {
1058 sr_err("Error while reading data: %d", chunk_len);
1059 goto fail;
1060 }
1061 g_array_append_vals(data, devc->receive_buffer, chunk_len);
8ab929d6 1062
af3487ec
SA
1063 /* Read the entire query response before processing. */
1064 if (!sr_scpi_read_complete(sdi->conn))
1065 return TRUE;
8ab929d6 1066
af3487ec
SA
1067 /* We finished reading and are no longer waiting for data. */
1068 devc->data_pending = FALSE;
8ab929d6 1069
af3487ec
SA
1070 /* Signal the beginning of a new frame if this is the first channel. */
1071 if (devc->current_channel == devc->enabled_channels) {
1072 packet.type = SR_DF_FRAME_BEGIN;
1073 sr_session_send(sdi, &packet);
1074 }
8ab929d6 1075
af3487ec
SA
1076 if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
1077 sr_err("Encountered malformed block data header.");
1078 goto fail;
1079 }
8ab929d6 1080
af3487ec
SA
1081 if (num_bytes == 0) {
1082 sr_warn("Zero-length waveform data packet received. " \
ac10a927
SA
1083 "Live mode not supported yet, stopping " \
1084 "acquisition and retrying.");
af3487ec
SA
1085 /* Don't care about return value here. */
1086 dlm_acquisition_stop(sdi->conn);
1087 g_array_free(data, TRUE);
0028d5a1 1088 dlm_channel_data_request(sdi);
af3487ec
SA
1089 return TRUE;
1090 }
8ab929d6 1091
af3487ec
SA
1092 ch = devc->current_channel->data;
1093 switch (ch->type) {
1094 case SR_CHANNEL_ANALOG:
1095 if (dlm_analog_samples_send(data,
1096 &model_state->analog_states[ch->index],
1097 sdi) != SR_OK)
8ab929d6 1098 goto fail;
af3487ec
SA
1099 break;
1100 case SR_CHANNEL_LOGIC:
1101 if (dlm_digital_samples_send(data, sdi) != SR_OK)
1102 goto fail;
1103 break;
1104 default:
1105 sr_err("Invalid channel type encountered.");
1106 break;
1107 }
8ab929d6 1108
af3487ec
SA
1109 g_array_free(data, TRUE);
1110 data = NULL;
8ab929d6 1111
af3487ec
SA
1112 /* Signal the end of this frame if this was the last enabled channel
1113 * and set the next enabled channel. Then, request its data.
1114 */
1115 if (!devc->current_channel->next) {
1116 packet.type = SR_DF_FRAME_END;
1117 sr_session_send(sdi, &packet);
1118 devc->current_channel = devc->enabled_channels;
1119
1120 /* As of now we only support importing the current acquisition
1121 * data so we're going to stop at this point.
1122 */
1123 sdi->driver->dev_acquisition_stop(sdi, cb_data);
1124 return TRUE;
1125 } else
1126 devc->current_channel = devc->current_channel->next;
8ab929d6 1127
af3487ec 1128 if (dlm_channel_data_request(sdi) != SR_OK) {
f3f19d11 1129 sr_err("Failed to request acquisition data.");
af3487ec 1130 goto fail;
8ab929d6
SA
1131 }
1132
8ab929d6
SA
1133 return TRUE;
1134
1135fail:
af3487ec 1136 if (data) {
8ab929d6 1137 g_array_free(data, TRUE);
af3487ec
SA
1138 data = NULL;
1139 }
8ab929d6 1140
af3487ec 1141 return FALSE;
8ab929d6 1142}