]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/rigol-ds/api.c
Use PRIu64 for format in pretty-printer.
[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, "DS2302", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
174 {RIGOL, "DS2072A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
175 {RIGOL, "DS2102A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
176 {RIGOL, "DS2202A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
177 {RIGOL, "DS2302A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
178 {RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
179 {RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
180 {RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
181 {RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
182 {RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
183 {RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
184 {RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
185 {RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
186 {RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
187 {RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
188 {AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
189 {AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
190 {AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
191 {AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
192 {AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
193 {AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
194};
195
196SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
197static struct sr_dev_driver *di = &rigol_ds_driver_info;
198
199static void clear_helper(void *priv)
200{
201 struct dev_context *devc;
202
203 devc = priv;
204 g_free(devc->data);
205 g_free(devc->buffer);
206 g_free(devc->coupling[0]);
207 g_free(devc->coupling[1]);
208 g_free(devc->trigger_source);
209 g_free(devc->trigger_slope);
210 g_slist_free(devc->analog_groups[0].probes);
211 g_slist_free(devc->analog_groups[1].probes);
212 g_slist_free(devc->digital_group.probes);
213}
214
215static int dev_clear(void)
216{
217 return std_dev_clear(di, clear_helper);
218}
219
220static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
221{
222 va_list args;
223 int ret;
224
225 va_start(args, format);
226 ret = sr_scpi_send_variadic(sdi->conn, format, args);
227 va_end(args);
228
229 if (ret != SR_OK)
230 return SR_ERR;
231
232 /* When setting a bunch of parameters in a row, the DS1052E scrambles
233 * some of them unless there is at least 100ms delay in between. */
234 sr_spew("delay %dms", 100);
235 g_usleep(100000);
236
237 return SR_OK;
238}
239
240static int init(struct sr_context *sr_ctx)
241{
242 return std_init(sr_ctx, di, LOG_PREFIX);
243}
244
245static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
246{
247 struct dev_context *devc;
248 struct sr_dev_inst *sdi;
249 struct sr_scpi_dev_inst *scpi;
250 struct sr_scpi_hw_info *hw_info;
251 struct sr_probe *probe;
252 unsigned int i;
253 const struct rigol_ds_model *model = NULL;
254 gchar *channel_name;
255
256 *devices = NULL;
257
258 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
259 return SR_ERR;
260
261 if (sr_scpi_open(scpi) != SR_OK) {
262 sr_info("Couldn't open SCPI device.");
263 sr_scpi_free(scpi);
264 return SR_ERR;
265 };
266
267 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
268 sr_info("Couldn't get IDN response.");
269 sr_scpi_close(scpi);
270 sr_scpi_free(scpi);
271 return SR_ERR;
272 }
273
274 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
275 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
276 !strcmp(hw_info->model, supported_models[i].name)) {
277 model = &supported_models[i];
278 break;
279 }
280 }
281
282 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
283 hw_info->manufacturer, hw_info->model,
284 hw_info->firmware_version))) {
285 sr_scpi_hw_info_free(hw_info);
286 sr_scpi_close(scpi);
287 sr_scpi_free(scpi);
288 return SR_ERR_NA;
289 }
290
291 sr_scpi_hw_info_free(hw_info);
292 sr_scpi_close(scpi);
293
294 sdi->conn = scpi;
295
296 sdi->driver = di;
297 sdi->inst_type = SR_INST_SCPI;
298
299 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
300 return SR_ERR_MALLOC;
301
302 devc->limit_frames = 0;
303 devc->model = model;
304
305 for (i = 0; i < model->analog_channels; i++) {
306 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
307 return SR_ERR_MALLOC;
308 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
309 sdi->probes = g_slist_append(sdi->probes, probe);
310 devc->analog_groups[i].name = channel_name;
311 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
312 sdi->probe_groups = g_slist_append(sdi->probe_groups,
313 &devc->analog_groups[i]);
314 }
315
316 if (devc->model->has_digital) {
317 for (i = 0; i < 16; i++) {
318 if (!(channel_name = g_strdup_printf("D%d", i)))
319 return SR_ERR_MALLOC;
320 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
321 g_free(channel_name);
322 if (!probe)
323 return SR_ERR_MALLOC;
324 sdi->probes = g_slist_append(sdi->probes, probe);
325 devc->digital_group.probes = g_slist_append(
326 devc->digital_group.probes, probe);
327 }
328 devc->digital_group.name = "LA";
329 sdi->probe_groups = g_slist_append(sdi->probe_groups,
330 &devc->digital_group);
331 }
332
333 for (i = 0; i < NUM_TIMEBASE; i++) {
334 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
335 devc->timebases = &timebases[i];
336 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
337 devc->num_timebases = &timebases[i] - devc->timebases + 1;
338 }
339
340 for (i = 0; i < NUM_VDIV; i++)
341 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
342 devc->vdivs = &vdivs[i];
343
344 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
345 return SR_ERR_MALLOC;
346 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
347 return SR_ERR_MALLOC;
348
349 devc->data_source = DATA_SOURCE_LIVE;
350
351 sdi->priv = devc;
352
353 *devices = g_slist_append(NULL, sdi);
354
355 return SR_OK;
356}
357
358static GSList *scan(GSList *options)
359{
360 struct drv_context *drvc;
361 struct sr_config *src;
362 GSList *l, *devices;
363 GDir *dir;
364 int ret;
365 const gchar *dev_name;
366 gchar *port = NULL;
367 gchar *serialcomm = NULL;
368
369 drvc = di->priv;
370
371 for (l = options; l; l = l->next) {
372 src = l->data;
373 switch (src->key) {
374 case SR_CONF_CONN:
375 port = (char *)g_variant_get_string(src->data, NULL);
376 break;
377 case SR_CONF_SERIALCOMM:
378 serialcomm = (char *)g_variant_get_string(src->data, NULL);
379 break;
380 }
381 }
382
383 devices = NULL;
384 if (port) {
385 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
386 g_free(port);
387 if (serialcomm)
388 g_free(serialcomm);
389 return NULL;
390 }
391 } else {
392 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
393 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
394 return NULL;
395 while ((dev_name = g_dir_read_name(dir))) {
396 if (strncmp(dev_name, "usbtmc", 6))
397 continue;
398 port = g_strconcat("/dev/", dev_name, NULL);
399 ret = probe_port(port, serialcomm, &devices);
400 g_free(port);
401 if (serialcomm)
402 g_free(serialcomm);
403 if (ret == SR_ERR_MALLOC) {
404 g_dir_close(dir);
405 return NULL;
406 }
407 }
408 g_dir_close(dir);
409 }
410
411 /* Tack a copy of the newly found devices onto the driver list. */
412 l = g_slist_copy(devices);
413 drvc->instances = g_slist_concat(drvc->instances, l);
414
415 return devices;
416}
417
418static GSList *dev_list(void)
419{
420 return ((struct drv_context *)(di->priv))->instances;
421}
422
423static int dev_open(struct sr_dev_inst *sdi)
424{
425 struct sr_scpi_dev_inst *scpi = sdi->conn;
426
427 if (sr_scpi_open(scpi) < 0)
428 return SR_ERR;
429
430 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
431 return SR_ERR;
432
433 sdi->status = SR_ST_ACTIVE;
434
435 return SR_OK;
436}
437
438static int dev_close(struct sr_dev_inst *sdi)
439{
440 struct sr_scpi_dev_inst *scpi;
441
442 scpi = sdi->conn;
443
444 if (scpi) {
445 if (sr_scpi_close(scpi) < 0)
446 return SR_ERR;
447 sdi->status = SR_ST_INACTIVE;
448 }
449
450 return SR_OK;
451}
452
453static int cleanup(void)
454{
455 return dev_clear();
456}
457
458static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
459 const struct sr_probe_group *probe_group)
460{
461 struct dev_context *devc;
462
463 if (!sdi || !(devc = sdi->priv))
464 return SR_ERR_ARG;
465
466 /* If a probe group is specified, it must be a valid one. */
467 if (probe_group) {
468 if (probe_group != &devc->analog_groups[0]
469 && probe_group != &devc->analog_groups[1]) {
470 sr_err("Invalid probe group specified.");
471 return SR_ERR;
472 }
473 }
474
475 switch (id) {
476 case SR_CONF_NUM_TIMEBASE:
477 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
478 break;
479 case SR_CONF_NUM_VDIV:
480 *data = g_variant_new_int32(8);
481 case SR_CONF_DATA_SOURCE:
482 if (devc->data_source == DATA_SOURCE_LIVE)
483 *data = g_variant_new_string("Live");
484 else if (devc->data_source == DATA_SOURCE_MEMORY)
485 *data = g_variant_new_string("Memory");
486 else
487 *data = g_variant_new_string("Segmented");
488 break;
489 default:
490 return SR_ERR_NA;
491 }
492
493 return SR_OK;
494}
495
496static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
497 const struct sr_probe_group *probe_group)
498{
499 struct dev_context *devc;
500 uint64_t tmp_u64, p, q;
501 double t_dbl;
502 unsigned int i, j;
503 int ret;
504 const char *tmp_str;
505
506 if (!(devc = sdi->priv))
507 return SR_ERR_ARG;
508
509 if (sdi->status != SR_ST_ACTIVE)
510 return SR_ERR_DEV_CLOSED;
511
512 /* If a probe group is specified, it must be a valid one. */
513 if (probe_group) {
514 if (probe_group != &devc->analog_groups[0]
515 && probe_group != &devc->analog_groups[1]) {
516 sr_err("Invalid probe group specified.");
517 return SR_ERR;
518 }
519 }
520
521 ret = SR_OK;
522 switch (id) {
523 case SR_CONF_LIMIT_FRAMES:
524 devc->limit_frames = g_variant_get_uint64(data);
525 break;
526 case SR_CONF_TRIGGER_SLOPE:
527 tmp_u64 = g_variant_get_uint64(data);
528 if (tmp_u64 != 0 && tmp_u64 != 1)
529 return SR_ERR;
530 g_free(devc->trigger_slope);
531 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
532 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
533 break;
534 case SR_CONF_HORIZ_TRIGGERPOS:
535 t_dbl = g_variant_get_double(data);
536 if (t_dbl < 0.0 || t_dbl > 1.0)
537 return SR_ERR;
538 devc->horiz_triggerpos = t_dbl;
539 /* We have the trigger offset as a percentage of the frame, but
540 * need to express this in seconds. */
541 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
542 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
543 break;
544 case SR_CONF_TIMEBASE:
545 g_variant_get(data, "(tt)", &p, &q);
546 for (i = 0; i < devc->num_timebases; i++) {
547 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
548 devc->timebase = (float)p / q;
549 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
550 break;
551 }
552 }
553 if (i == devc->num_timebases)
554 ret = SR_ERR_ARG;
555 break;
556 case SR_CONF_TRIGGER_SOURCE:
557 tmp_str = g_variant_get_string(data, NULL);
558 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
559 if (!strcmp(trigger_sources[i], tmp_str)) {
560 g_free(devc->trigger_source);
561 devc->trigger_source = g_strdup(trigger_sources[i]);
562 if (!strcmp(devc->trigger_source, "AC Line"))
563 tmp_str = "ACL";
564 else if (!strcmp(devc->trigger_source, "CH1"))
565 tmp_str = "CHAN1";
566 else if (!strcmp(devc->trigger_source, "CH2"))
567 tmp_str = "CHAN2";
568 else if (!strcmp(devc->trigger_source, "CH3"))
569 tmp_str = "CHAN3";
570 else if (!strcmp(devc->trigger_source, "CH4"))
571 tmp_str = "CHAN4";
572 else
573 tmp_str = (char *)devc->trigger_source;
574 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
575 break;
576 }
577 }
578 if (i == ARRAY_SIZE(trigger_sources))
579 ret = SR_ERR_ARG;
580 break;
581 case SR_CONF_VDIV:
582 if (!probe_group) {
583 sr_err("No probe group specified.");
584 return SR_ERR_PROBE_GROUP;
585 }
586 g_variant_get(data, "(tt)", &p, &q);
587 for (i = 0; i < 2; i++) {
588 if (probe_group == &devc->analog_groups[i]) {
589 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
590 if (vdivs[j][0] != p || vdivs[j][1] != q)
591 continue;
592 devc->vdiv[i] = (float)p / q;
593 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
594 devc->vdiv[i]);
595 }
596 return SR_ERR_ARG;
597 }
598 }
599 return SR_ERR_NA;
600 case SR_CONF_COUPLING:
601 if (!probe_group) {
602 sr_err("No probe group specified.");
603 return SR_ERR_PROBE_GROUP;
604 }
605 tmp_str = g_variant_get_string(data, NULL);
606 for (i = 0; i < 2; i++) {
607 if (probe_group == &devc->analog_groups[i]) {
608 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
609 if (!strcmp(tmp_str, coupling[j])) {
610 g_free(devc->coupling[i]);
611 devc->coupling[i] = g_strdup(coupling[j]);
612 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
613 devc->coupling[i]);
614 }
615 }
616 return SR_ERR_ARG;
617 }
618 }
619 return SR_ERR_NA;
620 case SR_CONF_DATA_SOURCE:
621 tmp_str = g_variant_get_string(data, NULL);
622 if (!strcmp(tmp_str, "Live"))
623 devc->data_source = DATA_SOURCE_LIVE;
624 else if (!strcmp(tmp_str, "Memory"))
625 devc->data_source = DATA_SOURCE_MEMORY;
626 else if (devc->model->protocol == PROTOCOL_IEEE488_2
627 && !strcmp(tmp_str, "Segmented"))
628 devc->data_source = DATA_SOURCE_SEGMENTED;
629 else
630 return SR_ERR;
631 break;
632 default:
633 ret = SR_ERR_NA;
634 break;
635 }
636
637 return ret;
638}
639
640static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
641 const struct sr_probe_group *probe_group)
642{
643 GVariant *tuple, *rational[2];
644 GVariantBuilder gvb;
645 unsigned int i;
646 struct dev_context *devc = NULL;
647
648 if (sdi)
649 devc = sdi->priv;
650
651 if (key == SR_CONF_SCAN_OPTIONS) {
652 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
653 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
654 return SR_OK;
655 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
656 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
657 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
658 return SR_OK;
659 }
660
661 /* Every other option requires a valid device instance. */
662 if (!sdi || !(devc = sdi->priv))
663 return SR_ERR_ARG;
664
665 /* If a probe group is specified, it must be a valid one. */
666 if (probe_group) {
667 if (probe_group != &devc->analog_groups[0]
668 && probe_group != &devc->analog_groups[1]) {
669 sr_err("Invalid probe group specified.");
670 return SR_ERR;
671 }
672 }
673
674 switch (key) {
675 break;
676 case SR_CONF_DEVICE_OPTIONS:
677 if (!probe_group) {
678 sr_err("No probe group specified.");
679 return SR_ERR_PROBE_GROUP;
680 }
681 if (probe_group == &devc->digital_group) {
682 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
683 NULL, 0, sizeof(int32_t));
684 return SR_OK;
685 } else {
686 for (i = 0; i < 2; i++) {
687 if (probe_group == &devc->analog_groups[i]) {
688 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
689 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
690 return SR_OK;
691 }
692 }
693 return SR_ERR_NA;
694 }
695 break;
696 case SR_CONF_COUPLING:
697 if (!probe_group) {
698 sr_err("No probe group specified.");
699 return SR_ERR_PROBE_GROUP;
700 }
701 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
702 break;
703 case SR_CONF_VDIV:
704 if (!devc)
705 /* Can't know this until we have the exact model. */
706 return SR_ERR_ARG;
707 if (!probe_group) {
708 sr_err("No probe group specified.");
709 return SR_ERR_PROBE_GROUP;
710 }
711 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
712 for (i = 0; i < NUM_VDIV; i++) {
713 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
714 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
715 tuple = g_variant_new_tuple(rational, 2);
716 g_variant_builder_add_value(&gvb, tuple);
717 }
718 *data = g_variant_builder_end(&gvb);
719 break;
720 case SR_CONF_TIMEBASE:
721 if (!devc)
722 /* Can't know this until we have the exact model. */
723 return SR_ERR_ARG;
724 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
725 for (i = 0; i < devc->num_timebases; i++) {
726 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
727 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
728 tuple = g_variant_new_tuple(rational, 2);
729 g_variant_builder_add_value(&gvb, tuple);
730 }
731 *data = g_variant_builder_end(&gvb);
732 break;
733 case SR_CONF_TRIGGER_SOURCE:
734 if (!devc)
735 /* Can't know this until we have the exact model. */
736 return SR_ERR_ARG;
737 *data = g_variant_new_strv(trigger_sources,
738 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
739 break;
740 case SR_CONF_DATA_SOURCE:
741 if (!devc)
742 /* Can't know this until we have the exact model. */
743 return SR_ERR_ARG;
744 /* This needs tweaking by series/model! */
745 if (devc->model->series == RIGOL_DS2000)
746 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
747 else
748 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
749 break;
750 default:
751 return SR_ERR_NA;
752 }
753
754 return SR_OK;
755}
756
757static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
758{
759 struct sr_scpi_dev_inst *scpi;
760 struct dev_context *devc;
761 struct sr_probe *probe;
762 GSList *l;
763
764 if (sdi->status != SR_ST_ACTIVE)
765 return SR_ERR_DEV_CLOSED;
766
767 scpi = sdi->conn;
768 devc = sdi->priv;
769
770 for (l = sdi->probes; l; l = l->next) {
771 probe = l->data;
772 sr_dbg("handling probe %s", probe->name);
773 if (probe->type == SR_PROBE_ANALOG) {
774 if (probe->enabled)
775 devc->enabled_analog_probes = g_slist_append(
776 devc->enabled_analog_probes, probe);
777 if (probe->enabled != devc->analog_channels[probe->index]) {
778 /* Enabled channel is currently disabled, or vice versa. */
779 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
780 probe->enabled ? "ON" : "OFF") != SR_OK)
781 return SR_ERR;
782 }
783 } else if (probe->type == SR_PROBE_LOGIC) {
784 if (probe->enabled)
785 devc->enabled_digital_probes = g_slist_append(
786 devc->enabled_digital_probes, probe);
787 if (probe->enabled != devc->digital_channels[probe->index]) {
788 /* Enabled channel is currently disabled, or vice versa. */
789 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
790 probe->enabled ? "ON" : "OFF") != SR_OK)
791 return SR_ERR;
792 }
793 }
794 }
795
796 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
797 return SR_ERR;
798
799 if (devc->data_source == DATA_SOURCE_LIVE) {
800 if (set_cfg(sdi, ":RUN") != SR_OK)
801 return SR_ERR;
802 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
803 if (devc->model->series != RIGOL_DS2000) {
804 sr_err("Data source 'Memory' not supported for this device");
805 return SR_ERR;
806 }
807 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
808 sr_err("Data source 'Segmented' not yet supported");
809 return SR_ERR;
810 }
811
812 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
813
814 /* Send header packet to the session bus. */
815 std_session_send_df_header(cb_data, LOG_PREFIX);
816
817 if (devc->enabled_analog_probes)
818 devc->channel_entry = devc->enabled_analog_probes;
819 else
820 devc->channel_entry = devc->enabled_digital_probes;
821
822 if (devc->model->protocol == PROTOCOL_LEGACY) {
823 devc->analog_frame_size = (devc->model->series == RIGOL_VS5000 ?
824 VS5000_ANALOG_LIVE_WAVEFORM_SIZE :
825 DS1000_ANALOG_LIVE_WAVEFORM_SIZE);
826 /* Fetch the first frame. */
827 if (rigol_ds_channel_start(sdi) != SR_OK)
828 return SR_ERR;
829 } else {
830 if (devc->enabled_analog_probes) {
831 if (devc->data_source == DATA_SOURCE_MEMORY)
832 {
833 if (g_slist_length(devc->enabled_analog_probes) == 1)
834 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
835 else
836 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
837 /* Apparently for the DS2000 the memory
838 * depth can only be set in Running state -
839 * this matches the behaviour of the UI. */
840 if (set_cfg(sdi, ":RUN") != SR_OK)
841 return SR_ERR;
842 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
843 return SR_ERR;
844 if (set_cfg(sdi, ":STOP") != SR_OK)
845 return SR_ERR;
846 } else {
847 if (devc->model->series == AGILENT_DSO1000)
848 devc->analog_frame_size = DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
849 else
850 devc->analog_frame_size = DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
851 }
852 if (rigol_ds_capture_start(sdi) != SR_OK)
853 return SR_ERR;
854 }
855 }
856
857 return SR_OK;
858}
859
860static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
861{
862 struct dev_context *devc;
863 struct sr_scpi_dev_inst *scpi;
864
865 (void)cb_data;
866
867 devc = sdi->priv;
868
869 if (sdi->status != SR_ST_ACTIVE) {
870 sr_err("Device inactive, can't stop acquisition.");
871 return SR_ERR;
872 }
873
874 g_slist_free(devc->enabled_analog_probes);
875 g_slist_free(devc->enabled_digital_probes);
876 devc->enabled_analog_probes = NULL;
877 devc->enabled_digital_probes = NULL;
878 scpi = sdi->conn;
879 sr_scpi_source_remove(scpi);
880
881 return SR_OK;
882}
883
884SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
885 .name = "rigol-ds",
886 .longname = "Rigol DS",
887 .api_version = 1,
888 .init = init,
889 .cleanup = cleanup,
890 .scan = scan,
891 .dev_list = dev_list,
892 .dev_clear = dev_clear,
893 .config_get = config_get,
894 .config_set = config_set,
895 .config_list = config_list,
896 .dev_open = dev_open,
897 .dev_close = dev_close,
898 .dev_acquisition_start = dev_acquisition_start,
899 .dev_acquisition_stop = dev_acquisition_stop,
900 .priv = NULL,
901};