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