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