]> sigrok.org Git - libsigrok.git/blame - src/hardware/yokogawa-dlm/protocol.c
yokogawa-dlm: Add support for the DL9000 series
[libsigrok.git] / src / hardware / yokogawa-dlm / protocol.c
CommitLineData
10763937
SA
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2014 abraxa (Soeren Apel) <soeren@apelpie.net>
5 * Based on the Hameg HMO driver by poljar (Damir Jelić) <poljarinho@gmail.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
8ab929d6
SA
21/** @file
22 * <em>Yokogawa DL/DLM series</em> oscilloscope driver
23 * @internal
24 */
25
10763937
SA
26#include "protocol.h"
27
f254bc4b 28static const uint32_t dlm_devopts[] = {
8ab929d6
SA
29 SR_CONF_LOGIC_ANALYZER,
30 SR_CONF_OSCILLOSCOPE,
5827f61b
BV
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,
bf622e6d 36 SR_CONF_NUM_HDIV | SR_CONF_GET,
5827f61b 37 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
8ab929d6
SA
38};
39
f254bc4b 40static const uint32_t dlm_analog_devopts[] = {
5827f61b
BV
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,
8ab929d6
SA
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
7048bb1f 160static const char *scope_digital_channel_names_8[] = {
8ab929d6
SA
161 "D0",
162 "D1",
163 "D2",
164 "D3",
165 "D4",
166 "D5",
167 "D6",
168 "D7"
169};
170
7048bb1f
SA
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
329733d9 206static const struct scope_config scope_models[] = {
8ab929d6
SA
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,
7048bb1f 215 .digital_names = &scope_digital_channel_names_8,
8ab929d6 216
f254bc4b
BV
217 .devopts = &dlm_devopts,
218 .num_devopts = ARRAY_SIZE(dlm_devopts),
8ab929d6 219
f254bc4b
BV
220 .analog_devopts = &dlm_analog_devopts,
221 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
8ab929d6
SA
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,
7048bb1f
SA
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,
8ab929d6 334
f254bc4b
BV
335 .devopts = &dlm_devopts,
336 .num_devopts = ARRAY_SIZE(dlm_devopts),
8ab929d6 337
f254bc4b
BV
338 .analog_devopts = &dlm_analog_devopts,
339 .num_analog_devopts = ARRAY_SIZE(dlm_analog_devopts),
8ab929d6
SA
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 */
329733d9 362static void scope_state_dump(const struct scope_config *config,
8ab929d6
SA
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],
ac10a927 370 (*config->vdivs)[state->analog_states[i].vdiv][1]);
8ab929d6 371 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
ac10a927
SA
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);
8ab929d6
SA
375 }
376
377 for (i = 0; i < config->digital_channels; ++i) {
378 sr_info("State of digital channel %d -> %s", i,
ac10a927 379 state->digital_states[i] ? "On" : "Off");
8ab929d6
SA
380 }
381
382 for (i = 0; i < config->pods; ++i) {
383 sr_info("State of digital POD %d -> %s", i,
ac10a927 384 state->pod_states[i] ? "On" : "Off");
8ab929d6
SA
385 }
386
387 tmp = sr_period_string((*config->timebases)[state->timebase][0] *
ac10a927 388 (*config->timebases)[state->timebase][1]);
8ab929d6
SA
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
af3487ec 396 sr_info("Current samples per acquisition (i.e. frame): %d",
ac10a927 397 state->samples_per_frame);
af3487ec 398
8ab929d6 399 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
ac10a927
SA
400 (*config->trigger_sources)[state->trigger_source],
401 (*config->trigger_slopes)[state->trigger_slope],
402 state->horiz_triggerpos);
8ab929d6
SA
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;
ac10a927 457 unsigned int s_int;
8ab929d6
SA
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. */
ac10a927 480 s_int = (unsigned int)s;
8ab929d6
SA
481
482 for (i = 0; i < array_len; i++) {
ac10a927 483 if ( (s_int == array[i][0]) && (f == array[i][1]) ) {
8ab929d6
SA
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,
329733d9 503 const struct scope_config *config,
ac10a927 504 struct scope_state *state)
8ab929d6
SA
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,
ac10a927 512 &state->analog_states[i].state) != SR_OK)
8ab929d6
SA
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,
ac10a927 519 &j) != SR_OK) {
8ab929d6
SA
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,
ac10a927 528 &state->analog_states[i].vertical_offset) != SR_OK)
8ab929d6
SA
529 return SR_ERR;
530
531 if (dlm_analog_chan_wrange_get(scpi, i + 1,
ac10a927 532 &state->analog_states[i].waveform_range) != SR_OK)
8ab929d6
SA
533 return SR_ERR;
534
535 if (dlm_analog_chan_woffs_get(scpi, i + 1,
ac10a927 536 &state->analog_states[i].waveform_offset) != SR_OK)
8ab929d6
SA
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,
ac10a927 545 &state->analog_states[i].coupling) != SR_OK) {
8ab929d6
SA
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,
329733d9 566 const struct scope_config *config,
ac10a927 567 struct scope_state *state)
8ab929d6
SA
568{
569 unsigned int i;
570
571 if (!config->digital_channels)
572 {
573 sr_warn("Tried obtaining digital channel states on a " \
ac10a927 574 "model without digital inputs.");
8ab929d6
SA
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;
329733d9 641 const struct scope_config *config;
8ab929d6
SA
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,
ac10a927 660 config->num_timebases, &i) != SR_OK) {
8ab929d6
SA
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 /
ac10a927
SA
673 (((double)(*config->timebases)[state->timebase][0] /
674 (*config->timebases)[state->timebase][1]) * config->num_xdivs);
8ab929d6
SA
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,
ac10a927 684 &state->trigger_source) != SR_OK) {
8ab929d6
SA
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
af3487ec
SA
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
8ab929d6
SA
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 *
ac10a927 713 * @return The newly allocated scope_state struct.
8ab929d6 714 */
329733d9 715static struct scope_state *dlm_scope_state_new(const struct scope_config *config)
8ab929d6
SA
716{
717 struct scope_state *state;
718
ac10a927 719 state = g_malloc0(sizeof(struct scope_state));
8ab929d6
SA
720
721 state->analog_states = g_malloc0(config->analog_channels *
ac10a927 722 sizeof(struct analog_channel_state));
8ab929d6
SA
723
724 state->digital_states = g_malloc0(config->digital_channels *
ac10a927 725 sizeof(gboolean));
8ab929d6
SA
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.",
ac10a927 766 model_id);
8ab929d6
SA
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*) *
ac10a927 789 scope_models[model_index].analog_channels);
8ab929d6
SA
790
791 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
ac10a927 792 scope_models[model_index].digital_channels);
8ab929d6
SA
793
794 /* Add analog channels. */
795 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
5e23fcab 796 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
c368e6f3 797 (*scope_models[model_index].analog_names)[i]);
8ab929d6
SA
798
799 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
800
801 devc->analog_groups[i]->name = g_strdup(
ac10a927 802 (char *)(*scope_models[model_index].analog_names)[i]);
8ab929d6
SA
803 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
804
805 sdi->channel_groups = g_slist_append(sdi->channel_groups,
ac10a927 806 devc->analog_groups[i]);
8ab929d6
SA
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++) {
5e23fcab 824 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 825 (*scope_models[model_index].digital_names)[i]);
8ab929d6
SA
826
827 devc->digital_groups[i / 8]->channels = g_slist_append(
ac10a927 828 devc->digital_groups[i / 8]->channels, ch);
8ab929d6
SA
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
af3487ec 843SR_PRIV int dlm_channel_data_request(const struct sr_dev_inst *sdi)
8ab929d6 844{
af3487ec
SA
845 struct dev_context *devc;
846 struct sr_channel *ch;
847 int result;
8ab929d6 848
af3487ec
SA
849 devc = sdi->priv;
850 ch = devc->current_channel->data;
8ab929d6 851
af3487ec
SA
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;
8ab929d6
SA
863 }
864
af3487ec
SA
865 if (result == SR_OK)
866 devc->data_pending = TRUE;
867 else
868 devc->data_pending = FALSE;
869
870 return result;
8ab929d6
SA
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.
8ab929d6
SA
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 */
af3487ec 913static int dlm_analog_samples_send(GArray *data,
ac10a927
SA
914 struct analog_channel_state *ch_state,
915 struct sr_dev_inst *sdi)
8ab929d6 916{
af3487ec 917 uint32_t i, samples;
8ab929d6
SA
918 float voltage, range, offset;
919 GArray *float_data;
920 struct dev_context *devc;
af3487ec 921 struct scope_state *model_state;
8ab929d6
SA
922 struct sr_channel *ch;
923 struct sr_datafeed_analog analog;
924 struct sr_datafeed_packet packet;
925
af3487ec
SA
926 devc = sdi->priv;
927 model_state = devc->model_state;
928 samples = model_state->samples_per_frame;
929 ch = devc->current_channel->data;
930
8ab929d6
SA
931 if (data->len < samples * sizeof(uint8_t)) {
932 sr_err("Truncated waveform data packet received.");
933 return SR_ERR;
934 }
935
8ab929d6
SA
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 /
ac10a927 946 DLM_DIVISION_FOR_BYTE_FORMAT) + offset;
8ab929d6
SA
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.
8ab929d6
SA
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 */
af3487ec 976static int dlm_digital_samples_send(GArray *data,
ac10a927 977 struct sr_dev_inst *sdi)
8ab929d6 978{
af3487ec
SA
979 struct dev_context *devc;
980 struct scope_state *model_state;
981 uint32_t samples;
8ab929d6
SA
982 struct sr_datafeed_logic logic;
983 struct sr_datafeed_packet packet;
984
af3487ec
SA
985 devc = sdi->priv;
986 model_state = devc->model_state;
987 samples = model_state->samples_per_frame;
988
8ab929d6
SA
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{
8ab929d6
SA
1019 struct sr_dev_inst *sdi;
1020 struct scope_state *model_state;
1021 struct dev_context *devc;
af3487ec 1022 struct sr_channel *ch;
8ab929d6 1023 struct sr_datafeed_packet packet;
af3487ec
SA
1024 int chunk_len, num_bytes;
1025 static GArray *data = NULL;
8ab929d6
SA
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
af3487ec
SA
1039 /* Are we waiting for a response from the device? */
1040 if (!devc->data_pending)
8ab929d6 1041 return TRUE;
af3487ec
SA
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),
ac10a927 1048 16 + model_state->samples_per_frame);
af3487ec
SA
1049 else
1050 return TRUE;
8ab929d6
SA
1051 }
1052
af3487ec
SA
1053 /* Store incoming data. */
1054 chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
ac10a927 1055 RECEIVE_BUFFER_SIZE);
af3487ec
SA
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);
8ab929d6 1061
af3487ec
SA
1062 /* Read the entire query response before processing. */
1063 if (!sr_scpi_read_complete(sdi->conn))
1064 return TRUE;
8ab929d6 1065
af3487ec
SA
1066 /* We finished reading and are no longer waiting for data. */
1067 devc->data_pending = FALSE;
8ab929d6 1068
af3487ec
SA
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 }
8ab929d6 1074
af3487ec
SA
1075 if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
1076 sr_err("Encountered malformed block data header.");
1077 goto fail;
1078 }
8ab929d6 1079
af3487ec
SA
1080 if (num_bytes == 0) {
1081 sr_warn("Zero-length waveform data packet received. " \
ac10a927
SA
1082 "Live mode not supported yet, stopping " \
1083 "acquisition and retrying.");
af3487ec
SA
1084 /* Don't care about return value here. */
1085 dlm_acquisition_stop(sdi->conn);
1086 g_array_free(data, TRUE);
0028d5a1 1087 dlm_channel_data_request(sdi);
af3487ec
SA
1088 return TRUE;
1089 }
8ab929d6 1090
af3487ec
SA
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)
8ab929d6 1097 goto fail;
af3487ec
SA
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 }
8ab929d6 1107
af3487ec
SA
1108 g_array_free(data, TRUE);
1109 data = NULL;
8ab929d6 1110
af3487ec
SA
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;
8ab929d6 1126
af3487ec 1127 if (dlm_channel_data_request(sdi) != SR_OK) {
f3f19d11 1128 sr_err("Failed to request acquisition data.");
af3487ec 1129 goto fail;
8ab929d6
SA
1130 }
1131
8ab929d6
SA
1132 return TRUE;
1133
1134fail:
af3487ec 1135 if (data) {
8ab929d6 1136 g_array_free(data, TRUE);
af3487ec
SA
1137 data = NULL;
1138 }
8ab929d6 1139
af3487ec 1140 return FALSE;
8ab929d6 1141}