]> sigrok.org Git - libsigrok.git/blame - src/hardware/yokogawa-dlm/protocol.c
yokogawa-dlm: Introduce config_channel_set()
[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
8ab929d6
SA
28static const char *dlm_coupling_options[] = {
29 "AC",
30 "DC",
31 "DC50",
32 "GND",
33 NULL,
34};
35
8ab929d6
SA
36static const char *dlm_2ch_trigger_sources[] = {
37 "1",
38 "2",
39 "LINE",
40 "EXT",
41 NULL,
42};
43
44/* TODO: Is BITx handled correctly or is Dx required? */
45static const char *dlm_4ch_trigger_sources[] = {
46 "1",
47 "2",
48 "3",
49 "4",
50 "LINE",
51 "EXT",
52 "BIT1",
53 "BIT2",
54 "BIT3",
55 "BIT4",
56 "BIT5",
57 "BIT6",
58 "BIT7",
59 "BIT8",
60 NULL,
61};
62
f3c60fb6
SA
63/* Note: Values must correlate to the trigger_slopes values */
64const char *dlm_trigger_slopes[3] = {
65 "r",
66 "f",
67 NULL,
68};
69
70const uint64_t dlm_timebases[36][2] = {
8ab929d6
SA
71 /* nanoseconds */
72 { 1, 1000000000 },
73 { 2, 1000000000 },
74 { 5, 1000000000 },
75 { 10, 1000000000 },
76 { 20, 1000000000 },
77 { 50, 1000000000 },
78 { 100, 1000000000 },
79 { 200, 1000000000 },
80 { 500, 1000000000 },
81 /* microseconds */
82 { 1, 1000000 },
83 { 2, 1000000 },
84 { 5, 1000000 },
85 { 10, 1000000 },
86 { 20, 1000000 },
87 { 50, 1000000 },
88 { 100, 1000000 },
89 { 200, 1000000 },
90 { 500, 1000000 },
91 /* milliseconds */
92 { 1, 1000 },
93 { 2, 1000 },
94 { 5, 1000 },
95 { 10, 1000 },
96 { 20, 1000 },
97 { 50, 1000 },
98 { 100, 1000 },
99 { 200, 1000 },
100 { 500, 1000 },
101 /* seconds */
102 { 1, 1 },
103 { 2, 1 },
104 { 5, 1 },
105 { 10, 1 },
106 { 20, 1 },
107 { 50, 1 },
108 { 100, 1 },
109 { 200, 1 },
110 { 500, 1 },
111};
112
f3c60fb6 113const uint64_t dlm_vdivs[17][2] = {
8ab929d6
SA
114 /* millivolts */
115 { 2, 1000 },
116 { 5, 1000 },
117 { 10, 1000 },
118 { 20, 1000 },
119 { 50, 1000 },
120 { 100, 1000 },
121 { 200, 1000 },
122 { 500, 1000 },
123 /* volts */
124 { 1, 1 },
125 { 2, 1 },
126 { 5, 1 },
127 { 10, 1 },
128 { 20, 1 },
129 { 50, 1 },
130 { 100, 1 },
131 { 200, 1 },
132 { 500, 1 },
133};
134
135static const char *scope_analog_channel_names[] = {
136 "1",
137 "2",
138 "3",
139 "4"
140};
141
7048bb1f 142static const char *scope_digital_channel_names_8[] = {
8ab929d6
SA
143 "D0",
144 "D1",
145 "D2",
146 "D3",
147 "D4",
148 "D5",
149 "D6",
150 "D7"
151};
152
7048bb1f
SA
153static const char *scope_digital_channel_names_32[] = {
154 "A0",
155 "A1",
156 "A2",
157 "A3",
158 "A4",
159 "A5",
160 "A6",
161 "A7",
162 "B0",
163 "B1",
164 "B2",
165 "B3",
166 "B4",
167 "B5",
168 "B6",
169 "B7",
170 "C0",
171 "C1",
172 "C2",
173 "C3",
174 "C4",
175 "C5",
176 "C6",
177 "C7",
178 "D0",
179 "D1",
180 "D2",
181 "D3",
182 "D4",
183 "D5",
184 "D6",
185 "D7",
186};
187
329733d9 188static const struct scope_config scope_models[] = {
8ab929d6
SA
189 {
190 .model_id = {"710105", "710115", "710125", NULL},
191 .model_name = {"DLM2022", "DLM2032", "DLM2052", NULL},
192 .analog_channels = 2,
193 .digital_channels = 0,
194 .pods = 0,
195
196 .analog_names = &scope_analog_channel_names,
7048bb1f 197 .digital_names = &scope_digital_channel_names_8,
8ab929d6 198
8ab929d6
SA
199 .coupling_options = &dlm_coupling_options,
200 .trigger_sources = &dlm_2ch_trigger_sources,
8ab929d6
SA
201
202 .num_xdivs = 10,
203 .num_ydivs = 8,
204 },
205 {
206 .model_id = {"710110", "710120", "710130", NULL},
207 .model_name = {"DLM2024", "DLM2034", "DLM2054", NULL},
208 .analog_channels = 4,
209 .digital_channels = 8,
210 .pods = 1,
211
212 .analog_names = &scope_analog_channel_names,
7048bb1f
SA
213 .digital_names = &scope_digital_channel_names_8,
214
7048bb1f
SA
215 .coupling_options = &dlm_coupling_options,
216 .trigger_sources = &dlm_4ch_trigger_sources,
7048bb1f
SA
217
218 .num_xdivs = 10,
219 .num_ydivs = 8,
220 },
221 {
222 .model_id = {"701307", "701308", "701310", "701311",
223 "701312", "701313", NULL},
224 .model_name = {"DL9040", "DL9040L", "DL9140", "DL9140L",
225 "DL9240", "DL9240L", NULL},
226 .analog_channels = 4,
227 .digital_channels = 0,
228 .pods = 0,
229
230 .analog_names = &scope_analog_channel_names,
231 .digital_names = NULL,
232
7048bb1f
SA
233 .coupling_options = &dlm_coupling_options,
234 .trigger_sources = &dlm_4ch_trigger_sources,
7048bb1f
SA
235
236 .num_xdivs = 10,
237 .num_ydivs = 8,
238 },
239 {
240 .model_id = {"701320", "701321", NULL},
241 .model_name = {"DL9505L", "DL9510L", NULL},
242 .analog_channels = 4,
243 .digital_channels = 16,
244 .pods = 4,
245
246 .analog_names = &scope_analog_channel_names,
247 .digital_names = &scope_digital_channel_names_32,
248
7048bb1f
SA
249 .coupling_options = &dlm_coupling_options,
250 .trigger_sources = &dlm_4ch_trigger_sources,
7048bb1f
SA
251
252 .num_xdivs = 10,
253 .num_ydivs = 8,
254 },
255 {
256 .model_id = {"701330", "701331", NULL},
257 .model_name = {"DL9705L", "DL9710L", NULL},
258 .analog_channels = 4,
259 .digital_channels = 32,
260 .pods = 4,
261
262 .analog_names = &scope_analog_channel_names,
263 .digital_names = &scope_digital_channel_names_32,
8ab929d6 264
8ab929d6
SA
265 .coupling_options = &dlm_coupling_options,
266 .trigger_sources = &dlm_4ch_trigger_sources,
8ab929d6
SA
267
268 .num_xdivs = 10,
269 .num_ydivs = 8,
270 },
271};
272
273/**
274 * Prints out the state of the device as we currently know it.
275 *
276 * @param config This is the scope configuration.
277 * @param state The current scope state to print.
278 */
329733d9 279static void scope_state_dump(const struct scope_config *config,
8ab929d6
SA
280 struct scope_state *state)
281{
282 unsigned int i;
283 char *tmp;
284
285 for (i = 0; i < config->analog_channels; ++i) {
f3c60fb6
SA
286 tmp = sr_voltage_string(dlm_vdivs[state->analog_states[i].vdiv][0],
287 dlm_vdivs[state->analog_states[i].vdiv][1]);
8ab929d6 288 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
ac10a927
SA
289 i + 1, state->analog_states[i].state ? "On" : "Off",
290 (*config->coupling_options)[state->analog_states[i].coupling],
291 tmp, state->analog_states[i].vertical_offset);
8ab929d6
SA
292 }
293
294 for (i = 0; i < config->digital_channels; ++i) {
295 sr_info("State of digital channel %d -> %s", i,
ac10a927 296 state->digital_states[i] ? "On" : "Off");
8ab929d6
SA
297 }
298
299 for (i = 0; i < config->pods; ++i) {
300 sr_info("State of digital POD %d -> %s", i,
ac10a927 301 state->pod_states[i] ? "On" : "Off");
8ab929d6
SA
302 }
303
f3c60fb6
SA
304 tmp = sr_period_string(dlm_timebases[state->timebase][0] *
305 dlm_timebases[state->timebase][1]);
8ab929d6
SA
306 sr_info("Current timebase: %s", tmp);
307 g_free(tmp);
308
309 tmp = sr_samplerate_string(state->sample_rate);
310 sr_info("Current samplerate: %s", tmp);
311 g_free(tmp);
312
af3487ec 313 sr_info("Current samples per acquisition (i.e. frame): %d",
ac10a927 314 state->samples_per_frame);
af3487ec 315
8ab929d6 316 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
ac10a927 317 (*config->trigger_sources)[state->trigger_source],
f3c60fb6 318 dlm_trigger_slopes[state->trigger_slope],
ac10a927 319 state->horiz_triggerpos);
8ab929d6
SA
320}
321
322/**
323 * Searches through an array of strings and returns the index to the
324 * array where a given string is located.
325 *
326 * @param value The string to search for.
327 * @param array The array of strings.
328 * @param result The index at which value is located in array. -1 on error.
329 *
330 * @return SR_ERR when value couldn't be found, SR_OK otherwise.
331 */
332static int array_option_get(char *value, const char *(*array)[],
333 int *result)
334{
335 unsigned int i;
336
337 *result = -1;
338
339 for (i = 0; (*array)[i]; ++i)
340 if (!g_strcmp0(value, (*array)[i])) {
341 *result = i;
342 break;
343 }
344
345 if (*result == -1)
346 return SR_ERR;
347
348 return SR_OK;
349}
350
351/**
352 * This function takes a value of the form "2.000E-03", converts it to a
353 * significand / factor pair and returns the index of an array where
354 * a matching pair was found.
355 *
356 * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
357 * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
358 * Therefore it's easier to break the number up into two strings and handle
359 * them separately.
360 *
361 * @param value The string to be parsed.
362 * @param array The array of s/f pairs.
363 * @param array_len The number of pairs in the array.
364 * @param result The index at which a matching pair was found.
365 *
366 * @return SR_ERR on any parsing error, SR_OK otherwise.
367 */
368static int array_float_get(gchar *value, const uint64_t array[][2],
369 int array_len, int *result)
370{
371 int i;
372 uint64_t f;
373 float s;
ac10a927 374 unsigned int s_int;
8ab929d6
SA
375 gchar ss[10], es[10];
376
377 memset(ss, 0, sizeof(ss));
378 memset(es, 0, sizeof(es));
379
380 strncpy(ss, value, 5);
381 strncpy(es, &(value[6]), 3);
382
383 if (sr_atof_ascii(ss, &s) != SR_OK)
384 return SR_ERR;
385 if (sr_atoi(es, &i) != SR_OK)
386 return SR_ERR;
387
388 /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
389 f = pow(10, abs(i));
390
391 /* Adjust the significand/factor pair to make sure
392 * that f is a multiple of 1000.
393 */
394 while ((int)fmod(log10(f), 3) > 0) { s *= 10; f *= 10; }
395
396 /* Truncate s to circumvent rounding errors. */
ac10a927 397 s_int = (unsigned int)s;
8ab929d6
SA
398
399 for (i = 0; i < array_len; i++) {
ac10a927 400 if ( (s_int == array[i][0]) && (f == array[i][1]) ) {
8ab929d6
SA
401 *result = i;
402 return SR_OK;
403 }
404 }
405
406 return SR_ERR;
407}
408
409/**
410 * Obtains information about all analog channels from the oscilloscope.
411 * The internal state information is updated accordingly.
412 *
c65a021c 413 * @param sdi The device instance.
8ab929d6
SA
414 * @param config The device's device configuration.
415 * @param state The device's state information.
416 *
417 * @return SR_ERR on error, SR_OK otherwise.
418 */
c65a021c 419static int analog_channel_state_get(const struct sr_dev_inst *sdi,
329733d9 420 const struct scope_config *config,
ac10a927 421 struct scope_state *state)
8ab929d6 422{
c65a021c 423 struct sr_scpi_dev_inst *scpi;
8ab929d6 424 int i, j;
c65a021c
SA
425 GSList *l;
426 struct sr_channel *ch;
8ab929d6
SA
427 gchar *response;
428
c65a021c
SA
429 scpi = sdi->conn;
430
8ab929d6
SA
431 for (i = 0; i < config->analog_channels; ++i) {
432
433 if (dlm_analog_chan_state_get(scpi, i + 1,
ac10a927 434 &state->analog_states[i].state) != SR_OK)
8ab929d6
SA
435 return SR_ERR;
436
c65a021c
SA
437 for (l = sdi->channels; l; l = l->next) {
438 ch = l->data;
439 if (ch->index == i) {
440 ch->enabled = state->analog_states[i].state;
441 break;
442 }
443 }
444
8ab929d6
SA
445 if (dlm_analog_chan_vdiv_get(scpi, i + 1, &response) != SR_OK)
446 return SR_ERR;
447
f3c60fb6 448 if (array_float_get(response, dlm_vdivs, ARRAY_SIZE(dlm_vdivs),
ac10a927 449 &j) != SR_OK) {
8ab929d6
SA
450 g_free(response);
451 return SR_ERR;
452 }
453
454 g_free(response);
455 state->analog_states[i].vdiv = j;
456
457 if (dlm_analog_chan_voffs_get(scpi, i + 1,
ac10a927 458 &state->analog_states[i].vertical_offset) != SR_OK)
8ab929d6
SA
459 return SR_ERR;
460
461 if (dlm_analog_chan_wrange_get(scpi, i + 1,
ac10a927 462 &state->analog_states[i].waveform_range) != SR_OK)
8ab929d6
SA
463 return SR_ERR;
464
465 if (dlm_analog_chan_woffs_get(scpi, i + 1,
ac10a927 466 &state->analog_states[i].waveform_offset) != SR_OK)
8ab929d6
SA
467 return SR_ERR;
468
469 if (dlm_analog_chan_coupl_get(scpi, i + 1, &response) != SR_OK) {
470 g_free(response);
471 return SR_ERR;
472 }
473
474 if (array_option_get(response, config->coupling_options,
ac10a927 475 &state->analog_states[i].coupling) != SR_OK) {
8ab929d6
SA
476 g_free(response);
477 return SR_ERR;
478 }
479 g_free(response);
480 }
481
482 return SR_OK;
483}
484
485/**
486 * Obtains information about all digital channels from the oscilloscope.
487 * The internal state information is updated accordingly.
488 *
c65a021c 489 * @param sdi The device instance.
8ab929d6
SA
490 * @param config The device's device configuration.
491 * @param state The device's state information.
492 *
493 * @return SR_ERR on error, SR_OK otherwise.
494 */
c65a021c 495static int digital_channel_state_get(const struct sr_dev_inst *sdi,
329733d9 496 const struct scope_config *config,
ac10a927 497 struct scope_state *state)
8ab929d6 498{
c65a021c
SA
499 struct sr_scpi_dev_inst *scpi;
500 int i;
501 GSList *l;
502 struct sr_channel *ch;
503
504 scpi = sdi->conn;
8ab929d6
SA
505
506 if (!config->digital_channels)
507 {
508 sr_warn("Tried obtaining digital channel states on a " \
ac10a927 509 "model without digital inputs.");
8ab929d6
SA
510 return SR_OK;
511 }
512
513 for (i = 0; i < config->digital_channels; ++i) {
514 if (dlm_digital_chan_state_get(scpi, i + 1,
515 &state->digital_states[i]) != SR_OK) {
516 return SR_ERR;
517 }
c65a021c
SA
518
519 for (l = sdi->channels; l; l = l->next) {
520 ch = l->data;
521 if (ch->index == i + DLM_DIG_CHAN_INDEX_OFFS) {
522 ch->enabled = state->digital_states[i];
523 break;
524 }
525 }
8ab929d6
SA
526 }
527
528 if (!config->pods)
529 {
530 sr_warn("Tried obtaining pod states on a model without pods.");
531 return SR_OK;
532 }
533
534 for (i = 0; i < config->pods; ++i) {
535 if (dlm_digital_pod_state_get(scpi, i + 'A',
536 &state->pod_states[i]) != SR_OK)
537 return SR_ERR;
538 }
539
540 return SR_OK;
541}
542
c65a021c
SA
543/**
544 *
545 */
546SR_PRIV int dlm_channel_state_set(const struct sr_dev_inst *sdi,
547 const int ch_index, gboolean ch_state)
548{
549 GSList *l;
550 struct sr_channel *ch;
551 struct dev_context *devc = NULL;
552 struct scope_state *state;
553 const struct scope_config *model = NULL;
554 struct sr_scpi_dev_inst *scpi;
555 gboolean chan_found;
556 gboolean *pod_enabled;
557 int i, result;
558
559 result = SR_OK;
560
561 scpi = sdi->conn;
562 devc = sdi->priv;
563 state = devc->model_state;
564 model = devc->model_config;
565 chan_found = FALSE;
566
567 pod_enabled = g_malloc0(sizeof(gboolean) * model->pods);
568
569 for (l = sdi->channels; l; l = l->next) {
570 ch = l->data;
571
572 switch (ch->type) {
573 case SR_CHANNEL_ANALOG:
574 if (ch->index == ch_index) {
575 if (dlm_analog_chan_state_set(scpi, ch->index + 1, ch_state) != SR_OK) {
576 result = SR_ERR;
577 break;
578 }
579
580 ch->enabled = ch_state;
581 state->analog_states[ch->index].state = ch_state;
582 chan_found = TRUE;
583 break;
584 }
585 break;
586 case SR_CHANNEL_LOGIC:
587 i = ch->index - DLM_DIG_CHAN_INDEX_OFFS;
588
589 if (ch->index == ch_index) {
590 if (dlm_digital_chan_state_set(scpi, i + 1, ch_state) != SR_OK) {
591 result = SR_ERR;
592 break;
593 }
594
595 ch->enabled = ch_state;
596 state->digital_states[i] = ch_state;
597 chan_found = TRUE;
598
599 /* The corresponding pod has to be enabled also. */
600 pod_enabled[i / 8] |= ch->enabled;
601 } else
602 /* Also check all other channels. Maybe we can disable a pod. */
603 pod_enabled[i / 8] |= ch->enabled;
604 break;
605 default:
606 result = SR_ERR_NA;
607 }
608 }
609
610 for (i = 0; i < model->pods; ++i) {
611 if (state->pod_states[i] == pod_enabled[i])
612 continue;
613
614 if (dlm_digital_pod_state_set(scpi, i + 1, pod_enabled[i]) != SR_OK) {
615 result = SR_ERR;
616 break;
617 }
618
619 state->pod_states[i] = pod_enabled[i];
620 }
621
622 g_free(pod_enabled);
623
624 if ((result == SR_OK) && !chan_found)
625 result = SR_ERR_BUG;
626
627 return result;
628}
629
8ab929d6
SA
630/**
631 * Obtains information about the sample rate from the oscilloscope.
632 * The internal state information is updated accordingly.
633 *
634 * @param sdi The device instance.
635 *
636 * @return SR_ERR on error, SR_OK otherwise.
637 */
638SR_PRIV int dlm_sample_rate_query(const struct sr_dev_inst *sdi)
639{
640 struct dev_context *devc;
641 struct scope_state *state;
642 float tmp_float;
643
644 devc = sdi->priv;
645 state = devc->model_state;
646
647 /* No need to find an active channel to query the sample rate:
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. */
840 for (i = 0; i < scope_models[model_index].pods; ++i) {
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
8ab929d6
SA
967 range = ch_state->waveform_range;
968 offset = ch_state->waveform_offset;
969
970 /* Convert byte sample to voltage according to
971 * page 269 of the Communication Interface User's Manual.
972 */
973 float_data = g_array_new(FALSE, FALSE, sizeof(float));
974 for (i = 0; i < samples; i++) {
975 voltage = (float)g_array_index(data, int8_t, i);
976 voltage = (range * voltage /
ac10a927 977 DLM_DIVISION_FOR_BYTE_FORMAT) + offset;
8ab929d6
SA
978 g_array_append_val(float_data, voltage);
979 }
980
981 analog.channels = g_slist_append(NULL, ch);
982 analog.num_samples = float_data->len;
983 analog.data = (float*)float_data->data;
984 analog.mq = SR_MQ_VOLTAGE;
985 analog.unit = SR_UNIT_VOLT;
986 analog.mqflags = 0;
987 packet.type = SR_DF_ANALOG;
988 packet.payload = &analog;
989 sr_session_send(sdi, &packet);
990 g_slist_free(analog.channels);
991
992 g_array_free(float_data, TRUE);
993 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
994
995 return SR_OK;
996}
997
998/**
999 * Sends logic sample data off to the session bus.
1000 *
1001 * @param data The raw sample data.
8ab929d6
SA
1002 * @ch_state Pointer to the state of the channel whose data we're processing.
1003 * @sdi The device instance.
1004 *
1005 * @return SR_ERR when data is trucated, SR_OK otherwise.
1006 */
af3487ec 1007static int dlm_digital_samples_send(GArray *data,
ac10a927 1008 struct sr_dev_inst *sdi)
8ab929d6 1009{
af3487ec
SA
1010 struct dev_context *devc;
1011 struct scope_state *model_state;
1012 uint32_t samples;
8ab929d6
SA
1013 struct sr_datafeed_logic logic;
1014 struct sr_datafeed_packet packet;
1015
af3487ec
SA
1016 devc = sdi->priv;
1017 model_state = devc->model_state;
1018 samples = model_state->samples_per_frame;
1019
8ab929d6
SA
1020 if (data->len < samples * sizeof(uint8_t)) {
1021 sr_err("Truncated waveform data packet received.");
1022 return SR_ERR;
1023 }
1024
1025 logic.length = samples;
1026 logic.unitsize = 1;
1027 logic.data = data->data;
1028 packet.type = SR_DF_LOGIC;
1029 packet.payload = &logic;
1030 sr_session_send(sdi, &packet);
1031
1032 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
1033
1034 return SR_OK;
1035}
1036
1037/**
1038 * Attempts to query sample data from the oscilloscope in order to send it
1039 * to the session bus for further processing.
1040 *
1041 * @param fd The file descriptor used as the event source.
1042 * @param revents The received events.
1043 * @param cb_data Callback data, in this case our device instance.
1044 *
1045 * @return TRUE in case of success or a recoverable error,
1046 * FALSE when a fatal error was encountered.
1047 */
1048SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
1049{
8ab929d6
SA
1050 struct sr_dev_inst *sdi;
1051 struct scope_state *model_state;
1052 struct dev_context *devc;
af3487ec 1053 struct sr_channel *ch;
8ab929d6 1054 struct sr_datafeed_packet packet;
af3487ec
SA
1055 int chunk_len, num_bytes;
1056 static GArray *data = NULL;
8ab929d6
SA
1057
1058 (void)fd;
1059 (void)revents;
1060
1061 if (!(sdi = cb_data))
1062 return FALSE;
1063
1064 if (!(devc = sdi->priv))
1065 return FALSE;
1066
1067 if (!(model_state = (struct scope_state*)devc->model_state))
1068 return FALSE;
1069
af3487ec
SA
1070 /* Are we waiting for a response from the device? */
1071 if (!devc->data_pending)
8ab929d6 1072 return TRUE;
af3487ec
SA
1073
1074 /* Check if a new query response is coming our way. */
1075 if (!data) {
1076 if (sr_scpi_read_begin(sdi->conn) == SR_OK)
1077 /* The 16 here accounts for the header and EOL. */
1078 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
ac10a927 1079 16 + model_state->samples_per_frame);
af3487ec
SA
1080 else
1081 return TRUE;
8ab929d6
SA
1082 }
1083
af3487ec
SA
1084 /* Store incoming data. */
1085 chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
ac10a927 1086 RECEIVE_BUFFER_SIZE);
af3487ec
SA
1087 if (chunk_len < 0) {
1088 sr_err("Error while reading data: %d", chunk_len);
1089 goto fail;
1090 }
1091 g_array_append_vals(data, devc->receive_buffer, chunk_len);
8ab929d6 1092
af3487ec
SA
1093 /* Read the entire query response before processing. */
1094 if (!sr_scpi_read_complete(sdi->conn))
1095 return TRUE;
8ab929d6 1096
af3487ec
SA
1097 /* We finished reading and are no longer waiting for data. */
1098 devc->data_pending = FALSE;
8ab929d6 1099
af3487ec
SA
1100 /* Signal the beginning of a new frame if this is the first channel. */
1101 if (devc->current_channel == devc->enabled_channels) {
1102 packet.type = SR_DF_FRAME_BEGIN;
1103 sr_session_send(sdi, &packet);
1104 }
8ab929d6 1105
af3487ec
SA
1106 if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
1107 sr_err("Encountered malformed block data header.");
1108 goto fail;
1109 }
8ab929d6 1110
af3487ec
SA
1111 if (num_bytes == 0) {
1112 sr_warn("Zero-length waveform data packet received. " \
ac10a927
SA
1113 "Live mode not supported yet, stopping " \
1114 "acquisition and retrying.");
af3487ec
SA
1115 /* Don't care about return value here. */
1116 dlm_acquisition_stop(sdi->conn);
1117 g_array_free(data, TRUE);
0028d5a1 1118 dlm_channel_data_request(sdi);
af3487ec
SA
1119 return TRUE;
1120 }
8ab929d6 1121
af3487ec
SA
1122 ch = devc->current_channel->data;
1123 switch (ch->type) {
1124 case SR_CHANNEL_ANALOG:
1125 if (dlm_analog_samples_send(data,
1126 &model_state->analog_states[ch->index],
1127 sdi) != SR_OK)
8ab929d6 1128 goto fail;
af3487ec
SA
1129 break;
1130 case SR_CHANNEL_LOGIC:
1131 if (dlm_digital_samples_send(data, sdi) != SR_OK)
1132 goto fail;
1133 break;
1134 default:
1135 sr_err("Invalid channel type encountered.");
1136 break;
1137 }
8ab929d6 1138
af3487ec
SA
1139 g_array_free(data, TRUE);
1140 data = NULL;
8ab929d6 1141
af3487ec
SA
1142 /* Signal the end of this frame if this was the last enabled channel
1143 * and set the next enabled channel. Then, request its data.
1144 */
1145 if (!devc->current_channel->next) {
1146 packet.type = SR_DF_FRAME_END;
1147 sr_session_send(sdi, &packet);
1148 devc->current_channel = devc->enabled_channels;
1149
1150 /* As of now we only support importing the current acquisition
1151 * data so we're going to stop at this point.
1152 */
1153 sdi->driver->dev_acquisition_stop(sdi, cb_data);
1154 return TRUE;
1155 } else
1156 devc->current_channel = devc->current_channel->next;
8ab929d6 1157
af3487ec 1158 if (dlm_channel_data_request(sdi) != SR_OK) {
f3f19d11 1159 sr_err("Failed to request acquisition data.");
af3487ec 1160 goto fail;
8ab929d6
SA
1161 }
1162
8ab929d6
SA
1163 return TRUE;
1164
1165fail:
af3487ec 1166 if (data) {
8ab929d6 1167 g_array_free(data, TRUE);
af3487ec
SA
1168 data = NULL;
1169 }
8ab929d6 1170
af3487ec 1171 return FALSE;
8ab929d6 1172}