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