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