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