]> sigrok.org Git - libsigrok.git/blame_incremental - yokogawa-dlm/protocol.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / yokogawa-dlm / protocol.c
... / ...
CommitLineData
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2014 abraxa (Soeren Apel) <soeren@apelpie.net>
5 * Based on the Hameg HMO driver by poljar (Damir Jelić) <poljarinho@gmail.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <config.h>
22#include "scpi.h"
23#include "protocol.h"
24
25static const char *coupling_options[] = {
26 "AC", "DC", "DC50", "GND",
27};
28
29static const char *trigger_sources_2ch[] = {
30 "1", "2", "LINE", "EXT",
31};
32
33/* TODO: Is BITx handled correctly or is Dx required? */
34static const char *trigger_sources_4ch[] = {
35 "1", "2", "3", "4",
36 "LINE", "EXT", "BIT1",
37 "BIT2", "BIT3", "BIT4", "BIT5", "BIT6", "BIT7", "BIT8",
38};
39
40/* Note: Values must correlate to the trigger_slopes values. */
41const char *dlm_trigger_slopes[2] = {
42 "r", "f",
43};
44
45const uint64_t dlm_timebases[36][2] = {
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
88const uint64_t dlm_vdivs[17][2] = {
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[] = {
111 "1", "2", "3", "4",
112};
113
114static const char *scope_digital_channel_names_8[] = {
115 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
116};
117
118static const char *scope_digital_channel_names_32[] = {
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",
123};
124
125static const struct scope_config scope_models[] = {
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,
134 .digital_names = &scope_digital_channel_names_8,
135
136 .coupling_options = &coupling_options,
137 .num_coupling_options = ARRAY_SIZE(coupling_options),
138
139 .trigger_sources = &trigger_sources_2ch,
140 .num_trigger_sources = ARRAY_SIZE(trigger_sources_2ch),
141
142 .num_xdivs = 10,
143 .num_ydivs = 8,
144 },
145 {
146 .model_id = {"710110", "710120", "710130", NULL},
147 .model_name = {"DLM2024", "DLM2034", "DLM2054", NULL},
148 .analog_channels = 4,
149 .digital_channels = 8,
150 .pods = 1,
151
152 .analog_names = &scope_analog_channel_names,
153 .digital_names = &scope_digital_channel_names_8,
154
155 .coupling_options = &coupling_options,
156 .num_coupling_options = ARRAY_SIZE(coupling_options),
157
158 .trigger_sources = &trigger_sources_4ch,
159 .num_trigger_sources = ARRAY_SIZE(trigger_sources_4ch),
160
161 .num_xdivs = 10,
162 .num_ydivs = 8,
163 },
164 {
165 .model_id = {"701307", "701308", "701310", "701311",
166 "701312", "701313", NULL},
167 .model_name = {"DL9040", "DL9040L", "DL9140", "DL9140L",
168 "DL9240", "DL9240L", NULL},
169 .analog_channels = 4,
170 .digital_channels = 0,
171 .pods = 0,
172
173 .analog_names = &scope_analog_channel_names,
174 .digital_names = NULL,
175
176 .coupling_options = &coupling_options,
177 .num_coupling_options = ARRAY_SIZE(coupling_options),
178
179 .trigger_sources = &trigger_sources_4ch,
180 .num_trigger_sources = ARRAY_SIZE(trigger_sources_4ch),
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
195 .coupling_options = &coupling_options,
196 .num_coupling_options = ARRAY_SIZE(coupling_options),
197
198 .trigger_sources = &trigger_sources_4ch,
199 .num_trigger_sources = ARRAY_SIZE(trigger_sources_4ch),
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,
213
214 .coupling_options = &coupling_options,
215 .num_coupling_options = ARRAY_SIZE(coupling_options),
216
217 .trigger_sources = &trigger_sources_4ch,
218 .num_trigger_sources = ARRAY_SIZE(trigger_sources_4ch),
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 */
231static void scope_state_dump(const struct scope_config *config,
232 struct scope_state *state)
233{
234 unsigned int i;
235 char *tmp;
236
237 for (i = 0; i < config->analog_channels; i++) {
238 tmp = sr_voltage_string(dlm_vdivs[state->analog_states[i].vdiv][0],
239 dlm_vdivs[state->analog_states[i].vdiv][1]);
240 sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
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);
244 }
245
246 for (i = 0; i < config->digital_channels; i++) {
247 sr_info("State of digital channel %d -> %s", i,
248 state->digital_states[i] ? "On" : "Off");
249 }
250
251 for (i = 0; i < config->pods; i++) {
252 sr_info("State of digital POD %d -> %s", i,
253 state->pod_states[i] ? "On" : "Off");
254 }
255
256 tmp = sr_period_string(dlm_timebases[state->timebase][0],
257 dlm_timebases[state->timebase][1]);
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
265 sr_info("Current samples per acquisition (i.e. frame): %d",
266 state->samples_per_frame);
267
268 sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
269 (*config->trigger_sources)[state->trigger_source],
270 dlm_trigger_slopes[state->trigger_slope],
271 state->horiz_triggerpos);
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)[],
285 unsigned int n, int *result)
286{
287 unsigned int i;
288
289 *result = -1;
290
291 for (i = 0; i < n; i++)
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{
323 int i, e;
324 size_t pos;
325 uint64_t f;
326 float s;
327 unsigned int s_int;
328 gchar ss[10], es[10];
329
330 memset(ss, 0, sizeof(ss));
331 memset(es, 0, sizeof(es));
332
333 /* Get index of the separating 'E' character and break up the string. */
334 pos = strcspn(value, "E");
335
336 strncpy(ss, value, pos);
337 strncpy(es, &(value[pos+1]), 3);
338
339 if (sr_atof_ascii(ss, &s) != SR_OK)
340 return SR_ERR;
341 if (sr_atoi(es, &e) != SR_OK)
342 return SR_ERR;
343
344 /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
345 f = pow(10, abs(e));
346
347 /*
348 * Adjust the significand/factor pair to make sure
349 * that f is a multiple of 1000.
350 */
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 }
359
360 /* Truncate s to circumvent rounding errors. */
361 s_int = (unsigned int)s;
362
363 for (i = 0; i < array_len; i++) {
364 if ((s_int == array[i][0]) && (f == array[i][1])) {
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 *
377 * @param sdi The device instance.
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 */
383static int analog_channel_state_get(const struct sr_dev_inst *sdi,
384 const struct scope_config *config,
385 struct scope_state *state)
386{
387 struct sr_scpi_dev_inst *scpi;
388 int i, j;
389 GSList *l;
390 struct sr_channel *ch;
391 gchar *response;
392
393 scpi = sdi->conn;
394
395 for (i = 0; i < config->analog_channels; i++) {
396
397 if (dlm_analog_chan_state_get(scpi, i + 1,
398 &state->analog_states[i].state) != SR_OK)
399 return SR_ERR;
400
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
409 if (dlm_analog_chan_vdiv_get(scpi, i + 1, &response) != SR_OK)
410 return SR_ERR;
411
412 if (array_float_get(response, ARRAY_AND_SIZE(dlm_vdivs),
413 &j) != SR_OK) {
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,
422 &state->analog_states[i].vertical_offset) != SR_OK)
423 return SR_ERR;
424
425 if (dlm_analog_chan_wrange_get(scpi, i + 1,
426 &state->analog_states[i].waveform_range) != SR_OK)
427 return SR_ERR;
428
429 if (dlm_analog_chan_woffs_get(scpi, i + 1,
430 &state->analog_states[i].waveform_offset) != SR_OK)
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,
439 config->num_coupling_options,
440 &state->analog_states[i].coupling) != SR_OK) {
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 *
454 * @param sdi The device instance.
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 */
460static int digital_channel_state_get(const struct sr_dev_inst *sdi,
461 const struct scope_config *config,
462 struct scope_state *state)
463{
464 struct sr_scpi_dev_inst *scpi;
465 int i;
466 GSList *l;
467 struct sr_channel *ch;
468
469 scpi = sdi->conn;
470
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 }
476
477 for (i = 0; i < config->digital_channels; i++) {
478 if (dlm_digital_chan_state_get(scpi, i + 1,
479 &state->digital_states[i]) != SR_OK) {
480 return SR_ERR;
481 }
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 }
490 }
491
492 if (!config->pods) {
493 sr_warn("Tried obtaining pod states on a model without pods.");
494 return SR_OK;
495 }
496
497 for (i = 0; i < config->pods; i++) {
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
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
555 ch->enabled = ch_state;
556 state->digital_states[i] = ch_state;
557 chan_found = TRUE;
558
559 /* The corresponding pod has to be enabled also. */
560 pod_enabled[i / 8] |= ch->enabled;
561 } else {
562 /* Also check all other channels. Maybe we can disable a pod. */
563 pod_enabled[i / 8] |= ch->enabled;
564 }
565 break;
566 default:
567 result = SR_ERR_NA;
568 }
569 }
570
571 for (i = 0; i < model->pods; i++) {
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
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
608 /*
609 * No need to find an active channel to query the sample rate:
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;
633 const struct scope_config *config;
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
642 if (analog_channel_state_get(sdi, config, state) != SR_OK)
643 return SR_ERR;
644
645 if (digital_channel_state_get(sdi, config, state) != SR_OK)
646 return SR_ERR;
647
648 if (dlm_timebase_get(sdi->conn, &response) != SR_OK)
649 return SR_ERR;
650
651 if (array_float_get(response, ARRAY_AND_SIZE(dlm_timebases), &i) != SR_OK) {
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 /
664 (((double)dlm_timebases[state->timebase][0] /
665 dlm_timebases[state->timebase][1]) * config->num_xdivs);
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,
675 config->num_trigger_sources, &state->trigger_source) != SR_OK) {
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
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
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 *
704 * @return The newly allocated scope_state struct.
705 */
706static struct scope_state *dlm_scope_state_new(const struct scope_config *config)
707{
708 struct scope_state *state;
709
710 state = g_malloc0(sizeof(struct scope_state));
711
712 state->analog_states = g_malloc0(config->analog_channels *
713 sizeof(struct analog_channel_state));
714
715 state->digital_states = g_malloc0(config->digital_channels *
716 sizeof(gboolean));
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.",
757 model_id);
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 int i;
773 struct sr_channel *ch;
774 struct dev_context *devc;
775
776 devc = sdi->priv;
777
778 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
779 scope_models[model_index].analog_channels);
780
781 devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
782 scope_models[model_index].pods);
783
784 /* Add analog channels, each in its own group. */
785 for (i = 0; i < scope_models[model_index].analog_channels; i++) {
786 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
787 (*scope_models[model_index].analog_names)[i]);
788
789 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
790
791 devc->analog_groups[i]->name = g_strdup(
792 (char *)(*scope_models[model_index].analog_names)[i]);
793 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
794
795 sdi->channel_groups = g_slist_append(sdi->channel_groups,
796 devc->analog_groups[i]);
797 }
798
799 /* Add digital channel groups. */
800 for (i = 0; i < scope_models[model_index].pods; i++) {
801 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
802 if (!devc->digital_groups[i])
803 return SR_ERR_MALLOC;
804 devc->digital_groups[i]->name = g_strdup_printf("POD%d", i);
805 sdi->channel_groups = g_slist_append(sdi->channel_groups,
806 devc->digital_groups[i]);
807 }
808
809 /* Add digital channels. */
810 for (i = 0; i < scope_models[model_index].digital_channels; i++) {
811 ch = sr_channel_new(sdi, DLM_DIG_CHAN_INDEX_OFFS + i,
812 SR_CHANNEL_LOGIC, TRUE,
813 (*scope_models[model_index].digital_names)[i]);
814
815 devc->digital_groups[i / 8]->channels = g_slist_append(
816 devc->digital_groups[i / 8]->channels, ch);
817 }
818 devc->model_config = &scope_models[model_index];
819 devc->frame_limit = 0;
820
821 if (!(devc->model_state = dlm_scope_state_new(devc->model_config)))
822 return SR_ERR_MALLOC;
823
824 /* Disable non-standard response behavior. */
825 if (dlm_response_headers_set(sdi->conn, FALSE) != SR_OK)
826 return SR_ERR;
827
828 return SR_OK;
829}
830
831SR_PRIV int dlm_channel_data_request(const struct sr_dev_inst *sdi)
832{
833 struct dev_context *devc;
834 struct sr_channel *ch;
835 int result;
836
837 devc = sdi->priv;
838 ch = devc->current_channel->data;
839
840 switch (ch->type) {
841 case SR_CHANNEL_ANALOG:
842 result = dlm_analog_data_get(sdi->conn, ch->index + 1);
843 break;
844 case SR_CHANNEL_LOGIC:
845 result = dlm_digital_data_get(sdi->conn);
846 break;
847 default:
848 sr_err("Invalid channel type encountered (%d).",
849 ch->type);
850 result = SR_ERR;
851 }
852
853 if (result == SR_OK)
854 devc->data_pending = TRUE;
855 else
856 devc->data_pending = FALSE;
857
858 return result;
859}
860
861/**
862 * Reads and removes the block data header from a given data input.
863 * Format is #ndddd... with n being the number of decimal digits d.
864 * The string dddd... contains the decimal-encoded length of the data.
865 * Example: #9000000013 would yield a length of 13 bytes.
866 *
867 * @param data The input data.
868 * @param len The determined input data length.
869 */
870static int dlm_block_data_header_process(GArray *data, int *len)
871{
872 int i, n;
873 gchar s[20];
874
875 if (g_array_index(data, gchar, 0) != '#')
876 return SR_ERR;
877
878 n = (uint8_t)(g_array_index(data, gchar, 1) - '0');
879
880 for (i = 0; i < n; i++)
881 s[i] = g_array_index(data, gchar, 2 + i);
882 s[i] = 0;
883
884 if (sr_atoi(s, len) != SR_OK)
885 return SR_ERR;
886
887 g_array_remove_range(data, 0, 2 + n);
888
889 return SR_OK;
890}
891
892/**
893 * Turns raw sample data into voltages and sends them off to the session bus.
894 *
895 * @param data The raw sample data.
896 * @ch_state Pointer to the state of the channel whose data we're processing.
897 * @sdi The device instance.
898 *
899 * @return SR_ERR when data is trucated, SR_OK otherwise.
900 */
901static int dlm_analog_samples_send(GArray *data,
902 struct analog_channel_state *ch_state,
903 struct sr_dev_inst *sdi)
904{
905 uint32_t i, samples;
906 float voltage, range, offset;
907 GArray *float_data;
908 struct dev_context *devc;
909 struct scope_state *model_state;
910 struct sr_channel *ch;
911 struct sr_datafeed_analog analog;
912 struct sr_analog_encoding encoding;
913 struct sr_analog_meaning meaning;
914 struct sr_analog_spec spec;
915 struct sr_datafeed_packet packet;
916
917 devc = sdi->priv;
918 model_state = devc->model_state;
919 samples = model_state->samples_per_frame;
920 ch = devc->current_channel->data;
921
922 if (data->len < samples * sizeof(uint8_t)) {
923 sr_err("Truncated waveform data packet received.");
924 return SR_ERR;
925 }
926
927 range = ch_state->waveform_range;
928 offset = ch_state->waveform_offset;
929
930 /*
931 * Convert byte sample to voltage according to
932 * page 269 of the Communication Interface User's Manual.
933 */
934 float_data = g_array_new(FALSE, FALSE, sizeof(float));
935 for (i = 0; i < samples; i++) {
936 voltage = (float)g_array_index(data, int8_t, i);
937 voltage = (range * voltage /
938 DLM_DIVISION_FOR_BYTE_FORMAT) + offset;
939 g_array_append_val(float_data, voltage);
940 }
941
942 /* TODO: Use proper 'digits' value for this device (and its modes). */
943 sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
944 analog.meaning->channels = g_slist_append(NULL, ch);
945 analog.num_samples = float_data->len;
946 analog.data = (float*)float_data->data;
947 analog.meaning->mq = SR_MQ_VOLTAGE;
948 analog.meaning->unit = SR_UNIT_VOLT;
949 analog.meaning->mqflags = 0;
950 packet.type = SR_DF_ANALOG;
951 packet.payload = &analog;
952 sr_session_send(sdi, &packet);
953 g_slist_free(analog.meaning->channels);
954
955 g_array_free(float_data, TRUE);
956 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
957
958 return SR_OK;
959}
960
961/**
962 * Sends logic sample data off to the session bus.
963 *
964 * @param data The raw sample data.
965 * @ch_state Pointer to the state of the channel whose data we're processing.
966 * @sdi The device instance.
967 *
968 * @return SR_ERR when data is trucated, SR_OK otherwise.
969 */
970static int dlm_digital_samples_send(GArray *data,
971 struct sr_dev_inst *sdi)
972{
973 struct dev_context *devc;
974 struct scope_state *model_state;
975 uint32_t samples;
976 struct sr_datafeed_logic logic;
977 struct sr_datafeed_packet packet;
978
979 devc = sdi->priv;
980 model_state = devc->model_state;
981 samples = model_state->samples_per_frame;
982
983 if (data->len < samples * sizeof(uint8_t)) {
984 sr_err("Truncated waveform data packet received.");
985 return SR_ERR;
986 }
987
988 logic.length = samples;
989 logic.unitsize = 1;
990 logic.data = data->data;
991 packet.type = SR_DF_LOGIC;
992 packet.payload = &logic;
993 sr_session_send(sdi, &packet);
994
995 g_array_remove_range(data, 0, samples * sizeof(uint8_t));
996
997 return SR_OK;
998}
999
1000/**
1001 * Attempts to query sample data from the oscilloscope in order to send it
1002 * to the session bus for further processing.
1003 *
1004 * @param fd The file descriptor used as the event source.
1005 * @param revents The received events.
1006 * @param cb_data Callback data, in this case our device instance.
1007 *
1008 * @return TRUE in case of success or a recoverable error,
1009 * FALSE when a fatal error was encountered.
1010 */
1011SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
1012{
1013 struct sr_dev_inst *sdi;
1014 struct scope_state *model_state;
1015 struct dev_context *devc;
1016 struct sr_channel *ch;
1017 struct sr_datafeed_packet packet;
1018 int chunk_len, num_bytes;
1019 static GArray *data = NULL;
1020
1021 (void)fd;
1022 (void)revents;
1023
1024 if (!(sdi = cb_data))
1025 return FALSE;
1026
1027 if (!(devc = sdi->priv))
1028 return FALSE;
1029
1030 if (!(model_state = (struct scope_state*)devc->model_state))
1031 return FALSE;
1032
1033 /* Are we waiting for a response from the device? */
1034 if (!devc->data_pending)
1035 return TRUE;
1036
1037 /* Check if a new query response is coming our way. */
1038 if (!data) {
1039 if (sr_scpi_read_begin(sdi->conn) == SR_OK)
1040 /* The 16 here accounts for the header and EOL. */
1041 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
1042 16 + model_state->samples_per_frame);
1043 else
1044 return TRUE;
1045 }
1046
1047 /* Store incoming data. */
1048 chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
1049 RECEIVE_BUFFER_SIZE);
1050 if (chunk_len < 0) {
1051 sr_err("Error while reading data: %d", chunk_len);
1052 goto fail;
1053 }
1054 g_array_append_vals(data, devc->receive_buffer, chunk_len);
1055
1056 /* Read the entire query response before processing. */
1057 if (!sr_scpi_read_complete(sdi->conn))
1058 return TRUE;
1059
1060 /* We finished reading and are no longer waiting for data. */
1061 devc->data_pending = FALSE;
1062
1063 /* Signal the beginning of a new frame if this is the first channel. */
1064 if (devc->current_channel == devc->enabled_channels) {
1065 packet.type = SR_DF_FRAME_BEGIN;
1066 sr_session_send(sdi, &packet);
1067 }
1068
1069 if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
1070 sr_err("Encountered malformed block data header.");
1071 goto fail;
1072 }
1073
1074 if (num_bytes == 0) {
1075 sr_warn("Zero-length waveform data packet received. " \
1076 "Live mode not supported yet, stopping " \
1077 "acquisition and retrying.");
1078 /* Don't care about return value here. */
1079 dlm_acquisition_stop(sdi->conn);
1080 g_array_free(data, TRUE);
1081 dlm_channel_data_request(sdi);
1082 return TRUE;
1083 }
1084
1085 ch = devc->current_channel->data;
1086 switch (ch->type) {
1087 case SR_CHANNEL_ANALOG:
1088 if (dlm_analog_samples_send(data,
1089 &model_state->analog_states[ch->index],
1090 sdi) != SR_OK)
1091 goto fail;
1092 break;
1093 case SR_CHANNEL_LOGIC:
1094 if (dlm_digital_samples_send(data, sdi) != SR_OK)
1095 goto fail;
1096 break;
1097 default:
1098 sr_err("Invalid channel type encountered.");
1099 break;
1100 }
1101
1102 g_array_free(data, TRUE);
1103 data = NULL;
1104
1105 /*
1106 * Signal the end of this frame if this was the last enabled channel
1107 * and set the next enabled channel. Then, request its data.
1108 */
1109 if (!devc->current_channel->next) {
1110 packet.type = SR_DF_FRAME_END;
1111 sr_session_send(sdi, &packet);
1112 devc->current_channel = devc->enabled_channels;
1113
1114 /*
1115 * As of now we only support importing the current acquisition
1116 * data so we're going to stop at this point.
1117 */
1118 sr_dev_acquisition_stop(sdi);
1119 return TRUE;
1120 } else
1121 devc->current_channel = devc->current_channel->next;
1122
1123 if (dlm_channel_data_request(sdi) != SR_OK) {
1124 sr_err("Failed to request acquisition data.");
1125 goto fail;
1126 }
1127
1128 return TRUE;
1129
1130fail:
1131 if (data) {
1132 g_array_free(data, TRUE);
1133 data = NULL;
1134 }
1135
1136 return FALSE;
1137}