]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
scpi_usbtmc_libusb: disable all clear_halt for Rigol DS1000
[libsigrok.git] / hardware / rigol-ds / api.c
CommitLineData
f4816ac6
ML
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
88e429c9 5 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
bafd4890 6 * Copyright (C) 2013 Mathias Grimmberger <mgri@zaphod.sax.de>
f4816ac6
ML
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
e0b7d23c
ML
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
2b0e4a46 26#include <math.h>
f4816ac6
ML
27#include <glib.h>
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
31
ca55277c
ML
32static const int32_t hwopts[] = {
33 SR_CONF_CONN,
0dc7b43e 34 SR_CONF_SERIALCOMM
ca55277c
ML
35};
36
f6a0ac9f 37static const int32_t hwcaps[] = {
1953564a 38 SR_CONF_OSCILLOSCOPE,
1953564a
BV
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
d62d7ad1 43 SR_CONF_NUM_TIMEBASE,
c1bcb8cc 44 SR_CONF_LIMIT_FRAMES,
4914dd4b 45 SR_CONF_SAMPLERATE,
f48e0249
ML
46};
47
48static const int32_t analog_hwcaps[] = {
d62d7ad1 49 SR_CONF_NUM_VDIV,
f48e0249 50 SR_CONF_VDIV,
78bcc55a 51 SR_CONF_COUPLING,
babab622 52 SR_CONF_DATA_SOURCE,
e0b7d23c
ML
53};
54
f6a0ac9f 55static const uint64_t timebases[][2] = {
e0b7d23c 56 /* nanoseconds */
8e06edf5 57 { 1, 1000000000 },
e0b7d23c
ML
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 },
bafd4890
ML
92 { 100, 1 },
93 { 200, 1 },
94 { 500, 1 },
8e06edf5 95 { 1000, 1 },
e0b7d23c
ML
96};
97
f6a0ac9f 98static const uint64_t vdivs[][2] = {
bafd4890
ML
99 /* microvolts */
100 { 500, 1000000 },
e0b7d23c 101 /* millivolts */
bafd4890 102 { 1, 1000 },
e0b7d23c
ML
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 },
e0b7d23c
ML
116};
117
bafd4890
ML
118#define NUM_TIMEBASE ARRAY_SIZE(timebases)
119#define NUM_VDIV ARRAY_SIZE(vdivs)
120
e0b7d23c
ML
121static const char *trigger_sources[] = {
122 "CH1",
123 "CH2",
821fbcad
ML
124 "CH3",
125 "CH4",
e0b7d23c
ML
126 "EXT",
127 "AC Line",
6bb192bc
ML
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",
e0b7d23c
ML
144};
145
5d336f11
AJ
146static const char *trigger_slopes[] = {
147 "r",
148 "f",
149};
150
e0b7d23c
ML
151static const char *coupling[] = {
152 "AC",
153 "DC",
154 "GND",
e0b7d23c
ML
155};
156
babab622
ML
157/* Do not change the order of entries */
158static const char *data_sources[] = {
159 "Live",
160 "Memory",
161 "Segmented",
162};
163
569d4dbd
ML
164enum vendor {
165 RIGOL,
166 AGILENT,
167};
168
169enum series {
170 VS5000,
171 DS1000,
172 DS2000,
173 DS2000A,
174 DSO1000,
175};
10afee13 176
569d4dbd
ML
177/* short name, full name */
178static const struct rigol_ds_vendor supported_vendors[] = {
179 [RIGOL] = {"Rigol", "Rigol Technologies"},
180 [AGILENT] = {"Agilent", "Rigol Technologies"},
181};
182
183#define VENDOR(x) &supported_vendors[x]
184/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
185 * live waveform samples, memory buffer samples */
186static const struct rigol_ds_series supported_series[] = {
187 [VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
188 {50, 1}, {2, 1000}, 14, 2048, 0},
189 [DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
190 {50, 1}, {2, 1000}, 12, 600, 1048576},
191 [DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
192 {500, 1}, {2, 1000}, 14, 1400, 14000},
193 [DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
194 {1000, 1}, {500, 1000000}, 14, 1400, 14000},
195 [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
196 {50, 1}, {2, 1000}, 12, 600, 20480},
197};
10afee13 198
569d4dbd
ML
199#define SERIES(x) &supported_series[x]
200/* series, model, min timebase, analog channels, digital */
bafd4890 201static const struct rigol_ds_model supported_models[] = {
569d4dbd
ML
202 {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
203 {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
204 {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
205 {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
206 {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
207 {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
208 {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
209 {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
210 {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
211 {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
212 {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
213 {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
214 {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
215 {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
216 {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
217 {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
218 {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
219 {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
220 {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
221 {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
222 {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
223 {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
224 {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
225 {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
226 {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
227 {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
228 {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
229 {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
230 {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
231 {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
512bb890
BV
232};
233
3086efdd
ML
234SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
235static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 236
fa85f376 237static void clear_helper(void *priv)
f4816ac6 238{
f4816ac6 239 struct dev_context *devc;
f4816ac6 240
ba358ffd 241 devc = priv;
babab622
ML
242 g_free(devc->data);
243 g_free(devc->buffer);
fa85f376
UH
244 g_free(devc->coupling[0]);
245 g_free(devc->coupling[1]);
246 g_free(devc->trigger_source);
247 g_free(devc->trigger_slope);
a68bf88e
UH
248 g_slist_free(devc->analog_groups[0].channels);
249 g_slist_free(devc->analog_groups[1].channels);
250 g_slist_free(devc->digital_group.channels);
fa85f376 251}
f4816ac6 252
3b412e3a 253static int dev_clear(void)
fa85f376
UH
254{
255 return std_dev_clear(di, clear_helper);
f4816ac6
ML
256}
257
6078d2c9 258static int init(struct sr_context *sr_ctx)
f4816ac6 259{
f6beaac5 260 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
261}
262
9d3ae01b 263static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
f4816ac6 264{
cc9fd2d2
BV
265 struct dev_context *devc;
266 struct sr_dev_inst *sdi;
ae1bc1cc 267 struct sr_scpi_hw_info *hw_info;
ba7dd8bb 268 struct sr_channel *ch;
8dd0b290 269 long n[3];
f6a0ac9f 270 unsigned int i;
bafd4890 271 const struct rigol_ds_model *model = NULL;
569d4dbd 272 gchar *channel_name, **version;
fb6e5ba8 273
ae1bc1cc
ML
274 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
275 sr_info("Couldn't get IDN response.");
9d3ae01b 276 return NULL;
ca55277c 277 }
e0b7d23c 278
ca55277c 279 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
569d4dbd
ML
280 if (!strcasecmp(hw_info->manufacturer,
281 supported_models[i].series->vendor->full_name) &&
10afee13 282 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 283 model = &supported_models[i];
ca55277c 284 break;
fb6e5ba8 285 }
ca55277c 286 }
fb6e5ba8 287
bafd4890 288 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
569d4dbd
ML
289 model->series->vendor->name,
290 model->name,
ae1bc1cc
ML
291 hw_info->firmware_version))) {
292 sr_scpi_hw_info_free(hw_info);
9d3ae01b 293 return NULL;
ca55277c 294 }
fb6e5ba8 295
ae1bc1cc 296 sdi->conn = scpi;
fb6e5ba8 297
cc9fd2d2 298 sdi->driver = di;
ae1bc1cc 299 sdi->inst_type = SR_INST_SCPI;
512bb890 300
cc9fd2d2 301 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
9d3ae01b 302 return NULL;
ae1bc1cc 303
cc9fd2d2 304 devc->limit_frames = 0;
bafd4890 305 devc->model = model;
569d4dbd 306 devc->format = model->series->format;
8dd0b290 307
569d4dbd
ML
308 /* DS1000 models with firmware before 0.2.4 used the old data format. */
309 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
310 version = g_strsplit(hw_info->firmware_version, ".", 0);
311 do {
312 if (!version[0] || !version[1] || !version[2])
313 break;
314 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
315 break;
316 for (i = 0; i < 3; i++) {
317 if (sr_atol(version[i], &n[i]) != SR_OK)
318 break;
319 }
320 if (i != 3)
321 break;
322 if (n[0] != 0 || n[1] > 2)
323 break;
324 if (n[1] == 2 && n[2] > 3)
325 break;
569d4dbd
ML
326 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
327 devc->format = FORMAT_RAW;
8dd0b290
BV
328 } while(0);
329 g_strfreev(version);
330 }
331
332 sr_scpi_hw_info_free(hw_info);
512bb890 333
821fbcad
ML
334 for (i = 0; i < model->analog_channels; i++) {
335 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
9d3ae01b 336 return NULL;
3f239f08 337 ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, channel_name);
ba7dd8bb 338 sdi->channels = g_slist_append(sdi->channels, ch);
3d3a601e 339 devc->analog_groups[i].name = channel_name;
ba7dd8bb 340 devc->analog_groups[i].channels = g_slist_append(NULL, ch);
660e398f 341 sdi->channel_groups = g_slist_append(sdi->channel_groups,
3d3a601e 342 &devc->analog_groups[i]);
ca55277c 343 }
512bb890 344
bafd4890 345 if (devc->model->has_digital) {
ca55277c
ML
346 for (i = 0; i < 16; i++) {
347 if (!(channel_name = g_strdup_printf("D%d", i)))
9d3ae01b 348 return NULL;
3f239f08 349 ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ca55277c 350 g_free(channel_name);
ba7dd8bb 351 if (!ch)
9d3ae01b 352 return NULL;
ba7dd8bb 353 sdi->channels = g_slist_append(sdi->channels, ch);
a68bf88e 354 devc->digital_group.channels = g_slist_append(
ba7dd8bb 355 devc->digital_group.channels, ch);
512bb890 356 }
b3916147 357 devc->digital_group.name = "LA";
660e398f 358 sdi->channel_groups = g_slist_append(sdi->channel_groups,
b3916147 359 &devc->digital_group);
ca55277c 360 }
bafd4890
ML
361
362 for (i = 0; i < NUM_TIMEBASE; i++) {
363 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
364 devc->timebases = &timebases[i];
569d4dbd 365 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
366 devc->num_timebases = &timebases[i] - devc->timebases + 1;
367 }
368
0709197d 369 for (i = 0; i < NUM_VDIV; i++)
569d4dbd 370 if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 371 devc->vdivs = &vdivs[i];
bafd4890 372
babab622 373 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
9d3ae01b 374 return NULL;
babab622 375 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
9d3ae01b 376 return NULL;
babab622
ML
377
378 devc->data_source = DATA_SOURCE_LIVE;
379
cc9fd2d2
BV
380 sdi->priv = devc;
381
9d3ae01b 382 return sdi;
ca55277c 383}
512bb890 384
6078d2c9 385static GSList *scan(GSList *options)
ca55277c 386{
9d3ae01b 387 return sr_scpi_scan(di->priv, options, probe_device);
f4816ac6
ML
388}
389
6078d2c9 390static GSList *dev_list(void)
f4816ac6 391{
0e94d524 392 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
393}
394
6078d2c9 395static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 396{
ae1bc1cc 397 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 398
ae1bc1cc 399 if (sr_scpi_open(scpi) < 0)
e0b7d23c 400 return SR_ERR;
e0b7d23c 401
3086efdd 402 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 403 return SR_ERR;
f4816ac6 404
46a743c1 405 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 406
f4816ac6
ML
407 return SR_OK;
408}
409
6078d2c9 410static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 411{
ae1bc1cc 412 struct sr_scpi_dev_inst *scpi;
22c19688 413 struct dev_context *devc;
ae1bc1cc 414
83dbd9f0
AJ
415 if (sdi->status != SR_ST_ACTIVE)
416 return SR_ERR_DEV_CLOSED;
464d4936 417
ae1bc1cc 418 scpi = sdi->conn;
22c19688
ML
419 devc = sdi->priv;
420
6e94eb41 421 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 422 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 423
ae1bc1cc
ML
424 if (scpi) {
425 if (sr_scpi_close(scpi) < 0)
426 return SR_ERR;
cc9fd2d2
BV
427 sdi->status = SR_ST_INACTIVE;
428 }
f4816ac6
ML
429
430 return SR_OK;
431}
432
6078d2c9 433static int cleanup(void)
f4816ac6 434{
3b412e3a 435 return dev_clear();
f4816ac6
ML
436}
437
5415e602
ML
438static int analog_frame_size(const struct sr_dev_inst *sdi)
439{
440 struct dev_context *devc = sdi->priv;
ba7dd8bb
UH
441 struct sr_channel *ch;
442 int analog_channels = 0;
5415e602
ML
443 GSList *l;
444
ba7dd8bb
UH
445 for (l = sdi->channels; l; l = l->next) {
446 ch = l->data;
3f239f08 447 if (ch->type == SR_CHANNEL_ANALOG && ch->enabled)
ba7dd8bb 448 analog_channels++;
569d4dbd
ML
449 }
450
ba7dd8bb 451 if (analog_channels == 0)
824eb2ac
ML
452 return 0;
453
569d4dbd
ML
454 switch (devc->data_source) {
455 case DATA_SOURCE_LIVE:
456 return devc->model->series->live_samples;
457 case DATA_SOURCE_MEMORY:
ba7dd8bb 458 return devc->model->series->buffer_samples / analog_channels;
470140fc 459 default:
569d4dbd 460 return 0;
5415e602
ML
461 }
462}
463
d22250a9
ML
464static int digital_frame_size(const struct sr_dev_inst *sdi)
465{
466 struct dev_context *devc = sdi->priv;
467
569d4dbd
ML
468 switch (devc->data_source) {
469 case DATA_SOURCE_LIVE:
470 return devc->model->series->live_samples * 2;
471 case DATA_SOURCE_MEMORY:
472 return devc->model->series->buffer_samples * 2;
d22250a9
ML
473 default:
474 return 0;
475 }
476}
477
8f996b89 478static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 479 const struct sr_channel_group *cg)
d62d7ad1 480{
e43fdd8d 481 struct dev_context *devc;
ba7dd8bb 482 struct sr_channel *ch;
2b0e4a46 483 const char *tmp_str;
c2b394d5 484 uint64_t samplerate;
2b0e4a46
AJ
485 int analog_channel = -1;
486 float smallest_diff = 0.0000000001;
487 int idx = -1;
488 unsigned i;
d62d7ad1 489
e43fdd8d
BV
490 if (!sdi || !(devc = sdi->priv))
491 return SR_ERR_ARG;
492
660e398f 493 /* If a channel group is specified, it must be a valid one. */
53b4680f 494 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 495 sr_err("Invalid channel group specified.");
969edf63 496 return SR_ERR;
be60a9e4
BV
497 }
498
53b4680f 499 if (cg) {
ba7dd8bb
UH
500 ch = g_slist_nth_data(cg->channels, 0);
501 if (!ch)
2b0e4a46 502 return SR_ERR;
3f239f08 503 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 504 if (ch->name[2] < '1' || ch->name[2] > '4')
2b0e4a46 505 return SR_ERR;
ba7dd8bb 506 analog_channel = ch->name[2] - '1';
2b0e4a46
AJ
507 }
508 }
509
d62d7ad1
BV
510 switch (id) {
511 case SR_CONF_NUM_TIMEBASE:
569d4dbd 512 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
513 break;
514 case SR_CONF_NUM_VDIV:
72ecba02 515 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
516 case SR_CONF_DATA_SOURCE:
517 if (devc->data_source == DATA_SOURCE_LIVE)
518 *data = g_variant_new_string("Live");
519 else if (devc->data_source == DATA_SOURCE_MEMORY)
520 *data = g_variant_new_string("Memory");
521 else
522 *data = g_variant_new_string("Segmented");
523 break;
4914dd4b
ML
524 case SR_CONF_SAMPLERATE:
525 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 526 samplerate = analog_frame_size(sdi) /
569d4dbd 527 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 528 *data = g_variant_new_uint64(samplerate);
c2b394d5 529 } else {
4914dd4b 530 return SR_ERR_NA;
c2b394d5 531 }
4914dd4b 532 break;
2b0e4a46
AJ
533 case SR_CONF_TRIGGER_SOURCE:
534 if (!strcmp(devc->trigger_source, "ACL"))
535 tmp_str = "AC Line";
536 else if (!strcmp(devc->trigger_source, "CHAN1"))
537 tmp_str = "CH1";
538 else if (!strcmp(devc->trigger_source, "CHAN2"))
539 tmp_str = "CH2";
540 else if (!strcmp(devc->trigger_source, "CHAN3"))
541 tmp_str = "CH3";
542 else if (!strcmp(devc->trigger_source, "CHAN4"))
543 tmp_str = "CH4";
544 else
545 tmp_str = devc->trigger_source;
546 *data = g_variant_new_string(tmp_str);
547 break;
5d336f11
AJ
548 case SR_CONF_TRIGGER_SLOPE:
549 if (!strcmp(devc->trigger_slope, "POS"))
550 tmp_str = "r";
551 else if (!strcmp(devc->trigger_slope, "NEG"))
552 tmp_str = "f";
553 else
554 return SR_ERR_NA;
555 *data = g_variant_new_string(tmp_str);
556 break;
2b0e4a46
AJ
557 case SR_CONF_TIMEBASE:
558 for (i = 0; i < devc->num_timebases; i++) {
559 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
560 float diff = fabs(devc->timebase - tb);
561 if (diff < smallest_diff) {
562 smallest_diff = diff;
563 idx = i;
564 }
565 }
566 if (idx < 0)
567 return SR_ERR_NA;
568 *data = g_variant_new("(tt)", devc->timebases[idx][0],
569 devc->timebases[idx][1]);
570 break;
571 case SR_CONF_VDIV:
572 if (analog_channel < 0)
573 return SR_ERR_NA;
574 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
575 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
576 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
577 if (diff < smallest_diff) {
578 smallest_diff = diff;
579 idx = i;
580 }
581 }
582 if (idx < 0)
583 return SR_ERR_NA;
584 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
585 break;
586 case SR_CONF_COUPLING:
587 if (analog_channel < 0)
588 return SR_ERR_NA;
589 *data = g_variant_new_string(devc->coupling[analog_channel]);
590 break;
d62d7ad1 591 default:
bd6fbf62 592 return SR_ERR_NA;
d62d7ad1
BV
593 }
594
595 return SR_OK;
596}
597
8f996b89 598static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 599 const struct sr_channel_group *cg)
f4816ac6 600{
29d957ce 601 struct dev_context *devc;
ca9b9f48 602 uint64_t p, q;
254dd102 603 double t_dbl;
f48e0249 604 unsigned int i, j;
254dd102
BV
605 int ret;
606 const char *tmp_str;
889ef4a0 607 char buffer[16];
f4816ac6 608
e43fdd8d
BV
609 if (!(devc = sdi->priv))
610 return SR_ERR_ARG;
29d957ce 611
e73ffd42
BV
612 if (sdi->status != SR_ST_ACTIVE)
613 return SR_ERR_DEV_CLOSED;
f4816ac6 614
660e398f 615 /* If a channel group is specified, it must be a valid one. */
53b4680f 616 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 617 sr_err("Invalid channel group specified.");
969edf63 618 return SR_ERR;
be60a9e4
BV
619 }
620
f4816ac6 621 ret = SR_OK;
035a1078 622 switch (id) {
1953564a 623 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 624 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 625 break;
1953564a 626 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
627 tmp_str = g_variant_get_string(data, NULL);
628
629 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
630 return SR_ERR_ARG;
631
254dd102 632 g_free(devc->trigger_slope);
ca9b9f48 633 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 634 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 635 break;
1953564a 636 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
637 t_dbl = g_variant_get_double(data);
638 if (t_dbl < 0.0 || t_dbl > 1.0)
639 return SR_ERR;
640 devc->horiz_triggerpos = t_dbl;
641 /* We have the trigger offset as a percentage of the frame, but
642 * need to express this in seconds. */
bafd4890 643 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 644 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 645 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 646 break;
1953564a 647 case SR_CONF_TIMEBASE:
f6a0ac9f 648 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
649 for (i = 0; i < devc->num_timebases; i++) {
650 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 651 devc->timebase = (float)p / q;
889ef4a0
AJ
652 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
653 devc->timebase);
38354d9d 654 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
655 break;
656 }
657 }
bafd4890 658 if (i == devc->num_timebases)
254dd102 659 ret = SR_ERR_ARG;
e0b7d23c 660 break;
1953564a 661 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 662 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
663 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
664 if (!strcmp(trigger_sources[i], tmp_str)) {
665 g_free(devc->trigger_source);
666 devc->trigger_source = g_strdup(trigger_sources[i]);
667 if (!strcmp(devc->trigger_source, "AC Line"))
668 tmp_str = "ACL";
669 else if (!strcmp(devc->trigger_source, "CH1"))
670 tmp_str = "CHAN1";
671 else if (!strcmp(devc->trigger_source, "CH2"))
672 tmp_str = "CHAN2";
821fbcad
ML
673 else if (!strcmp(devc->trigger_source, "CH3"))
674 tmp_str = "CHAN3";
675 else if (!strcmp(devc->trigger_source, "CH4"))
676 tmp_str = "CHAN4";
254dd102
BV
677 else
678 tmp_str = (char *)devc->trigger_source;
38354d9d 679 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
680 break;
681 }
4e108ace 682 }
254dd102
BV
683 if (i == ARRAY_SIZE(trigger_sources))
684 ret = SR_ERR_ARG;
e0b7d23c 685 break;
1953564a 686 case SR_CONF_VDIV:
53b4680f 687 if (!cg) {
660e398f
UH
688 sr_err("No channel group specified.");
689 return SR_ERR_CHANNEL_GROUP;
be60a9e4 690 }
f6a0ac9f 691 g_variant_get(data, "(tt)", &p, &q);
f48e0249 692 for (i = 0; i < 2; i++) {
53b4680f 693 if (cg == &devc->analog_groups[i]) {
78bcc55a 694 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
695 if (vdivs[j][0] != p || vdivs[j][1] != q)
696 continue;
697 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
698 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
699 devc->vdiv[i]);
38354d9d 700 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 701 buffer);
f48e0249
ML
702 }
703 return SR_ERR_ARG;
704 }
e0b7d23c 705 }
f48e0249 706 return SR_ERR_NA;
1953564a 707 case SR_CONF_COUPLING:
53b4680f 708 if (!cg) {
660e398f
UH
709 sr_err("No channel group specified.");
710 return SR_ERR_CHANNEL_GROUP;
78bcc55a 711 }
f6a0ac9f 712 tmp_str = g_variant_get_string(data, NULL);
f48e0249 713 for (i = 0; i < 2; i++) {
53b4680f 714 if (cg == &devc->analog_groups[i]) {
78bcc55a
BV
715 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
716 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
717 g_free(devc->coupling[i]);
718 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 719 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
720 devc->coupling[i]);
721 }
722 }
723 return SR_ERR_ARG;
e0b7d23c
ML
724 }
725 }
f48e0249 726 return SR_ERR_NA;
babab622
ML
727 case SR_CONF_DATA_SOURCE:
728 tmp_str = g_variant_get_string(data, NULL);
729 if (!strcmp(tmp_str, "Live"))
730 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
731 else if (devc->model->series->protocol >= PROTOCOL_V2
732 && !strcmp(tmp_str, "Memory"))
babab622 733 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 734 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
735 && !strcmp(tmp_str, "Segmented"))
736 devc->data_source = DATA_SOURCE_SEGMENTED;
737 else
738 return SR_ERR;
739 break;
f4816ac6 740 default:
bd6fbf62 741 ret = SR_ERR_NA;
29d957ce 742 break;
f4816ac6
ML
743 }
744
745 return ret;
746}
747
8f996b89 748static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 749 const struct sr_channel_group *cg)
a1c743fc 750{
861c447b
BV
751 GVariant *tuple, *rational[2];
752 GVariantBuilder gvb;
753 unsigned int i;
7cc1a550
ML
754 struct dev_context *devc = NULL;
755
756 if (sdi)
757 devc = sdi->priv;
8f996b89 758
e43fdd8d 759 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
760 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
761 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d 762 return SR_OK;
53b4680f 763 } else if (key == SR_CONF_DEVICE_OPTIONS && cg == NULL) {
e43fdd8d
BV
764 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
765 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
766 return SR_OK;
767 }
768
769 /* Every other option requires a valid device instance. */
770 if (!sdi || !(devc = sdi->priv))
771 return SR_ERR_ARG;
772
660e398f 773 /* If a channel group is specified, it must be a valid one. */
53b4680f
UH
774 if (cg) {
775 if (cg != &devc->analog_groups[0]
776 && cg != &devc->analog_groups[1]) {
660e398f 777 sr_err("Invalid channel group specified.");
be60a9e4
BV
778 return SR_ERR;
779 }
780 }
781
e43fdd8d 782 switch (key) {
9a6517d1 783 case SR_CONF_DEVICE_OPTIONS:
53b4680f 784 if (!cg) {
660e398f
UH
785 sr_err("No channel group specified.");
786 return SR_ERR_CHANNEL_GROUP;
be60a9e4 787 }
53b4680f 788 if (cg == &devc->digital_group) {
f48e0249
ML
789 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
790 NULL, 0, sizeof(int32_t));
791 return SR_OK;
792 } else {
793 for (i = 0; i < 2; i++) {
53b4680f 794 if (cg == &devc->analog_groups[i]) {
f48e0249
ML
795 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
796 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
797 return SR_OK;
798 }
799 }
800 return SR_ERR_NA;
801 }
5f77dffc 802 break;
2a7b113d 803 case SR_CONF_COUPLING:
53b4680f 804 if (!cg) {
660e398f
UH
805 sr_err("No channel group specified.");
806 return SR_ERR_CHANNEL_GROUP;
f48e0249 807 }
58f43369
BV
808 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
809 break;
e4f2b2ad 810 case SR_CONF_VDIV:
7cc1a550
ML
811 if (!devc)
812 /* Can't know this until we have the exact model. */
813 return SR_ERR_ARG;
53b4680f 814 if (!cg) {
660e398f
UH
815 sr_err("No channel group specified.");
816 return SR_ERR_CHANNEL_GROUP;
861c447b 817 }
58f43369 818 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 819 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
820 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
821 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
822 tuple = g_variant_new_tuple(rational, 2);
823 g_variant_builder_add_value(&gvb, tuple);
824 }
825 *data = g_variant_builder_end(&gvb);
826 break;
41f5bd09 827 case SR_CONF_TIMEBASE:
7cc1a550
ML
828 if (!devc)
829 /* Can't know this until we have the exact model. */
830 return SR_ERR_ARG;
a31b2ccb
AJ
831 if (devc->num_timebases <= 0)
832 return SR_ERR_NA;
861c447b 833 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
834 for (i = 0; i < devc->num_timebases; i++) {
835 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
836 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
837 tuple = g_variant_new_tuple(rational, 2);
838 g_variant_builder_add_value(&gvb, tuple);
839 }
840 *data = g_variant_builder_end(&gvb);
41f5bd09 841 break;
328bafab 842 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
843 if (!devc)
844 /* Can't know this until we have the exact model. */
845 return SR_ERR_ARG;
f6a0ac9f 846 *data = g_variant_new_strv(trigger_sources,
bafd4890 847 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 848 break;
5d336f11
AJ
849 case SR_CONF_TRIGGER_SLOPE:
850 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
851 break;
babab622
ML
852 case SR_CONF_DATA_SOURCE:
853 if (!devc)
854 /* Can't know this until we have the exact model. */
855 return SR_ERR_ARG;
569d4dbd
ML
856 switch (devc->model->series->protocol) {
857 case PROTOCOL_V1:
858 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
859 break;
860 case PROTOCOL_V2:
babab622 861 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
862 break;
863 default:
864 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
865 break;
866 }
babab622 867 break;
a1c743fc 868 default:
bd6fbf62 869 return SR_ERR_NA;
a1c743fc
BV
870 }
871
872 return SR_OK;
873}
874
254dd102 875static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 876{
ae1bc1cc 877 struct sr_scpi_dev_inst *scpi;
29d957ce 878 struct dev_context *devc;
ba7dd8bb 879 struct sr_channel *ch;
f76c24f6 880 struct sr_datafeed_packet packet;
254dd102 881 GSList *l;
29d957ce 882
e73ffd42
BV
883 if (sdi->status != SR_ST_ACTIVE)
884 return SR_ERR_DEV_CLOSED;
e0b7d23c 885
ae1bc1cc 886 scpi = sdi->conn;
29d957ce
UH
887 devc = sdi->priv;
888
51b294cd
ML
889 devc->num_frames = 0;
890
ba7dd8bb
UH
891 for (l = sdi->channels; l; l = l->next) {
892 ch = l->data;
893 sr_dbg("handling channel %s", ch->name);
3f239f08 894 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb
UH
895 if (ch->enabled)
896 devc->enabled_analog_channels = g_slist_append(
897 devc->enabled_analog_channels, ch);
898 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 899 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
900 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
901 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 902 return SR_ERR;
ba7dd8bb 903 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 904 }
3f239f08 905 } else if (ch->type == SR_CHANNEL_LOGIC) {
ba7dd8bb
UH
906 if (ch->enabled) {
907 devc->enabled_digital_channels = g_slist_append(
908 devc->enabled_digital_channels, ch);
04e8e01e
ML
909 /* Turn on LA module if currently off. */
910 if (!devc->la_enabled) {
38354d9d 911 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
912 return SR_ERR;
913 devc->la_enabled = TRUE;
914 }
915 }
ba7dd8bb 916 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 917 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
918 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", ch->index,
919 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 920 return SR_ERR;
ba7dd8bb 921 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 922 }
254dd102
BV
923 }
924 }
1fed20cb 925
ba7dd8bb 926 if (!devc->enabled_analog_channels && !devc->enabled_digital_channels)
254dd102 927 return SR_ERR;
e0b7d23c 928
ba7dd8bb
UH
929 /* Turn off LA module if on and no digital channels selected. */
930 if (devc->la_enabled && !devc->enabled_digital_channels)
38354d9d 931 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
932 return SR_ERR;
933
e086b750
ML
934 /* Set memory mode. */
935 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
936 sr_err("Data source 'Segmented' not yet supported");
937 return SR_ERR;
938 }
939
940 devc->analog_frame_size = analog_frame_size(sdi);
941 devc->digital_frame_size = digital_frame_size(sdi);
942
569d4dbd
ML
943 switch (devc->model->series->protocol) {
944 case PROTOCOL_V2:
e086b750
ML
945 if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK)
946 return SR_ERR;
569d4dbd
ML
947 break;
948 case PROTOCOL_V3:
e086b750
ML
949 /* Apparently for the DS2000 the memory
950 * depth can only be set in Running state -
951 * this matches the behaviour of the UI. */
38354d9d 952 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 953 return SR_ERR;
e086b750
ML
954 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
955 devc->analog_frame_size) != SR_OK)
956 return SR_ERR;
957 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 958 return SR_ERR;
569d4dbd
ML
959 break;
960 default:
961 break;
1fed20cb
ML
962 }
963
e086b750
ML
964 if (devc->data_source == DATA_SOURCE_LIVE)
965 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
966 return SR_ERR;
967
ae1bc1cc 968 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
969
970 /* Send header packet to the session bus. */
29a27196 971 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 972
ba7dd8bb
UH
973 if (devc->enabled_analog_channels)
974 devc->channel_entry = devc->enabled_analog_channels;
821fbcad 975 else
ba7dd8bb 976 devc->channel_entry = devc->enabled_digital_channels;
821fbcad 977
e086b750
ML
978 if (rigol_ds_capture_start(sdi) != SR_OK)
979 return SR_ERR;
f4816ac6 980
f76c24f6
ML
981 /* Start of first frame. */
982 packet.type = SR_DF_FRAME_BEGIN;
983 sr_session_send(cb_data, &packet);
984
f4816ac6
ML
985 return SR_OK;
986}
987
254dd102 988static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 989{
29d957ce 990 struct dev_context *devc;
ae1bc1cc 991 struct sr_scpi_dev_inst *scpi;
b751cf7a 992 struct sr_datafeed_packet packet;
29d957ce 993
f4816ac6
ML
994 (void)cb_data;
995
29d957ce
UH
996 devc = sdi->priv;
997
f4816ac6
ML
998 if (sdi->status != SR_ST_ACTIVE) {
999 sr_err("Device inactive, can't stop acquisition.");
1000 return SR_ERR;
1001 }
1002
b751cf7a
ML
1003 /* End of last frame. */
1004 packet.type = SR_DF_END;
1005 sr_session_send(sdi, &packet);
1006
ba7dd8bb
UH
1007 g_slist_free(devc->enabled_analog_channels);
1008 g_slist_free(devc->enabled_digital_channels);
1009 devc->enabled_analog_channels = NULL;
1010 devc->enabled_digital_channels = NULL;
ae1bc1cc
ML
1011 scpi = sdi->conn;
1012 sr_scpi_source_remove(scpi);
f4816ac6
ML
1013
1014 return SR_OK;
1015}
1016
3086efdd
ML
1017SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1018 .name = "rigol-ds",
1019 .longname = "Rigol DS",
f4816ac6 1020 .api_version = 1,
6078d2c9
UH
1021 .init = init,
1022 .cleanup = cleanup,
1023 .scan = scan,
1024 .dev_list = dev_list,
3b412e3a 1025 .dev_clear = dev_clear,
d62d7ad1 1026 .config_get = config_get,
035a1078 1027 .config_set = config_set,
a1c743fc 1028 .config_list = config_list,
6078d2c9
UH
1029 .dev_open = dev_open,
1030 .dev_close = dev_close,
254dd102
BV
1031 .dev_acquisition_start = dev_acquisition_start,
1032 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1033 .priv = NULL,
1034};