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