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