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