]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/rigol-ds/api.c
scpi: Strip trailing newline from *IDN response if present.
[libsigrok.git] / hardware / rigol-ds / api.c
... / ...
CommitLineData
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 * Copyright (C) 2013 Mathias Grimmberger <mgri@zaphod.sax.de>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
26#include <glib.h>
27#include "libsigrok.h"
28#include "libsigrok-internal.h"
29#include "protocol.h"
30
31static const int32_t hwopts[] = {
32 SR_CONF_CONN,
33 SR_CONF_SERIALCOMM
34};
35
36static const int32_t hwcaps[] = {
37 SR_CONF_OSCILLOSCOPE,
38 SR_CONF_TIMEBASE,
39 SR_CONF_TRIGGER_SOURCE,
40 SR_CONF_TRIGGER_SLOPE,
41 SR_CONF_HORIZ_TRIGGERPOS,
42 SR_CONF_NUM_TIMEBASE,
43};
44
45static const int32_t analog_hwcaps[] = {
46 SR_CONF_NUM_VDIV,
47 SR_CONF_VDIV,
48 SR_CONF_COUPLING,
49 SR_CONF_DATA_SOURCE,
50};
51
52static const uint64_t timebases[][2] = {
53 /* nanoseconds */
54 { 2, 1000000000 },
55 { 5, 1000000000 },
56 { 10, 1000000000 },
57 { 20, 1000000000 },
58 { 50, 1000000000 },
59 { 100, 1000000000 },
60 { 500, 1000000000 },
61 /* microseconds */
62 { 1, 1000000 },
63 { 2, 1000000 },
64 { 5, 1000000 },
65 { 10, 1000000 },
66 { 20, 1000000 },
67 { 50, 1000000 },
68 { 100, 1000000 },
69 { 200, 1000000 },
70 { 500, 1000000 },
71 /* milliseconds */
72 { 1, 1000 },
73 { 2, 1000 },
74 { 5, 1000 },
75 { 10, 1000 },
76 { 20, 1000 },
77 { 50, 1000 },
78 { 100, 1000 },
79 { 200, 1000 },
80 { 500, 1000 },
81 /* seconds */
82 { 1, 1 },
83 { 2, 1 },
84 { 5, 1 },
85 { 10, 1 },
86 { 20, 1 },
87 { 50, 1 },
88 { 100, 1 },
89 { 200, 1 },
90 { 500, 1 },
91 /* { 1000, 1 }, Confuses other code? */
92};
93
94static const uint64_t vdivs[][2] = {
95 /* microvolts */
96 { 500, 1000000 },
97 /* millivolts */
98 { 1, 1000 },
99 { 2, 1000 },
100 { 5, 1000 },
101 { 10, 1000 },
102 { 20, 1000 },
103 { 50, 1000 },
104 { 100, 1000 },
105 { 200, 1000 },
106 { 500, 1000 },
107 /* volts */
108 { 1, 1 },
109 { 2, 1 },
110 { 5, 1 },
111 { 10, 1 },
112};
113
114#define NUM_TIMEBASE ARRAY_SIZE(timebases)
115#define NUM_VDIV ARRAY_SIZE(vdivs)
116
117static const char *trigger_sources[] = {
118 "CH1",
119 "CH2",
120 "CH3",
121 "CH4",
122 "EXT",
123 "AC Line",
124 "D0",
125 "D1",
126 "D2",
127 "D3",
128 "D4",
129 "D5",
130 "D6",
131 "D7",
132 "D8",
133 "D9",
134 "D10",
135 "D11",
136 "D12",
137 "D13",
138 "D14",
139 "D15",
140};
141
142static const char *coupling[] = {
143 "AC",
144 "DC",
145 "GND",
146};
147
148/* Do not change the order of entries */
149static const char *data_sources[] = {
150 "Live",
151 "Memory",
152 "Segmented",
153};
154
155/*
156 * name, series, protocol flavor, min timebase, max timebase, min vdiv,
157 * digital channels, number of horizontal divs
158 */
159
160#define RIGOL "Rigol Technologies"
161#define AGILENT "Agilent Technologies"
162
163static const struct rigol_ds_model supported_models[] = {
164 {RIGOL, "DS1052E", RIGOL_DS1000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
165 {RIGOL, "DS1102E", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
166 {RIGOL, "DS1152E", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
167 {RIGOL, "DS1052D", RIGOL_DS1000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
168 {RIGOL, "DS1102D", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
169 {RIGOL, "DS1152D", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
170 {RIGOL, "DS2072", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
171 {RIGOL, "DS2102", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
172 {RIGOL, "DS2202", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
173 {RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
174 {RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
175 {RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
176 {RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
177 {RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
178 {RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
179 {RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
180 {RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
181 {RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
182 {RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
183 {AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
184 {AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
185 {AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
186 {AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
187 {AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
188 {AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
189};
190
191SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
192static struct sr_dev_driver *di = &rigol_ds_driver_info;
193
194static void clear_helper(void *priv)
195{
196 struct dev_context *devc;
197
198 devc = priv;
199 g_free(devc->data);
200 g_free(devc->buffer);
201 g_free(devc->coupling[0]);
202 g_free(devc->coupling[1]);
203 g_free(devc->trigger_source);
204 g_free(devc->trigger_slope);
205 g_slist_free(devc->analog_groups[0].probes);
206 g_slist_free(devc->analog_groups[1].probes);
207 g_slist_free(devc->digital_group.probes);
208}
209
210static int dev_clear(void)
211{
212 return std_dev_clear(di, clear_helper);
213}
214
215static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
216{
217 va_list args;
218 int ret;
219
220 va_start(args, format);
221 ret = sr_scpi_send_variadic(sdi->conn, format, args);
222 va_end(args);
223
224 if (ret != SR_OK)
225 return SR_ERR;
226
227 /* When setting a bunch of parameters in a row, the DS1052E scrambles
228 * some of them unless there is at least 100ms delay in between. */
229 sr_spew("delay %dms", 100);
230 g_usleep(100000);
231
232 return SR_OK;
233}
234
235static int init(struct sr_context *sr_ctx)
236{
237 return std_init(sr_ctx, di, LOG_PREFIX);
238}
239
240static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
241{
242 struct dev_context *devc;
243 struct sr_dev_inst *sdi;
244 const char *usbtmc_prefix = "/dev/usbtmc";
245 const char *tcp_prefix = "tcp/";
246 gchar **tokens, *address, *port;
247 struct sr_scpi_dev_inst *scpi;
248 struct sr_scpi_hw_info *hw_info;
249 struct sr_probe *probe;
250 unsigned int i;
251 const struct rigol_ds_model *model = NULL;
252 gchar *channel_name;
253
254 *devices = NULL;
255
256 if (strncmp(resource, usbtmc_prefix, strlen(usbtmc_prefix)) == 0) {
257 sr_dbg("Opening USBTMC device %s.", resource);
258 if (!(scpi = scpi_usbtmc_dev_inst_new(resource)))
259 return SR_ERR_MALLOC;
260 } else if (strncmp(resource, tcp_prefix, strlen(tcp_prefix)) == 0) {
261 sr_dbg("Opening TCP connection %s.", resource);
262 tokens = g_strsplit(resource + strlen(tcp_prefix), "/", 0);
263 address = tokens[0];
264 port = tokens[1];
265 if (!address || !port || tokens[2]) {
266 sr_err("Invalid parameters.");
267 g_strfreev(tokens);
268 return SR_ERR_ARG;
269 }
270 scpi = scpi_tcp_dev_inst_new(address, port);
271 g_strfreev(tokens);
272 if (!scpi)
273 return SR_ERR_MALLOC;
274 } else {
275 sr_dbg("Opening serial device %s.", resource);
276 if (!(scpi = scpi_serial_dev_inst_new(resource, serialcomm)))
277 return SR_ERR_MALLOC;
278 }
279
280 if (sr_scpi_open(scpi) != SR_OK) {
281 sr_info("Couldn't open SCPI device.");
282 sr_scpi_free(scpi);
283 return SR_ERR;
284 };
285
286 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
287 sr_info("Couldn't get IDN response.");
288 sr_scpi_close(scpi);
289 sr_scpi_free(scpi);
290 return SR_ERR;
291 }
292
293 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
294 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
295 !strcmp(hw_info->model, supported_models[i].name)) {
296 model = &supported_models[i];
297 break;
298 }
299 }
300
301 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
302 hw_info->manufacturer, hw_info->model,
303 hw_info->firmware_version))) {
304 sr_scpi_hw_info_free(hw_info);
305 sr_scpi_close(scpi);
306 sr_scpi_free(scpi);
307 return SR_ERR_NA;
308 }
309
310 sr_scpi_hw_info_free(hw_info);
311 sr_scpi_close(scpi);
312
313 sdi->conn = scpi;
314
315 sdi->driver = di;
316 sdi->inst_type = SR_INST_SCPI;
317
318 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
319 return SR_ERR_MALLOC;
320
321 devc->limit_frames = 0;
322 devc->model = model;
323
324 for (i = 0; i < model->analog_channels; i++) {
325 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
326 return SR_ERR_MALLOC;
327 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
328 sdi->probes = g_slist_append(sdi->probes, probe);
329 devc->analog_groups[i].name = channel_name;
330 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
331 sdi->probe_groups = g_slist_append(sdi->probe_groups,
332 &devc->analog_groups[i]);
333 }
334
335 if (devc->model->has_digital) {
336 for (i = 0; i < 16; i++) {
337 if (!(channel_name = g_strdup_printf("D%d", i)))
338 return SR_ERR_MALLOC;
339 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
340 g_free(channel_name);
341 if (!probe)
342 return SR_ERR_MALLOC;
343 sdi->probes = g_slist_append(sdi->probes, probe);
344 devc->digital_group.probes = g_slist_append(
345 devc->digital_group.probes, probe);
346 }
347 devc->digital_group.name = "LA";
348 sdi->probe_groups = g_slist_append(sdi->probe_groups,
349 &devc->digital_group);
350 }
351
352 for (i = 0; i < NUM_TIMEBASE; i++) {
353 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
354 devc->timebases = &timebases[i];
355 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
356 devc->num_timebases = &timebases[i] - devc->timebases + 1;
357 }
358
359 for (i = 0; i < NUM_VDIV; i++) {
360 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2]))) {
361 devc->vdivs = &vdivs[i];
362 devc->num_vdivs = NUM_VDIV - (&vdivs[i] - &vdivs[0]);
363 }
364 }
365
366 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
367 return SR_ERR_MALLOC;
368 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
369 return SR_ERR_MALLOC;
370
371 devc->data_source = DATA_SOURCE_LIVE;
372
373 sdi->priv = devc;
374
375 *devices = g_slist_append(NULL, sdi);
376
377 return SR_OK;
378}
379
380static GSList *scan(GSList *options)
381{
382 struct drv_context *drvc;
383 struct sr_config *src;
384 GSList *l, *devices;
385 GDir *dir;
386 int ret;
387 const gchar *dev_name;
388 gchar *port = NULL;
389 gchar *serialcomm = NULL;
390
391 drvc = di->priv;
392
393 for (l = options; l; l = l->next) {
394 src = l->data;
395 switch (src->key) {
396 case SR_CONF_CONN:
397 port = (char *)g_variant_get_string(src->data, NULL);
398 break;
399 case SR_CONF_SERIALCOMM:
400 serialcomm = (char *)g_variant_get_string(src->data, NULL);
401 break;
402 }
403 }
404
405 devices = NULL;
406 if (port) {
407 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
408 g_free(port);
409 if (serialcomm)
410 g_free(serialcomm);
411 return NULL;
412 }
413 } else {
414 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
415 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
416 return NULL;
417 while ((dev_name = g_dir_read_name(dir))) {
418 if (strncmp(dev_name, "usbtmc", 6))
419 continue;
420 port = g_strconcat("/dev/", dev_name, NULL);
421 ret = probe_port(port, serialcomm, &devices);
422 g_free(port);
423 if (serialcomm)
424 g_free(serialcomm);
425 if (ret == SR_ERR_MALLOC) {
426 g_dir_close(dir);
427 return NULL;
428 }
429 }
430 g_dir_close(dir);
431 }
432
433 /* Tack a copy of the newly found devices onto the driver list. */
434 l = g_slist_copy(devices);
435 drvc->instances = g_slist_concat(drvc->instances, l);
436
437 return devices;
438}
439
440static GSList *dev_list(void)
441{
442 return ((struct drv_context *)(di->priv))->instances;
443}
444
445static int dev_open(struct sr_dev_inst *sdi)
446{
447 struct sr_scpi_dev_inst *scpi = sdi->conn;
448
449 if (sr_scpi_open(scpi) < 0)
450 return SR_ERR;
451
452 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
453 return SR_ERR;
454
455 sdi->status = SR_ST_ACTIVE;
456
457 return SR_OK;
458}
459
460static int dev_close(struct sr_dev_inst *sdi)
461{
462 struct sr_scpi_dev_inst *scpi;
463
464 scpi = sdi->conn;
465
466 if (scpi) {
467 if (sr_scpi_close(scpi) < 0)
468 return SR_ERR;
469 sdi->status = SR_ST_INACTIVE;
470 }
471
472 return SR_OK;
473}
474
475static int cleanup(void)
476{
477 return dev_clear();
478}
479
480static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
481 const struct sr_probe_group *probe_group)
482{
483 struct dev_context *devc;
484 unsigned int i;
485
486 if (!sdi || !(devc = sdi->priv))
487 return SR_ERR_ARG;
488
489 /* If a probe group is specified, it must be a valid one. */
490 if (probe_group) {
491 if (probe_group != &devc->analog_groups[0]
492 && probe_group != &devc->analog_groups[1]) {
493 sr_err("Invalid probe group specified.");
494 return SR_ERR;
495 }
496 }
497
498 switch (id) {
499 case SR_CONF_NUM_TIMEBASE:
500 *data = g_variant_new_int32(devc->num_timebases);
501 break;
502 case SR_CONF_NUM_VDIV:
503 if (!probe_group) {
504 sr_err("No probe group specified.");
505 return SR_ERR_PROBE_GROUP;
506 }
507 for (i = 0; i < 2; i++) {
508 if (probe_group == &devc->analog_groups[i]) {
509 *data = g_variant_new_int32(devc->num_vdivs);
510 return SR_OK;
511 }
512 }
513 return SR_ERR_NA;
514 case SR_CONF_DATA_SOURCE:
515 if (devc->data_source == DATA_SOURCE_LIVE)
516 *data = g_variant_new_string("Live");
517 else if (devc->data_source == DATA_SOURCE_MEMORY)
518 *data = g_variant_new_string("Memory");
519 else
520 *data = g_variant_new_string("Segmented");
521 break;
522 default:
523 return SR_ERR_NA;
524 }
525
526 return SR_OK;
527}
528
529static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
530 const struct sr_probe_group *probe_group)
531{
532 struct dev_context *devc;
533 uint64_t tmp_u64, p, q;
534 double t_dbl;
535 unsigned int i, j;
536 int ret;
537 const char *tmp_str;
538
539 if (!(devc = sdi->priv))
540 return SR_ERR_ARG;
541
542 if (sdi->status != SR_ST_ACTIVE)
543 return SR_ERR_DEV_CLOSED;
544
545 /* If a probe group is specified, it must be a valid one. */
546 if (probe_group) {
547 if (probe_group != &devc->analog_groups[0]
548 && probe_group != &devc->analog_groups[1]) {
549 sr_err("Invalid probe group specified.");
550 return SR_ERR;
551 }
552 }
553
554 ret = SR_OK;
555 switch (id) {
556 case SR_CONF_LIMIT_FRAMES:
557 devc->limit_frames = g_variant_get_uint64(data);
558 break;
559 case SR_CONF_TRIGGER_SLOPE:
560 tmp_u64 = g_variant_get_uint64(data);
561 if (tmp_u64 != 0 && tmp_u64 != 1)
562 return SR_ERR;
563 g_free(devc->trigger_slope);
564 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
565 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
566 break;
567 case SR_CONF_HORIZ_TRIGGERPOS:
568 t_dbl = g_variant_get_double(data);
569 if (t_dbl < 0.0 || t_dbl > 1.0)
570 return SR_ERR;
571 devc->horiz_triggerpos = t_dbl;
572 /* We have the trigger offset as a percentage of the frame, but
573 * need to express this in seconds. */
574 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
575 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
576 break;
577 case SR_CONF_TIMEBASE:
578 g_variant_get(data, "(tt)", &p, &q);
579 for (i = 0; i < devc->num_timebases; i++) {
580 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
581 devc->timebase = (float)p / q;
582 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
583 break;
584 }
585 }
586 if (i == devc->num_timebases)
587 ret = SR_ERR_ARG;
588 break;
589 case SR_CONF_TRIGGER_SOURCE:
590 tmp_str = g_variant_get_string(data, NULL);
591 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
592 if (!strcmp(trigger_sources[i], tmp_str)) {
593 g_free(devc->trigger_source);
594 devc->trigger_source = g_strdup(trigger_sources[i]);
595 if (!strcmp(devc->trigger_source, "AC Line"))
596 tmp_str = "ACL";
597 else if (!strcmp(devc->trigger_source, "CH1"))
598 tmp_str = "CHAN1";
599 else if (!strcmp(devc->trigger_source, "CH2"))
600 tmp_str = "CHAN2";
601 else if (!strcmp(devc->trigger_source, "CH3"))
602 tmp_str = "CHAN3";
603 else if (!strcmp(devc->trigger_source, "CH4"))
604 tmp_str = "CHAN4";
605 else
606 tmp_str = (char *)devc->trigger_source;
607 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
608 break;
609 }
610 }
611 if (i == ARRAY_SIZE(trigger_sources))
612 ret = SR_ERR_ARG;
613 break;
614 case SR_CONF_VDIV:
615 if (!probe_group) {
616 sr_err("No probe group specified.");
617 return SR_ERR_PROBE_GROUP;
618 }
619 g_variant_get(data, "(tt)", &p, &q);
620 for (i = 0; i < 2; i++) {
621 if (probe_group == &devc->analog_groups[i]) {
622 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
623 if (vdivs[j][0] != p || vdivs[j][1] != q)
624 continue;
625 devc->vdiv[i] = (float)p / q;
626 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
627 devc->vdiv[i]);
628 }
629 return SR_ERR_ARG;
630 }
631 }
632 return SR_ERR_NA;
633 case SR_CONF_COUPLING:
634 if (!probe_group) {
635 sr_err("No probe group specified.");
636 return SR_ERR_PROBE_GROUP;
637 }
638 tmp_str = g_variant_get_string(data, NULL);
639 for (i = 0; i < 2; i++) {
640 if (probe_group == &devc->analog_groups[i]) {
641 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
642 if (!strcmp(tmp_str, coupling[j])) {
643 g_free(devc->coupling[i]);
644 devc->coupling[i] = g_strdup(coupling[j]);
645 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
646 devc->coupling[i]);
647 }
648 }
649 return SR_ERR_ARG;
650 }
651 }
652 return SR_ERR_NA;
653 case SR_CONF_DATA_SOURCE:
654 tmp_str = g_variant_get_string(data, NULL);
655 if (!strcmp(tmp_str, "Live"))
656 devc->data_source = DATA_SOURCE_LIVE;
657 else if (!strcmp(tmp_str, "Memory"))
658 devc->data_source = DATA_SOURCE_MEMORY;
659 else if (devc->model->protocol == PROTOCOL_IEEE488_2
660 && !strcmp(tmp_str, "Segmented"))
661 devc->data_source = DATA_SOURCE_SEGMENTED;
662 else
663 return SR_ERR;
664 break;
665 default:
666 ret = SR_ERR_NA;
667 break;
668 }
669
670 return ret;
671}
672
673static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
674 const struct sr_probe_group *probe_group)
675{
676 GVariant *tuple, *rational[2];
677 GVariantBuilder gvb;
678 unsigned int i;
679 struct dev_context *devc = NULL;
680
681 if (sdi)
682 devc = sdi->priv;
683
684 if (key == SR_CONF_SCAN_OPTIONS) {
685 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
686 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
687 return SR_OK;
688 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
689 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
690 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
691 return SR_OK;
692 }
693
694 /* Every other option requires a valid device instance. */
695 if (!sdi || !(devc = sdi->priv))
696 return SR_ERR_ARG;
697
698 /* If a probe group is specified, it must be a valid one. */
699 if (probe_group) {
700 if (probe_group != &devc->analog_groups[0]
701 && probe_group != &devc->analog_groups[1]) {
702 sr_err("Invalid probe group specified.");
703 return SR_ERR;
704 }
705 }
706
707 switch (key) {
708 break;
709 case SR_CONF_DEVICE_OPTIONS:
710 if (!probe_group) {
711 sr_err("No probe group specified.");
712 return SR_ERR_PROBE_GROUP;
713 }
714 if (probe_group == &devc->digital_group) {
715 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
716 NULL, 0, sizeof(int32_t));
717 return SR_OK;
718 } else {
719 for (i = 0; i < 2; i++) {
720 if (probe_group == &devc->analog_groups[i]) {
721 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
722 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
723 return SR_OK;
724 }
725 }
726 return SR_ERR_NA;
727 }
728 break;
729 case SR_CONF_COUPLING:
730 if (!probe_group) {
731 sr_err("No probe group specified.");
732 return SR_ERR_PROBE_GROUP;
733 }
734 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
735 break;
736 case SR_CONF_VDIV:
737 if (!devc)
738 /* Can't know this until we have the exact model. */
739 return SR_ERR_ARG;
740 if (!probe_group) {
741 sr_err("No probe group specified.");
742 return SR_ERR_PROBE_GROUP;
743 }
744 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
745 for (i = 0; i < devc->num_vdivs; i++) {
746 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
747 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
748 tuple = g_variant_new_tuple(rational, 2);
749 g_variant_builder_add_value(&gvb, tuple);
750 }
751 *data = g_variant_builder_end(&gvb);
752 break;
753 case SR_CONF_TIMEBASE:
754 if (!devc)
755 /* Can't know this until we have the exact model. */
756 return SR_ERR_ARG;
757 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
758 for (i = 0; i < devc->num_timebases; i++) {
759 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
760 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
761 tuple = g_variant_new_tuple(rational, 2);
762 g_variant_builder_add_value(&gvb, tuple);
763 }
764 *data = g_variant_builder_end(&gvb);
765 break;
766 case SR_CONF_TRIGGER_SOURCE:
767 if (!devc)
768 /* Can't know this until we have the exact model. */
769 return SR_ERR_ARG;
770 *data = g_variant_new_strv(trigger_sources,
771 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
772 break;
773 case SR_CONF_DATA_SOURCE:
774 if (!devc)
775 /* Can't know this until we have the exact model. */
776 return SR_ERR_ARG;
777 /* This needs tweaking by series/model! */
778 if (devc->model->series == RIGOL_DS2000)
779 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
780 else
781 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
782 break;
783 default:
784 return SR_ERR_NA;
785 }
786
787 return SR_OK;
788}
789
790static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
791{
792 struct sr_scpi_dev_inst *scpi;
793 struct dev_context *devc;
794 struct sr_probe *probe;
795 GSList *l;
796
797 if (sdi->status != SR_ST_ACTIVE)
798 return SR_ERR_DEV_CLOSED;
799
800 scpi = sdi->conn;
801 devc = sdi->priv;
802
803 for (l = sdi->probes; l; l = l->next) {
804 probe = l->data;
805 sr_dbg("handling probe %s", probe->name);
806 if (probe->type == SR_PROBE_ANALOG) {
807 if (probe->enabled)
808 devc->enabled_analog_probes = g_slist_append(
809 devc->enabled_analog_probes, probe);
810 if (probe->enabled != devc->analog_channels[probe->index]) {
811 /* Enabled channel is currently disabled, or vice versa. */
812 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
813 probe->enabled ? "ON" : "OFF") != SR_OK)
814 return SR_ERR;
815 }
816 } else if (probe->type == SR_PROBE_LOGIC) {
817 if (probe->enabled)
818 devc->enabled_digital_probes = g_slist_append(
819 devc->enabled_digital_probes, probe);
820 if (probe->enabled != devc->digital_channels[probe->index]) {
821 /* Enabled channel is currently disabled, or vice versa. */
822 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
823 probe->enabled ? "ON" : "OFF") != SR_OK)
824 return SR_ERR;
825 }
826 }
827 }
828
829 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
830 return SR_ERR;
831
832 if (devc->data_source == DATA_SOURCE_LIVE) {
833 if (set_cfg(sdi, ":RUN") != SR_OK)
834 return SR_ERR;
835 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
836 if (devc->model->series != RIGOL_DS2000) {
837 sr_err("Data source 'Memory' not supported for this device");
838 return SR_ERR;
839 }
840 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
841 sr_err("Data source 'Segmented' not yet supported");
842 return SR_ERR;
843 }
844
845 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
846
847 /* Send header packet to the session bus. */
848 std_session_send_df_header(cb_data, LOG_PREFIX);
849
850 if (devc->enabled_analog_probes)
851 devc->channel_entry = devc->enabled_analog_probes;
852 else
853 devc->channel_entry = devc->enabled_digital_probes;
854
855 if (devc->model->protocol == PROTOCOL_LEGACY) {
856 devc->analog_frame_size = (devc->model->series == RIGOL_VS5000 ?
857 VS5000_ANALOG_LIVE_WAVEFORM_SIZE :
858 DS1000_ANALOG_LIVE_WAVEFORM_SIZE);
859 /* Fetch the first frame. */
860 if (rigol_ds_channel_start(sdi) != SR_OK)
861 return SR_ERR;
862 } else {
863 if (devc->enabled_analog_probes) {
864 if (devc->data_source == DATA_SOURCE_MEMORY)
865 {
866 if (g_slist_length(devc->enabled_analog_probes) == 1)
867 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
868 else
869 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
870 /* Apparently for the DS2000 the memory
871 * depth can only be set in Running state -
872 * this matches the behaviour of the UI. */
873 if (set_cfg(sdi, ":RUN") != SR_OK)
874 return SR_ERR;
875 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
876 return SR_ERR;
877 if (set_cfg(sdi, ":STOP") != SR_OK)
878 return SR_ERR;
879 } else {
880 if (devc->model->series == AGILENT_DSO1000)
881 devc->analog_frame_size = DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
882 else
883 devc->analog_frame_size = DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
884 }
885 if (rigol_ds_capture_start(sdi) != SR_OK)
886 return SR_ERR;
887 }
888 }
889
890 return SR_OK;
891}
892
893static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
894{
895 struct dev_context *devc;
896 struct sr_scpi_dev_inst *scpi;
897
898 (void)cb_data;
899
900 devc = sdi->priv;
901
902 if (sdi->status != SR_ST_ACTIVE) {
903 sr_err("Device inactive, can't stop acquisition.");
904 return SR_ERR;
905 }
906
907 g_slist_free(devc->enabled_analog_probes);
908 g_slist_free(devc->enabled_digital_probes);
909 devc->enabled_analog_probes = NULL;
910 devc->enabled_digital_probes = NULL;
911 scpi = sdi->conn;
912 sr_scpi_source_remove(scpi);
913
914 return SR_OK;
915}
916
917SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
918 .name = "rigol-ds",
919 .longname = "Rigol DS",
920 .api_version = 1,
921 .init = init,
922 .cleanup = cleanup,
923 .scan = scan,
924 .dev_list = dev_list,
925 .dev_clear = dev_clear,
926 .config_get = config_get,
927 .config_set = config_set,
928 .config_list = config_list,
929 .dev_open = dev_open,
930 .dev_close = dev_close,
931 .dev_acquisition_start = dev_acquisition_start,
932 .dev_acquisition_stop = dev_acquisition_stop,
933 .priv = NULL,
934};