]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/yokogawa-dlm/protocol.c
Consistently don't check sdi->priv in dev_acquisition_start().
[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_old analog;
968 struct sr_datafeed_packet packet;
969
970 devc = sdi->priv;
971 model_state = devc->model_state;
972 samples = model_state->samples_per_frame;
973 ch = devc->current_channel->data;
974
975 if (data->len < samples * sizeof(uint8_t)) {
976 sr_err("Truncated waveform data packet received.");
977 return SR_ERR;
978 }
979
980 range = ch_state->waveform_range;
981 offset = ch_state->waveform_offset;
982
983 /*
984 * Convert byte sample to voltage according to
985 * page 269 of the Communication Interface User's Manual.
986 */
987 float_data = g_array_new(FALSE, FALSE, sizeof(float));
988 for (i = 0; i < samples; i++) {
989 voltage = (float)g_array_index(data, int8_t, i);
990 voltage = (range * voltage /
991 DLM_DIVISION_FOR_BYTE_FORMAT) + offset;
992 g_array_append_val(float_data, voltage);
993 }
994
995 analog.channels = g_slist_append(NULL, ch);
996 analog.num_samples = float_data->len;
997 analog.data = (float*)float_data->data;
998 analog.mq = SR_MQ_VOLTAGE;
999 analog.unit = SR_UNIT_VOLT;
1000 analog.mqflags = 0;
1001 packet.type = SR_DF_ANALOG_OLD;
1002 packet.payload = &analog;
1003 sr_session_send(sdi, &packet);
1004 g_slist_free(analog.channels);
1005
1006 g_array_free(float_data, TRUE);
1007 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
1008
1009 return SR_OK;
1010}
1011
1012/**
1013 * Sends logic sample data off to the session bus.
1014 *
1015 * @param data The raw sample data.
1016 * @ch_state Pointer to the state of the channel whose data we're processing.
1017 * @sdi The device instance.
1018 *
1019 * @return SR_ERR when data is trucated, SR_OK otherwise.
1020 */
1021static int dlm_digital_samples_send(GArray *data,
1022 struct sr_dev_inst *sdi)
1023{
1024 struct dev_context *devc;
1025 struct scope_state *model_state;
1026 uint32_t samples;
1027 struct sr_datafeed_logic logic;
1028 struct sr_datafeed_packet packet;
1029
1030 devc = sdi->priv;
1031 model_state = devc->model_state;
1032 samples = model_state->samples_per_frame;
1033
1034 if (data->len < samples * sizeof(uint8_t)) {
1035 sr_err("Truncated waveform data packet received.");
1036 return SR_ERR;
1037 }
1038
1039 logic.length = samples;
1040 logic.unitsize = 1;
1041 logic.data = data->data;
1042 packet.type = SR_DF_LOGIC;
1043 packet.payload = &logic;
1044 sr_session_send(sdi, &packet);
1045
1046 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
1047
1048 return SR_OK;
1049}
1050
1051/**
1052 * Attempts to query sample data from the oscilloscope in order to send it
1053 * to the session bus for further processing.
1054 *
1055 * @param fd The file descriptor used as the event source.
1056 * @param revents The received events.
1057 * @param cb_data Callback data, in this case our device instance.
1058 *
1059 * @return TRUE in case of success or a recoverable error,
1060 * FALSE when a fatal error was encountered.
1061 */
1062SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
1063{
1064 struct sr_dev_inst *sdi;
1065 struct scope_state *model_state;
1066 struct dev_context *devc;
1067 struct sr_channel *ch;
1068 struct sr_datafeed_packet packet;
1069 int chunk_len, num_bytes;
1070 static GArray *data = NULL;
1071
1072 (void)fd;
1073 (void)revents;
1074
1075 if (!(sdi = cb_data))
1076 return FALSE;
1077
1078 if (!(devc = sdi->priv))
1079 return FALSE;
1080
1081 if (!(model_state = (struct scope_state*)devc->model_state))
1082 return FALSE;
1083
1084 /* Are we waiting for a response from the device? */
1085 if (!devc->data_pending)
1086 return TRUE;
1087
1088 /* Check if a new query response is coming our way. */
1089 if (!data) {
1090 if (sr_scpi_read_begin(sdi->conn) == SR_OK)
1091 /* The 16 here accounts for the header and EOL. */
1092 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
1093 16 + model_state->samples_per_frame);
1094 else
1095 return TRUE;
1096 }
1097
1098 /* Store incoming data. */
1099 chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
1100 RECEIVE_BUFFER_SIZE);
1101 if (chunk_len < 0) {
1102 sr_err("Error while reading data: %d", chunk_len);
1103 goto fail;
1104 }
1105 g_array_append_vals(data, devc->receive_buffer, chunk_len);
1106
1107 /* Read the entire query response before processing. */
1108 if (!sr_scpi_read_complete(sdi->conn))
1109 return TRUE;
1110
1111 /* We finished reading and are no longer waiting for data. */
1112 devc->data_pending = FALSE;
1113
1114 /* Signal the beginning of a new frame if this is the first channel. */
1115 if (devc->current_channel == devc->enabled_channels) {
1116 packet.type = SR_DF_FRAME_BEGIN;
1117 sr_session_send(sdi, &packet);
1118 }
1119
1120 if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
1121 sr_err("Encountered malformed block data header.");
1122 goto fail;
1123 }
1124
1125 if (num_bytes == 0) {
1126 sr_warn("Zero-length waveform data packet received. " \
1127 "Live mode not supported yet, stopping " \
1128 "acquisition and retrying.");
1129 /* Don't care about return value here. */
1130 dlm_acquisition_stop(sdi->conn);
1131 g_array_free(data, TRUE);
1132 dlm_channel_data_request(sdi);
1133 return TRUE;
1134 }
1135
1136 ch = devc->current_channel->data;
1137 switch (ch->type) {
1138 case SR_CHANNEL_ANALOG:
1139 if (dlm_analog_samples_send(data,
1140 &model_state->analog_states[ch->index],
1141 sdi) != SR_OK)
1142 goto fail;
1143 break;
1144 case SR_CHANNEL_LOGIC:
1145 if (dlm_digital_samples_send(data, sdi) != SR_OK)
1146 goto fail;
1147 break;
1148 default:
1149 sr_err("Invalid channel type encountered.");
1150 break;
1151 }
1152
1153 g_array_free(data, TRUE);
1154 data = NULL;
1155
1156 /*
1157 * Signal the end of this frame if this was the last enabled channel
1158 * and set the next enabled channel. Then, request its data.
1159 */
1160 if (!devc->current_channel->next) {
1161 packet.type = SR_DF_FRAME_END;
1162 sr_session_send(sdi, &packet);
1163 devc->current_channel = devc->enabled_channels;
1164
1165 /*
1166 * As of now we only support importing the current acquisition
1167 * data so we're going to stop at this point.
1168 */
1169 sdi->driver->dev_acquisition_stop(sdi, cb_data);
1170 return TRUE;
1171 } else
1172 devc->current_channel = devc->current_channel->next;
1173
1174 if (dlm_channel_data_request(sdi) != SR_OK) {
1175 sr_err("Failed to request acquisition data.");
1176 goto fail;
1177 }
1178
1179 return TRUE;
1180
1181fail:
1182 if (data) {
1183 g_array_free(data, TRUE);
1184 data = NULL;
1185 }
1186
1187 return FALSE;
1188}