]> sigrok.org Git - libsigrok.git/blob - src/hardware/siglent-sds/api.c
siglent-sds: initial driver implementation for Siglent SDS
[libsigrok.git] / src / hardware / siglent-sds / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2018 mhooijboer <marchelh@gmail.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21
22 #include <fcntl.h>
23 #include <glib.h>
24 #include <math.h>
25 #include <rpc/rpc.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <unistd.h>
30
31 #include <libsigrok/libsigrok.h>
32 #include "libsigrok-internal.h"
33 #include "protocol.h"
34 #include "scpi.h"
35
36 static const uint32_t scanopts[] = {
37         SR_CONF_CONN,
38         SR_CONF_SERIALCOMM
39 };
40
41 static const uint32_t devopts[] = {
42         SR_CONF_OSCILLOSCOPE,
43         SR_CONF_LOGIC_ANALYZER,
44         SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
45         SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
46         SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
47         SR_CONF_TRIGGER_LEVEL | SR_CONF_GET | SR_CONF_SET,
48         SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
49         SR_CONF_NUM_HDIV | SR_CONF_GET | SR_CONF_LIST,
50         SR_CONF_SAMPLERATE | SR_CONF_GET,
51         SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
52         SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
53         SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
54         SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
55 };
56
57 static const uint32_t analog_devopts[] = {
58         SR_CONF_NUM_VDIV | SR_CONF_GET,
59         SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
60         SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
61         SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
62         SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
63         SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
64 };
65
66 static const uint64_t timebases[][2] = {
67         /* nanoseconds */
68         { 1, 1000000000 },
69         { 2, 1000000000 },
70         { 5, 1000000000 },
71         { 10, 1000000000 },
72         { 20, 1000000000 },
73         { 50, 1000000000 },
74         { 100, 1000000000 },
75         { 200, 1000000000 },
76         { 500, 1000000000 },
77         /* microseconds */
78         { 1, 1000000 },
79         { 2, 1000000 },
80         { 5, 1000000 },
81         { 10, 1000000 },
82         { 20, 1000000 },
83         { 50, 1000000 },
84         { 100, 1000000 },
85         { 200, 1000000 },
86         { 500, 1000000 },
87         /* milliseconds */
88         { 1, 1000 },
89         { 2, 1000 },
90         { 5, 1000 },
91         { 10, 1000 },
92         { 20, 1000 },
93         { 50, 1000 },
94         { 100, 1000 },
95         { 200, 1000 },
96         { 500, 1000 },
97         /* seconds */
98         { 1, 1 },
99         { 2, 1 },
100         { 5, 1 },
101         { 10, 1 },
102         { 20, 1 },
103         { 50, 1 },
104 };
105
106 static const uint64_t vdivs[][2] = {
107         /* microvolts */
108         { 500, 100000 },
109         /* millivolts */
110         { 1, 1000 },
111         { 2, 1000 },
112         { 5, 1000 },
113         { 10, 1000 },
114         { 20, 1000 },
115         { 50, 1000 },
116         { 100, 1000 },
117         { 200, 1000 },
118         { 500, 1000 },
119         /* volts */
120         { 1, 1 },
121         { 2, 1 },
122         { 5, 1 },
123         { 10, 1 },
124         { 20, 1 },
125         { 50, 1 },
126         { 100, 1 },
127 };
128
129 #define NUM_TIMEBASE    ARRAY_SIZE(timebases)
130 #define NUM_VDIV        ARRAY_SIZE(vdivs)
131
132 static const char *trigger_sources[] = {
133         "CH1",
134         "CH2",
135         "Ext",
136         "Ext /5",
137         "AC Line",
138         "D0",
139         "D1",
140         "D2",
141         "D3",
142         "D4",
143         "D5",
144         "D6",
145         "D7",
146         "D8",
147         "D9",
148         "D10",
149         "D11",
150         "D12",
151         "D13",
152         "D14",
153         "D15",
154 };
155
156 static const char *trigger_slopes[] = {
157         "Rising",
158         "Falling",
159 };
160
161 static const char *coupling[] = {
162         "A1M AC 1 Meg",
163         "A50 AC 50 Ohm",
164         "D1M DC 1 Meg",
165         "D50 DC 50 Ohm",
166         "GND",
167 };
168
169 static const uint64_t probe_factor[] = {
170         1,
171         2,
172         5,
173         10,
174         20,
175         50,
176         100,
177         200,
178         500,
179         1000,
180         2000,
181         5000,
182         10000,
183 };
184
185 /* Do not change the order of entries */
186 static const char *data_sources[] = {
187         "Display",
188         "History",
189 };
190
191 enum vendor {
192         SIGLENT,
193 };
194
195 enum series {
196         SDS1000CML,
197         SDS1000CNL,
198         SDS1000DL,
199         SDS1000X,
200         SDS1000XP,
201         SDS1000XE,
202         SDS2000X,
203 };
204
205 /* short name, full name, USB Name */
206 static const struct siglent_sds_vendor supported_vendors[] = {
207         [SIGLENT] = {
208                 "Siglent", "Siglent Technologies", "Siglent Technologies Co,. Ltd.",
209         },
210 };
211
212 #define VENDOR(x) &supported_vendors[x]
213 /* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
214  * number of vertical divs, live waveform samples, memory buffer samples */
215 static const struct siglent_sds_series supported_series[] = {
216         [SDS1000CML] = {
217                 VENDOR(SIGLENT), "SDS1000CML", NON_SPO_MODEL,
218                 { 50, 1 },
219                 { 2, 1000 }, 18, 8, 1400363,
220         },
221         [SDS1000CNL] = {
222                 VENDOR(SIGLENT), "SDS1000CNL", NON_SPO_MODEL,
223                 { 50, 1 },
224                 { 2, 1000 }, 18, 8, 1400363,
225         },
226         [SDS1000DL] = {
227                 VENDOR(SIGLENT), "SDS1000DL", NON_SPO_MODEL,
228                 { 50, 1 },
229                 { 2, 1000 }, 18, 8, 1400363,
230         },
231         [SDS1000X] = {
232                 VENDOR(SIGLENT), "SDS1000X", SPO_MODEL,
233                 { 50, 1 },
234                 { 500, 100000 }, 14, 8, 14000363,
235         },
236         [SDS1000XP] = {
237                 VENDOR(SIGLENT), "SDS1000X+", SPO_MODEL,
238                 { 50, 1 },
239                 { 500, 100000 }, 14, 8, 14000363,
240         },
241         [SDS1000XE] = {
242                 VENDOR(SIGLENT), "SDS1000XE", SPO_MODEL,
243                 { 50, 1 },
244                 { 500, 100000 }, 14, 8, 14000363,
245         },
246         [SDS2000X] = {
247                 VENDOR(SIGLENT), "SDS2000X", SPO_MODEL,
248                 { 50, 1 },
249                 { 500, 100000 }, 14, 8, 14000363,
250         },
251 };
252
253 #define SERIES(x) &supported_series[x]
254 /* series, model, min timebase, analog channels, digital */
255 static const struct siglent_sds_model supported_models[] = {
256         { SERIES(SDS1000CML), "SDS1152CML",
257                 { 20, 1000000000 }, 2, false, 0 },
258         { SERIES(SDS1000CML), "SDS1102CML",
259                 { 10, 1000000000 }, 2, false, 0 },
260         { SERIES(SDS1000CML), "SDS1072CML",
261                 { 5, 1000000000 }, 2, false, 0 },
262         { SERIES(SDS1000CNL), "SDS1202CNL",
263                 { 20, 1000000000 }, 2, false, 0 },
264         { SERIES(SDS1000CNL), "SDS1102CNL",
265                 { 10, 1000000000 }, 2, false, 0 },
266         { SERIES(SDS1000CNL), "SDS1072CNL",
267                 { 5, 1000000000 }, 2, false, 0 },
268         { SERIES(SDS1000DL), "SDS1202DL",
269                 { 20, 1000000000 }, 2, false, 0 },
270         { SERIES(SDS1000DL), "SDS1102DL",
271                 { 10, 1000000000 }, 2, false, 0 },
272         { SERIES(SDS1000DL), "SDS1022DL",
273                 { 5, 1000000000 }, 2, false, 0 },
274         { SERIES(SDS1000DL), "SDS1052DL",
275                 { 5, 1000000000 }, 2, false, 0 },
276         { SERIES(SDS1000X), "SDS1102X",
277                 { 2, 1000000000 }, 2, false, 0 },
278         { SERIES(SDS1000XP), "SDS1102X+",
279                 { 2, 1000000000 }, 2, false, 0 },
280         { SERIES(SDS1000X), "SDS1202X",
281                 { 2, 1000000000 }, 2, false, 0 },
282         { SERIES(SDS1000XP), "SDS1202X+",
283                 { 2, 1000000000 }, 2, false, 0 },
284         { SERIES(SDS1000XE), "SDS1202X-E",
285                 { 1, 1000000000 }, 2, false, 0 },
286         { SERIES(SDS1000XE), "SDS1104X-E",
287                 { 1, 1000000000 }, 4, true, 16 },
288         { SERIES(SDS1000XE), "SDS1204X-E",
289                 { 1, 1000000000 }, 4, true, 16 },
290         { SERIES(SDS2000X), "SDS2072X",
291                 { 2, 1000000000 }, 2, false, 0 },
292         { SERIES(SDS2000X), "SDS2074X",
293                 { 2, 1000000000 }, 4, false, 0 },
294         { SERIES(SDS2000X), "SDS2102X",
295                 { 2, 1000000000 }, 2, false, 0 },
296         { SERIES(SDS2000X), "SDS2104X",
297                 { 2, 1000000000 }, 4, false, 0 },
298         { SERIES(SDS2000X), "SDS2202X",
299                 { 2, 1000000000 }, 2, false, 0 },
300         { SERIES(SDS2000X), "SDS2204X",
301                 { 2, 1000000000 }, 4, false, 0 },
302         { SERIES(SDS2000X), "SDS2302X",
303                 { 2, 1000000000 }, 2, false, 0 },
304         { SERIES(SDS2000X), "SDS2304X",
305                 { 2, 1000000000 }, 4, false, 0 },
306 };
307
308 SR_PRIV struct sr_dev_driver siglent_sds_driver_info;
309
310 static void clear_helper(void *priv)
311 {
312         struct dev_context *devc;
313
314         devc = priv;
315         if (!devc)
316                 return;
317         g_free(devc->analog_groups);
318         g_free(devc->enabled_channels);
319 }
320
321 static int dev_clear(const struct sr_dev_driver *di)
322 {
323
324         return std_dev_clear_with_callback(di, clear_helper);
325 }
326
327 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
328 {
329         struct dev_context *devc;
330         struct sr_dev_inst *sdi;
331         struct sr_scpi_hw_info *hw_info;
332         struct sr_channel *ch;
333         unsigned int i;
334         const struct siglent_sds_model *model;
335         gchar *channel_name;
336
337         sr_info("Device probing decode...");
338
339         /* Setting communication Header Format to OFF*/
340         sr_dbg("Setting Communication Headers to off");
341         if (sr_scpi_send(scpi, "CHDR OFF") != SR_OK)
342                 return NULL;
343
344         if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
345                 sr_info("Couldn't get IDN response, retrying.");
346                 sr_scpi_close(scpi);
347                 sr_scpi_open(scpi);
348                 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
349                         sr_info("Couldn't get IDN response.");
350                         return NULL;
351                 }
352         }
353
354         model = NULL;
355         for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
356                 if (!strcmp(hw_info->model, supported_models[i].name)) {
357                         model = &supported_models[i];
358                         break;
359                 }
360         }
361
362         sr_info("Decoded Manufacturer: %s", hw_info->manufacturer);
363         sr_info("Decoded Model: %s", hw_info->model);
364
365         if (!model) {
366                 sr_scpi_hw_info_free(hw_info);
367                 return NULL;
368         }
369
370         sdi = g_malloc0(sizeof(struct sr_dev_inst));
371         sr_dbg("Setting Device Instance Vendor: %s", model->series->vendor->name);
372         sdi->vendor = g_strdup(model->series->vendor->name);
373         sr_dbg("Setting Device Instance model: %s", model->name);
374         sdi->model = g_strdup(model->name);
375         sr_dbg("Setting Device Instance version: %s", hw_info->firmware_version);
376         sdi->version = g_strdup(hw_info->firmware_version);
377         sdi->conn = scpi;
378         sdi->driver = &siglent_sds_driver_info;
379         sr_dbg("Setting Device Instance inst_type: SCPI");
380         sdi->inst_type = SR_INST_SCPI;
381         sdi->serial_num = g_strdup(hw_info->serial_number);
382         devc = g_malloc0(sizeof(struct dev_context));
383         devc->limit_frames = 1;
384         devc->model = model;
385         sr_dbg("Setting device Context model: %s", devc->model->name);
386
387         sr_scpi_hw_info_free(hw_info);
388
389         devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group *) *
390                 model->analog_channels);
391
392         for (i = 0; i < model->analog_channels; i++) {
393                 channel_name = g_strdup_printf("CH%d", i + 1);
394                 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_name);
395
396                 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
397
398                 devc->analog_groups[i]->name = channel_name;
399                 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
400                 sdi->channel_groups = g_slist_append(sdi->channel_groups,
401                         devc->analog_groups[i]);
402         }
403
404         if (devc->model->has_digital) {
405                 devc->digital_group = g_malloc0(sizeof(struct sr_channel_group));
406
407                 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
408                         channel_name = g_strdup_printf("D%d", i);
409                         ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
410                         g_free(channel_name);
411                         devc->digital_group->channels = g_slist_append(
412                                 devc->digital_group->channels, ch);
413                 }
414                 devc->digital_group->name = g_strdup("LA");
415                 sdi->channel_groups = g_slist_append(sdi->channel_groups,
416                         devc->digital_group);
417         }
418
419         for (i = 0; i < NUM_TIMEBASE; i++) {
420                 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
421                         devc->timebases = &timebases[i];
422
423                 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
424                         devc->num_timebases = &timebases[i] - devc->timebases + 1;
425         }
426
427         for (i = 0; i < NUM_VDIV; i++) {
428                 devc->vdivs = &vdivs[i];
429                 if (!memcmp(&devc->model->series->min_vdiv,
430                         &vdivs[i], sizeof(uint64_t[2]))) {
431                         devc->vdivs = &vdivs[i];
432                         devc->num_vdivs = NUM_VDIV - i;
433                         break;
434                 }
435         }
436
437         devc->buffer = g_malloc(devc->model->series->buffer_samples);
438         sr_dbg("Setting device Context buffer Size: %i", devc->model->series->buffer_samples);
439         devc->data = g_malloc(devc->model->series->buffer_samples * sizeof(float));
440
441         devc->data_source = DATA_SOURCE_SCREEN;
442
443         sdi->priv = devc;
444
445         return sdi;
446 }
447
448 static GSList *scan(struct sr_dev_driver *di, GSList *options)
449 {
450
451         // TODO implement RPC call for LXI device discovery.
452         return sr_scpi_scan(di->context, options, probe_device);
453 }
454
455 static int dev_open(struct sr_dev_inst *sdi)
456 {
457         int ret;
458         struct sr_scpi_dev_inst *scpi = sdi->conn;
459
460         if ((ret = sr_scpi_open(scpi)) < 0) {
461                 sr_err("Failed to open SCPI device: %s.", sr_strerror(ret));
462                 return SR_ERR;
463         }
464
465         if ((ret = siglent_sds_get_dev_cfg(sdi)) < 0) {
466                 sr_err("Failed to get device config: %s.", sr_strerror(ret));
467                 return SR_ERR;
468         }
469
470         sdi->status = SR_ST_ACTIVE;
471
472         return SR_OK;
473 }
474
475 static int dev_close(struct sr_dev_inst *sdi)
476 {
477
478         return sr_scpi_close(sdi->conn);
479 }
480
481
482 static int config_get(uint32_t key, GVariant **data,
483         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
484 {
485         struct dev_context *devc;
486         struct sr_channel *ch;
487         const char *tmp_str;
488         int analog_channel = -1;
489         float smallest_diff = INFINITY;
490         int idx = -1;
491         unsigned i;
492
493         if (!sdi)
494                 return SR_ERR_ARG;
495
496         devc = sdi->priv;
497
498         /* If a channel group is specified, it must be a valid one. */
499         if (cg && !g_slist_find(sdi->channel_groups, cg)) {
500                 sr_err("Invalid channel group specified.");
501                 return SR_ERR;
502         }
503
504         if (cg) {
505                 ch = g_slist_nth_data(cg->channels, 0);
506                 if (!ch)
507                         return SR_ERR;
508                 if (ch->type == SR_CHANNEL_ANALOG) {
509                         if (ch->name[2] < '1' || ch->name[2] > '4')
510                                 return SR_ERR;
511                         analog_channel = ch->name[2] - '1';
512                 }
513         }
514
515         switch (key) {
516         case SR_CONF_NUM_HDIV:
517                 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
518                 break;
519         case SR_CONF_NUM_VDIV:
520                 *data = g_variant_new_int32(devc->num_vdivs);
521                 break;
522         case SR_CONF_LIMIT_FRAMES:
523                 *data = g_variant_new_uint64(devc->limit_frames);
524                 break;
525         case SR_CONF_DATA_SOURCE:
526                 if (devc->data_source == DATA_SOURCE_SCREEN)
527                         *data = g_variant_new_string("Screen");
528                 else if (devc->data_source == DATA_SOURCE_HISTORY)
529                         *data = g_variant_new_string("History");
530                 break;
531         case SR_CONF_SAMPLERATE:
532                 siglent_sds_get_dev_cfg_horizontal(sdi);
533                 *data = g_variant_new_uint64(devc->sampleRate);
534                 sr_dbg("Sample rate set to %f", devc->sampleRate);
535                 break;
536         case SR_CONF_TRIGGER_SOURCE:
537                 if (!strcmp(devc->trigger_source, "ACL"))
538                         tmp_str = "AC Line";
539                 else if (!strcmp(devc->trigger_source, "CHAN1"))
540                         tmp_str = "CH1";
541                 else if (!strcmp(devc->trigger_source, "CHAN2"))
542                         tmp_str = "CH2";
543                 else
544                         tmp_str = devc->trigger_source;
545                 *data = g_variant_new_string(tmp_str);
546                 break;
547         case SR_CONF_TRIGGER_SLOPE:
548                 if (!strncmp(devc->trigger_slope, "POS", 3)) {
549                         tmp_str = "r";
550                 } else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
551                         tmp_str = "f";
552                 } else {
553                         sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
554                         return SR_ERR_NA;
555                 }
556                 *data = g_variant_new_string(tmp_str);
557                 break;
558         case SR_CONF_TRIGGER_LEVEL:
559                 *data = g_variant_new_double(devc->trigger_level);
560                 break;
561         case SR_CONF_HORIZ_TRIGGERPOS:
562                 *data = g_variant_new_double(devc->horiz_triggerpos);
563                 break;
564         case SR_CONF_TIMEBASE:
565                 for (i = 0; i < devc->num_timebases; i++) {
566                         float tb, diff;
567
568                         tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
569                         diff = fabs(devc->timebase - tb);
570                         if (diff < smallest_diff) {
571                                 smallest_diff = diff;
572                                 idx = i;
573                         }
574                 }
575                 if (idx < 0) {
576                         sr_dbg("Negative timebase index: %d.", idx);
577                         return SR_ERR_NA;
578                 }
579                 *data = g_variant_new("(tt)", devc->timebases[idx][0],
580                         devc->timebases[idx][1]);
581                 break;
582         case SR_CONF_VDIV:
583                 if (analog_channel < 0) {
584                         sr_dbg("Negative analog channel: %d.", analog_channel);
585                         return SR_ERR_NA;
586                 }
587                 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
588                         float vdiv, diff;
589
590                         vdiv = (float)vdivs[i][0] / vdivs[i][1];
591                         diff = fabsf(devc->vdiv[analog_channel] - vdiv);
592                         if (diff < smallest_diff) {
593                                 smallest_diff = diff;
594                                 idx = i;
595                         }
596                 }
597                 if (idx < 0) {
598                         sr_dbg("Negative vdiv index: %d.", idx);
599                         return SR_ERR_NA;
600                 }
601                 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
602                 break;
603         case SR_CONF_COUPLING:
604                 if (analog_channel < 0) {
605                         sr_dbg("Negative analog channel: %d.", analog_channel);
606                         return SR_ERR_NA;
607                 }
608                 *data = g_variant_new_string(devc->coupling[analog_channel]);
609                 break;
610         case SR_CONF_PROBE_FACTOR:
611                 if (analog_channel < 0) {
612                         sr_dbg("Negative analog channel: %d.", analog_channel);
613                         return SR_ERR_NA;
614                 }
615                 *data = g_variant_new_uint64(devc->attenuation[analog_channel]);
616                 break;
617         default:
618                 return SR_ERR_NA;
619         }
620
621         return SR_OK;
622 }
623
624 static int config_set(uint32_t key, GVariant *data,
625         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
626 {
627         struct dev_context *devc;
628         uint64_t p, q;
629         double t_dbl;
630         unsigned int i, j;
631         int ret;
632         const char *tmp_str;
633         char buffer[16];
634
635         devc = sdi->priv;
636
637         if (sdi->status != SR_ST_ACTIVE)
638                 return SR_ERR_DEV_CLOSED;
639
640         /* If a channel group is specified, it must be a valid one. */
641         if (cg && !g_slist_find(sdi->channel_groups, cg)) {
642                 sr_err("Invalid channel group specified.");
643                 return SR_ERR;
644         }
645
646         ret = SR_OK;
647         switch (key) {
648         case SR_CONF_LIMIT_FRAMES:
649                 devc->limit_frames = g_variant_get_uint64(data);
650                 break;
651         case SR_CONF_TRIGGER_SLOPE:
652                 tmp_str = g_variant_get_string(data, NULL);
653                 g_free(devc->trigger_slope);
654                 ret = siglent_sds_config_set(sdi, "%s:TRSL %s", devc->trigger_source, devc->trigger_slope);
655                 break;
656         case SR_CONF_HORIZ_TRIGGERPOS:
657                 t_dbl = g_variant_get_double(data);
658                 if (t_dbl < 0.0 || t_dbl > 1.0) {
659                         sr_err("Invalid horiz. trigger position: %g.", t_dbl);
660                         return SR_ERR;
661                 }
662                 devc->horiz_triggerpos = t_dbl;
663                 /* We have the trigger offset as a percentage of the frame, but
664                  * need to express this in seconds. */
665                 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
666                 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
667                 ret = siglent_sds_config_set(sdi, ":TIM:OFFS %s", buffer);
668                 break;
669         case SR_CONF_TRIGGER_LEVEL:
670                 t_dbl = g_variant_get_double(data);
671                 g_ascii_formatd(buffer, sizeof(buffer), "%.3f", t_dbl);
672                 ret = siglent_sds_config_set(sdi, ":TRIG:EDGE:LEV %s", buffer);
673                 if (ret == SR_OK)
674                         devc->trigger_level = t_dbl;
675                 break;
676         case SR_CONF_TIMEBASE:
677                 sr_dbg("Setting device Timebase");
678                 g_variant_get(data, "(tt)", &p, &q);
679                 for (i = 0; i < devc->num_timebases; i++) {
680                         char *cmd;
681                         if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
682                                 cmd = "";
683                                 devc->timebase = (float) p / q;
684                                 switch (q) {
685                                 case 1:
686                                         cmd = g_strdup_printf("%luS", p);
687                                         break;
688                                 case 1000:
689                                         cmd = g_strdup_printf("%luMS", p);
690                                         break;
691                                 case 1000000:
692                                         cmd = g_strdup_printf("%luUS", p);
693                                         break;
694                                 case 100000000:
695                                         cmd = g_strdup_printf("%luNS", p);
696                                         break;
697                                 }
698                                 sr_dbg("Setting device Timebase: TDIV %s", cmd);
699                                 ret = siglent_sds_config_set(sdi, "TDIV %s", cmd);
700                                 break;
701                         }
702                 }
703                 if (i == devc->num_timebases) {
704                         sr_err("Invalid timebase index: %d.", i);
705                         ret = SR_ERR_ARG;
706                 }
707                 break;
708         case SR_CONF_TRIGGER_SOURCE:
709                 tmp_str = g_variant_get_string(data, NULL);
710                 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
711                         if (!strcmp(trigger_sources[i], tmp_str)) {
712                                 g_free(devc->trigger_source);
713                                 devc->trigger_source = g_strdup(trigger_sources[i]);
714                                 if (!strcmp(devc->trigger_source, "AC Line"))
715                                         tmp_str = "LINE";
716                                 else if (!strcmp(devc->trigger_source, "CH1"))
717                                         tmp_str = "C1";
718                                 else if (!strcmp(devc->trigger_source, "CH2"))
719                                         tmp_str = "C2";
720                                 else if (!strcmp(devc->trigger_source, "CH3"))
721                                         tmp_str = "C3";
722                                 else if (!strcmp(devc->trigger_source, "CH4"))
723                                         tmp_str = "C4";
724                                 else if (!strcmp(devc->trigger_source, "Ext"))
725                                         tmp_str = "EX";
726                                 else if (!strcmp(devc->trigger_source, "Ext /5"))
727                                         tmp_str = "EX5";
728                                 else
729                                         tmp_str = (char *) devc->trigger_source;
730                                 ret = siglent_sds_config_set(sdi, "TRSE EDGE,SR,%s,OFF", tmp_str);
731                                 break;
732                         }
733                 }
734                 if (i == ARRAY_SIZE(trigger_sources)) {
735                         sr_err("Invalid trigger source index: %d.", i);
736                         ret = SR_ERR_ARG;
737                 }
738                 break;
739         case SR_CONF_VDIV:
740                 if (!cg) {
741                         sr_err("No channel group specified.");
742                         return SR_ERR_CHANNEL_GROUP;
743                 }
744                 g_variant_get(data, "(tt)", &p, &q);
745                 for (i = 0; i < devc->model->analog_channels; i++) {
746                         char *cmd;
747                         if (cg == devc->analog_groups[i]) {
748                                 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
749                                         if (vdivs[j][0] != p || vdivs[j][1] != q)
750                                                 continue;
751                                         cmd = "";
752                                         switch (q) {
753                                         case 1:
754                                                 cmd = g_strdup_printf("%luV", p);
755                                                 break;
756                                         case 1000:
757                                                 cmd = g_strdup_printf("%luMV", p);
758                                                 break;
759                                         case 100000:
760                                                 cmd = g_strdup_printf("%luUV", p);
761                                                 break;
762                                         }
763                                         return siglent_sds_config_set(sdi, "C%d:VDIV %s", i + 1,
764                                                 cmd);
765                                 }
766                                 sr_err("Invalid vdiv index: %d.", j);
767                                 return SR_ERR_ARG;
768                         }
769                 }
770                 sr_dbg("Didn't set vdiv, unknown channel(group).");
771                 return SR_ERR_NA;
772         case SR_CONF_COUPLING:
773                 if (!cg) {
774                         sr_err("No channel group specified.");
775                         return SR_ERR_CHANNEL_GROUP;
776                 }
777                 tmp_str = g_variant_get_string(data, NULL);
778                 for (i = 0; i < devc->model->analog_channels; i++) {
779                         char cmd[4];
780                         if (cg == devc->analog_groups[i]) {
781                                 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
782                                         if (!strcmp(tmp_str, coupling[j])) {
783                                                 g_free(devc->coupling[i]);
784                                                 devc->coupling[i] = g_strdup(coupling[j]);
785                                                 strncpy(cmd, devc->coupling[i], 3);
786                                                 cmd[3] = 0;
787                                                 return siglent_sds_config_set(sdi, "C%d:CPL %s", i + 1,
788                                                         cmd);
789                                         }
790                                 }
791                                 sr_err("Invalid coupling index: %d.", j);
792                                 return SR_ERR_ARG;
793                         }
794                 }
795                 sr_dbg("Didn't set coupling, unknown channel(group).");
796                 return SR_ERR_NA;
797         case SR_CONF_PROBE_FACTOR:
798                 if (!cg) {
799                         sr_err("No channel group specified.");
800                         return SR_ERR_CHANNEL_GROUP;
801                 }
802                 p = g_variant_get_uint64(data);
803                 for (i = 0; i < devc->model->analog_channels; i++) {
804                         if (cg == devc->analog_groups[i]) {
805                                 for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
806                                         if (p == probe_factor[j]) {
807                                                 devc->attenuation[i] = p;
808                                                 ret = siglent_sds_config_set(sdi, "C%d:ATTN %"PRIu64,
809                                                         i + 1, p);
810                                                 if (ret == SR_OK)
811                                                         siglent_sds_get_dev_cfg_vertical(sdi);
812                                                 return ret;
813                                         }
814                                 }
815                                 sr_err("Invalid probe factor: %"PRIu64".", p);
816                                 return SR_ERR_ARG;
817                         }
818                 }
819                 sr_dbg("Didn't set probe factor, unknown channel(group).");
820                 return SR_ERR_NA;
821         case SR_CONF_DATA_SOURCE:
822                 tmp_str = g_variant_get_string(data, NULL);
823                 if (!strcmp(tmp_str, "Display"))
824                         devc->data_source = DATA_SOURCE_SCREEN;
825                 else if (devc->model->series->protocol >= SPO_MODEL
826                         && !strcmp(tmp_str, "History"))
827                         devc->data_source = DATA_SOURCE_HISTORY;
828                 else {
829                         sr_err("Unknown data source: '%s'.", tmp_str);
830                         return SR_ERR;
831                 }
832                 break;
833         case SR_CONF_SAMPLERATE:
834                 siglent_sds_get_dev_cfg_horizontal(sdi);
835                 data = g_variant_new_uint64(devc->sampleRate);
836                 break;
837         default:
838                 return SR_ERR_NA;
839         }
840
841         return ret;
842 }
843
844 static int config_list(uint32_t key, GVariant **data,
845         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
846 {
847         GVariant *tuple, *rational[2];
848         GVariantBuilder gvb;
849         unsigned int i;
850         struct dev_context *devc = NULL;
851
852         if (key == SR_CONF_SCAN_OPTIONS) {
853                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
854                         scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
855                 return SR_OK;
856         } else if (key == SR_CONF_DEVICE_OPTIONS && !cg) {
857                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
858                         devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
859                 return SR_OK;
860         }
861
862         /* Every other option requires a valid device instance. */
863         if (!sdi)
864                 return SR_ERR_ARG;
865         devc = sdi->priv;
866
867         /* If a channel group is specified, it must be a valid one. */
868         if (cg && !g_slist_find(sdi->channel_groups, cg)) {
869                 sr_err("Invalid channel group specified.");
870                 return SR_ERR;
871         }
872
873         switch (key) {
874         case SR_CONF_DEVICE_OPTIONS:
875                 if (!cg) {
876                         sr_err("No channel group specified.");
877                         return SR_ERR_CHANNEL_GROUP;
878                 }
879                 if (cg == devc->digital_group) {
880                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
881                                 NULL, 0, sizeof(uint32_t));
882                         return SR_OK;
883                 } else {
884                         for (i = 0; i < devc->model->analog_channels; i++) {
885                                 if (cg == devc->analog_groups[i]) {
886                                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
887                                                 analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
888                                         return SR_OK;
889                                 }
890                         }
891                         return SR_ERR_NA;
892                 }
893                 break;
894         case SR_CONF_COUPLING:
895                 if (!cg) {
896                         sr_err("No channel group specified.");
897                         return SR_ERR_CHANNEL_GROUP;
898                 }
899                 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
900                 break;
901         case SR_CONF_PROBE_FACTOR:
902                 if (!cg) {
903                         sr_err("No channel group specified.");
904                         return SR_ERR_CHANNEL_GROUP;
905                 }
906                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
907                         probe_factor, ARRAY_SIZE(probe_factor), sizeof(uint64_t));
908                 break;
909         case SR_CONF_VDIV:
910                 if (!devc)
911                         /* Can't know this until we have the exact model. */
912                         return SR_ERR_ARG;
913                 if (!cg) {
914                         sr_err("No channel group specified.");
915                         return SR_ERR_CHANNEL_GROUP;
916                 }
917                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
918                 for (i = 0; i < devc->num_vdivs; i++) {
919                         rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
920                         rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
921                         tuple = g_variant_new_tuple(rational, 2);
922                         g_variant_builder_add_value(&gvb, tuple);
923                 }
924                 *data = g_variant_builder_end(&gvb);
925                 break;
926         case SR_CONF_TIMEBASE:
927                 if (!devc)
928                         /* Can't know this until we have the exact model. */
929                         return SR_ERR_ARG;
930                 if (devc->num_timebases <= 0)
931                         return SR_ERR_NA;
932                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
933                 for (i = 0; i < devc->num_timebases; i++) {
934                         rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
935                         rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
936                         tuple = g_variant_new_tuple(rational, 2);
937                         g_variant_builder_add_value(&gvb, tuple);
938                 }
939                 *data = g_variant_builder_end(&gvb);
940                 break;
941         case SR_CONF_TRIGGER_SOURCE:
942                 if (!devc)
943                         /* Can't know this until we have the exact model. */
944                         return SR_ERR_ARG;
945                 *data = g_variant_new_strv(trigger_sources,
946                         devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 5);
947                 break;
948         case SR_CONF_TRIGGER_SLOPE:
949                 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
950                 break;
951         case SR_CONF_DATA_SOURCE:
952                 if (!devc)
953                         /* Can't know this until we have the exact model. */
954                         return SR_ERR_ARG;
955                 switch (devc->model->series->protocol) {
956                 // TODO check what must be done here for the data source buffer sizes
957                 case NON_SPO_MODEL:
958                         *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
959                         break;
960                 case SPO_MODEL:
961                         *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
962                         break;
963                 }
964                 break;
965         case SR_CONF_NUM_HDIV:
966                 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
967                 break;
968         case SR_CONF_AVERAGING:
969                 //TODO implement averaging.
970                 break;
971         default:
972                 return SR_ERR_NA;
973         }
974
975         return SR_OK;
976 }
977
978 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
979 {
980         struct sr_scpi_dev_inst *scpi;
981         struct dev_context *devc;
982         struct sr_channel *ch;
983         struct sr_datafeed_packet packet;
984         gboolean some_digital;
985         GSList *l;
986         GSList *d;
987
988         if (sdi->status != SR_ST_ACTIVE)
989                 return SR_ERR_DEV_CLOSED;
990
991         scpi = sdi->conn;
992         devc = sdi->priv;
993
994         devc->num_frames = 0;
995         some_digital = FALSE;
996
997         /* Check if there are any logic channels enabled, if so then enable de MSO, otherwise skip the digital channel setup */
998         /* enable and disable channels on the device is very slow and it is faster when checked in a small loop without the actual actions */
999         for (d = sdi->channels; d; d = d->next) {
1000                 ch = d->data;
1001                 if (ch->type == SR_CHANNEL_LOGIC && ch->enabled) {
1002                         some_digital = TRUE;
1003                 }
1004         }
1005
1006         for (l = sdi->channels; l; l = l->next) {
1007                 ch = l->data;
1008                 sr_dbg("handling channel %s", ch->name);
1009                 if (ch->type == SR_CHANNEL_ANALOG) {
1010                         if (ch->enabled)
1011                                 devc->enabled_channels = g_slist_append(
1012                                         devc->enabled_channels, ch);
1013                         if (ch->enabled != devc->analog_channels[ch->index]) {
1014                                 /* Enabled channel is currently disabled, or vice versa. */
1015                                 if (siglent_sds_config_set(sdi, "C%d:TRA %s", ch->index + 1,
1016                                         ch->enabled ? "ON" : "OFF") != SR_OK)
1017                                         return SR_ERR;
1018                                 devc->analog_channels[ch->index] = ch->enabled;
1019                         }
1020                 } else if (ch->type == SR_CHANNEL_LOGIC && some_digital) {
1021                         if (ch->enabled) {
1022                                 /* Turn on LA module if currently off and digital channels are enabled. */
1023                                 if (!devc->la_enabled) {
1024                                         if (siglent_sds_config_set(sdi, "DGST ON") != SR_OK)
1025                                                 return SR_ERR;
1026                                         g_usleep(630000);
1027                                         devc->la_enabled = TRUE;
1028                                 }
1029                                 devc->enabled_channels = g_slist_append(
1030                                         devc->enabled_channels, ch);
1031                         }
1032                         /* Enabled channel is currently disabled, or vice versa. */
1033                         if (siglent_sds_config_set(sdi, "D%d:DGCH %s", ch->index,
1034                                 ch->enabled ? "ON" : "OFF") != SR_OK)
1035                                 return SR_ERR;
1036                         /* Slowing the command sequence down to let the device handle it */
1037                         g_usleep(630000);
1038                         devc->digital_channels[ch->index] = ch->enabled;
1039                 }
1040         }
1041         if (!devc->enabled_channels)
1042                 return SR_ERR;
1043         /* Turn off LA module if on and no digital channels selected. */
1044         if (devc->la_enabled && !some_digital)
1045                 if (siglent_sds_config_set(sdi, "DGST OFF") != SR_OK) {
1046                         devc->la_enabled = FALSE;
1047                         g_usleep(500000);
1048                         return SR_ERR;
1049                 }
1050
1051         // devc->analog_frame_size = devc->model->series->buffer_samples;
1052         // devc->digital_frame_size = devc->model->series->buffer_samples;
1053
1054         switch (devc->model->series->protocol) {
1055         case SPO_MODEL:
1056                 if (siglent_sds_config_set(sdi, "WFSU SP,0,TYPE,1") != SR_OK)
1057                         return SR_ERR;
1058                 if (siglent_sds_config_set(sdi, "ACQW SAMPLING") != SR_OK)
1059                         return SR_ERR;
1060                 break;
1061         case NON_SPO_MODEL:
1062                 //TODO implement CML/CNL/DL models
1063                 if (siglent_sds_config_set(sdi, "WFSU SP,0,TYPE,1") != SR_OK)
1064                         return SR_ERR;
1065                 if (siglent_sds_config_set(sdi, "ACQW SAMPLING") != SR_OK)
1066                         return SR_ERR;
1067                 break;
1068         default:
1069                 break;
1070         }
1071
1072         sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1073                 siglent_sds_receive, (void *) sdi);
1074
1075         std_session_send_df_header(sdi);
1076
1077         devc->channel_entry = devc->enabled_channels;
1078
1079         if (siglent_sds_capture_start(sdi) != SR_OK)
1080                 return SR_ERR;
1081
1082         /* Start of first frame. */
1083         packet.type = SR_DF_FRAME_BEGIN;
1084         sr_session_send(sdi, &packet);
1085
1086         return SR_OK;
1087 }
1088
1089 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
1090 {
1091         struct dev_context *devc;
1092         struct sr_scpi_dev_inst *scpi;
1093
1094         devc = sdi->priv;
1095
1096         if (sdi->status != SR_ST_ACTIVE) {
1097                 sr_err("Device inactive, can't stop acquisition.");
1098                 return SR_ERR;
1099         }
1100
1101         std_session_send_df_end(sdi);
1102
1103         g_slist_free(devc->enabled_channels);
1104         devc->enabled_channels = NULL;
1105         scpi = sdi->conn;
1106         sr_scpi_source_remove(sdi->session, scpi);
1107
1108         return SR_OK;
1109 }
1110
1111 SR_PRIV struct sr_dev_driver siglent_sds_driver_info = {
1112         .name = "siglent-sds",
1113         .longname = "Siglent SDS1000/SDS2000 Series",
1114         .api_version = 1,
1115         .init = std_init,
1116         .cleanup = std_cleanup,
1117         .scan = scan,
1118         .dev_list = std_dev_list,
1119         .dev_clear = dev_clear,
1120         .config_get = config_get,
1121         .config_set = config_set,
1122         .config_list = config_list,
1123         .dev_open = dev_open,
1124         .dev_close = dev_close,
1125         .dev_acquisition_start = dev_acquisition_start,
1126         .dev_acquisition_stop = dev_acquisition_stop,
1127         .context = NULL,
1128 };
1129
1130 SR_REGISTER_DEV_DRIVER(siglent_sds_driver_info);