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