]> sigrok.org Git - libsigrok.git/blame - src/hardware/siglent-sds/api.c
hantek-4032l: Minor cosmetics.
[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>
b3360671 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"
89f5fab9 32#include "protocol.h"
b3360671 33#include "scpi.h"
89f5fab9 34
b3360671 35static const uint32_t scanopts[] = {
36 SR_CONF_CONN,
37 SR_CONF_SERIALCOMM
38};
39
40static 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
56static 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
65static 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
105static 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
131static 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
155static const char *trigger_slopes[] = {
156 "Rising",
157 "Falling",
158};
159
160static 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
168static 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 */
185static const char *data_sources[] = {
186 "Display",
187 "History",
188};
189
190enum vendor {
191 SIGLENT,
192};
193
194enum series {
195 SDS1000CML,
196 SDS1000CNL,
197 SDS1000DL,
198 SDS1000X,
199 SDS1000XP,
200 SDS1000XE,
201 SDS2000X,
202};
203
204/* short name, full name, USB Name */
205static 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 */
214static 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 */
254static 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
307SR_PRIV struct sr_dev_driver siglent_sds_driver_info;
308
309static 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
320static int dev_clear(const struct sr_dev_driver *di)
321{
322
323 return std_dev_clear_with_callback(di, clear_helper);
324}
325
326static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
89f5fab9 327{
b3360671 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...");
89f5fab9 337
b3360671 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;
89f5fab9 342
b3360671 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 }
89f5fab9 360
b3360671 361 sr_info("Decoded Manufacturer: %s", hw_info->manufacturer);
362 sr_info("Decoded Model: %s", hw_info->model);
89f5fab9 363
b3360671 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
447static 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);
89f5fab9 452}
453
454static int dev_open(struct sr_dev_inst *sdi)
455{
b3360671 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 }
89f5fab9 463
b3360671 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;
89f5fab9 470
471 return SR_OK;
472}
473
474static int dev_close(struct sr_dev_inst *sdi)
475{
89f5fab9 476
b3360671 477 return sr_scpi_close(sdi->conn);
89f5fab9 478}
479
b3360671 480
89f5fab9 481static int config_get(uint32_t key, GVariant **data,
482 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
483{
b3360671 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;
89f5fab9 491
b3360671 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 }
89f5fab9 513
89f5fab9 514 switch (key) {
b3360671 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;
89f5fab9 616 default:
617 return SR_ERR_NA;
618 }
619
b3360671 620 return SR_OK;
89f5fab9 621}
622
623static int config_set(uint32_t key, GVariant *data,
624 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
625{
b3360671 626 struct dev_context *devc;
627 uint64_t p, q;
628 double t_dbl;
629 unsigned int i, j;
89f5fab9 630 int ret;
b3360671 631 const char *tmp_str;
632 char buffer[16];
89f5fab9 633
b3360671 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 }
89f5fab9 644
645 ret = SR_OK;
646 switch (key) {
b3360671 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;
89f5fab9 836 default:
b3360671 837 return SR_ERR_NA;
89f5fab9 838 }
839
840 return ret;
841}
842
843static int config_list(uint32_t key, GVariant **data,
844 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
845{
b3360671 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 }
89f5fab9 860
b3360671 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 }
89f5fab9 871
89f5fab9 872 switch (key) {
b3360671 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;
89f5fab9 970 default:
971 return SR_ERR_NA;
972 }
973
b3360671 974 return SR_OK;
89f5fab9 975}
976
977static int dev_acquisition_start(const struct sr_dev_inst *sdi)
978{
b3360671 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;
89f5fab9 986
b3360671 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);
89f5fab9 1084
1085 return SR_OK;
1086}
1087
1088static int dev_acquisition_stop(struct sr_dev_inst *sdi)
1089{
b3360671 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);
89f5fab9 1101
b3360671 1102 g_slist_free(devc->enabled_channels);
1103 devc->enabled_channels = NULL;
1104 scpi = sdi->conn;
1105 sr_scpi_source_remove(sdi->session, scpi);
89f5fab9 1106
1107 return SR_OK;
1108}
1109
1110SR_PRIV struct sr_dev_driver siglent_sds_driver_info = {
1111 .name = "siglent-sds",
b3360671 1112 .longname = "Siglent SDS1000/SDS2000 Series",
89f5fab9 1113 .api_version = 1,
1114 .init = std_init,
1115 .cleanup = std_cleanup,
1116 .scan = scan,
1117 .dev_list = std_dev_list,
b3360671 1118 .dev_clear = dev_clear,
89f5fab9 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
1129SR_REGISTER_DEV_DRIVER(siglent_sds_driver_info);