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