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