]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
drivers: Provide proper drvopts.
[libsigrok.git] / src / 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
6ec6c43b 22#include <config.h>
e0b7d23c
ML
23#include <fcntl.h>
24#include <unistd.h>
25#include <stdlib.h>
26#include <string.h>
ba464a12 27#include <strings.h>
2b0e4a46 28#include <math.h>
f4816ac6 29#include <glib.h>
c1aae900 30#include <libsigrok/libsigrok.h>
f4816ac6 31#include "libsigrok-internal.h"
5a1afc09 32#include "scpi.h"
f4816ac6
ML
33#include "protocol.h"
34
a0e0bb41 35static const uint32_t scanopts[] = {
ca55277c 36 SR_CONF_CONN,
05199c0a 37 SR_CONF_SERIALCOMM,
ca55277c
ML
38};
39
d73aacf1 40static const uint32_t drvopts[] = {
1953564a 41 SR_CONF_OSCILLOSCOPE,
d73aacf1
SA
42};
43
44static const uint32_t devopts[] = {
5827f61b 45 SR_CONF_LIMIT_FRAMES | SR_CONF_SET,
86621306 46 SR_CONF_SAMPLERATE | SR_CONF_GET,
5827f61b 47 SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
86621306
UH
48 SR_CONF_NUM_HDIV | SR_CONF_GET,
49 SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_SET,
5827f61b 50 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
b0c9d1d1 51 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
9ea62f2e 52 SR_CONF_TRIGGER_LEVEL | SR_CONF_GET | SR_CONF_SET,
f579d08b 53 SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
f48e0249
ML
54};
55
f254bc4b 56static const uint32_t analog_devopts[] = {
5827f61b
BV
57 SR_CONF_NUM_VDIV | SR_CONF_GET,
58 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
59 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
934cf6cf 60 SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
e0b7d23c
ML
61};
62
f6a0ac9f 63static const uint64_t timebases[][2] = {
e0b7d23c 64 /* nanoseconds */
8e06edf5 65 { 1, 1000000000 },
e0b7d23c
ML
66 { 2, 1000000000 },
67 { 5, 1000000000 },
68 { 10, 1000000000 },
69 { 20, 1000000000 },
70 { 50, 1000000000 },
71 { 100, 1000000000 },
72 { 500, 1000000000 },
73 /* microseconds */
74 { 1, 1000000 },
75 { 2, 1000000 },
76 { 5, 1000000 },
77 { 10, 1000000 },
78 { 20, 1000000 },
79 { 50, 1000000 },
80 { 100, 1000000 },
81 { 200, 1000000 },
82 { 500, 1000000 },
83 /* milliseconds */
84 { 1, 1000 },
85 { 2, 1000 },
86 { 5, 1000 },
87 { 10, 1000 },
88 { 20, 1000 },
89 { 50, 1000 },
90 { 100, 1000 },
91 { 200, 1000 },
92 { 500, 1000 },
93 /* seconds */
94 { 1, 1 },
95 { 2, 1 },
96 { 5, 1 },
97 { 10, 1 },
98 { 20, 1 },
99 { 50, 1 },
bafd4890
ML
100 { 100, 1 },
101 { 200, 1 },
102 { 500, 1 },
8e06edf5 103 { 1000, 1 },
e0b7d23c
ML
104};
105
f6a0ac9f 106static const uint64_t vdivs[][2] = {
bafd4890
ML
107 /* microvolts */
108 { 500, 1000000 },
e0b7d23c 109 /* millivolts */
bafd4890 110 { 1, 1000 },
e0b7d23c
ML
111 { 2, 1000 },
112 { 5, 1000 },
113 { 10, 1000 },
114 { 20, 1000 },
115 { 50, 1000 },
116 { 100, 1000 },
117 { 200, 1000 },
118 { 500, 1000 },
119 /* volts */
120 { 1, 1 },
121 { 2, 1 },
122 { 5, 1 },
123 { 10, 1 },
d50725e0
UH
124 { 20, 1 },
125 { 50, 1 },
126 { 100, 1 },
e0b7d23c
ML
127};
128
bafd4890
ML
129#define NUM_TIMEBASE ARRAY_SIZE(timebases)
130#define NUM_VDIV ARRAY_SIZE(vdivs)
131
e0b7d23c
ML
132static const char *trigger_sources[] = {
133 "CH1",
134 "CH2",
821fbcad
ML
135 "CH3",
136 "CH4",
e0b7d23c
ML
137 "EXT",
138 "AC Line",
6bb192bc
ML
139 "D0",
140 "D1",
141 "D2",
142 "D3",
143 "D4",
144 "D5",
145 "D6",
146 "D7",
147 "D8",
148 "D9",
149 "D10",
150 "D11",
151 "D12",
152 "D13",
153 "D14",
154 "D15",
e0b7d23c
ML
155};
156
5d336f11
AJ
157static const char *trigger_slopes[] = {
158 "r",
159 "f",
160};
161
e0b7d23c
ML
162static const char *coupling[] = {
163 "AC",
164 "DC",
165 "GND",
e0b7d23c
ML
166};
167
934cf6cf
AJ
168static const uint64_t probe_factor[] = {
169 1,
170 2,
171 5,
172 10,
173 20,
174 50,
175 100,
176 200,
177 500,
178 1000,
179};
180
babab622
ML
181/* Do not change the order of entries */
182static const char *data_sources[] = {
183 "Live",
184 "Memory",
185 "Segmented",
186};
187
569d4dbd
ML
188enum vendor {
189 RIGOL,
190 AGILENT,
191};
192
193enum series {
194 VS5000,
195 DS1000,
196 DS2000,
197 DS2000A,
198 DSO1000,
702f42e8 199 DS1000Z,
569d4dbd 200};
10afee13 201
569d4dbd
ML
202/* short name, full name */
203static const struct rigol_ds_vendor supported_vendors[] = {
204 [RIGOL] = {"Rigol", "Rigol Technologies"},
14e1aa6d 205 [AGILENT] = {"Agilent", "Agilent Technologies"},
569d4dbd
ML
206};
207
208#define VENDOR(x) &supported_vendors[x]
209/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
210 * live waveform samples, memory buffer samples */
211static const struct rigol_ds_series supported_series[] = {
212 [VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
213 {50, 1}, {2, 1000}, 14, 2048, 0},
214 [DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
215 {50, 1}, {2, 1000}, 12, 600, 1048576},
216 [DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
96cb7faa 217 {500, 1}, {500, 1000000}, 14, 1400, 14000},
569d4dbd
ML
218 [DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
219 {1000, 1}, {500, 1000000}, 14, 1400, 14000},
220 [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
221 {50, 1}, {2, 1000}, 12, 600, 20480},
702f42e8
ML
222 [DS1000Z] = {VENDOR(RIGOL), "DS1000Z", PROTOCOL_V4, FORMAT_IEEE488_2,
223 {50, 1}, {1, 1000}, 12, 1200, 12000000},
569d4dbd 224};
10afee13 225
569d4dbd
ML
226#define SERIES(x) &supported_series[x]
227/* series, model, min timebase, analog channels, digital */
bafd4890 228static const struct rigol_ds_model supported_models[] = {
569d4dbd
ML
229 {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
230 {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
231 {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
232 {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
233 {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
234 {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
235 {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
236 {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
237 {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
238 {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
239 {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
240 {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
241 {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
242 {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
243 {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
244 {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
245 {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
246 {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
247 {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
248 {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
249 {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
250 {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
251 {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
252 {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
09f24ef2
ML
253 {SERIES(DS2000A), "MSO2072A", {5, 1000000000}, 2, true},
254 {SERIES(DS2000A), "MSO2102A", {5, 1000000000}, 2, true},
255 {SERIES(DS2000A), "MSO2202A", {2, 1000000000}, 2, true},
256 {SERIES(DS2000A), "MSO2302A", {1, 1000000000}, 2, true},
569d4dbd
ML
257 {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
258 {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
259 {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
260 {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
261 {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
262 {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
702f42e8
ML
263 {SERIES(DS1000Z), "DS1054Z", {5, 1000000000}, 4, false},
264 {SERIES(DS1000Z), "DS1074Z", {5, 1000000000}, 4, false},
265 {SERIES(DS1000Z), "DS1104Z", {5, 1000000000}, 4, false},
266 {SERIES(DS1000Z), "DS1074Z-S", {5, 1000000000}, 4, false},
267 {SERIES(DS1000Z), "DS1104Z-S", {5, 1000000000}, 4, false},
d53295e6
KK
268 {SERIES(DS1000Z), "DS1074Z Plus", {5, 1000000000}, 4, false},
269 {SERIES(DS1000Z), "DS1104Z Plus", {5, 1000000000}, 4, false},
702f42e8
ML
270 {SERIES(DS1000Z), "MSO1074Z", {5, 1000000000}, 4, true},
271 {SERIES(DS1000Z), "MSO1104Z", {5, 1000000000}, 4, true},
272 {SERIES(DS1000Z), "MSO1074Z-S", {5, 1000000000}, 4, true},
273 {SERIES(DS1000Z), "MSO1104Z-S", {5, 1000000000}, 4, true},
512bb890
BV
274};
275
dd5c48a6 276static struct sr_dev_driver rigol_ds_driver_info;
f4816ac6 277
3553451f 278static void clear_helper(struct dev_context *devc)
f4816ac6 279{
effb9dd1 280 unsigned int i;
f4816ac6 281
babab622
ML
282 g_free(devc->data);
283 g_free(devc->buffer);
effb9dd1
AJ
284 for (i = 0; i < ARRAY_SIZE(devc->coupling); i++)
285 g_free(devc->coupling[i]);
fa85f376
UH
286 g_free(devc->trigger_source);
287 g_free(devc->trigger_slope);
562b7ae5 288 g_free(devc->analog_groups);
fa85f376 289}
f4816ac6 290
4f840ce9 291static int dev_clear(const struct sr_dev_driver *di)
fa85f376 292{
3553451f 293 return std_dev_clear_with_callback(di, (std_dev_clear_callback)clear_helper);
f4816ac6
ML
294}
295
9d3ae01b 296static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
f4816ac6 297{
cc9fd2d2
BV
298 struct dev_context *devc;
299 struct sr_dev_inst *sdi;
ae1bc1cc 300 struct sr_scpi_hw_info *hw_info;
ba7dd8bb 301 struct sr_channel *ch;
8dd0b290 302 long n[3];
f6a0ac9f 303 unsigned int i;
bafd4890 304 const struct rigol_ds_model *model = NULL;
569d4dbd 305 gchar *channel_name, **version;
fb6e5ba8 306
ae1bc1cc 307 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
05238d28
ML
308 sr_info("Couldn't get IDN response, retrying.");
309 sr_scpi_close(scpi);
310 sr_scpi_open(scpi);
311 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
312 sr_info("Couldn't get IDN response.");
313 return NULL;
314 }
ca55277c 315 }
e0b7d23c 316
ca55277c 317 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
34577da6 318 if (!g_ascii_strcasecmp(hw_info->manufacturer,
569d4dbd 319 supported_models[i].series->vendor->full_name) &&
10afee13 320 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 321 model = &supported_models[i];
ca55277c 322 break;
fb6e5ba8 323 }
ca55277c 324 }
fb6e5ba8 325
0af636be 326 if (!model) {
ae1bc1cc 327 sr_scpi_hw_info_free(hw_info);
9d3ae01b 328 return NULL;
ca55277c 329 }
fb6e5ba8 330
aac29cc1 331 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
332 sdi->vendor = g_strdup(model->series->vendor->name);
333 sdi->model = g_strdup(model->name);
334 sdi->version = g_strdup(hw_info->firmware_version);
ae1bc1cc 335 sdi->conn = scpi;
4f840ce9 336 sdi->driver = &rigol_ds_driver_info;
ae1bc1cc 337 sdi->inst_type = SR_INST_SCPI;
b3fccc85 338 sdi->serial_num = g_strdup(hw_info->serial_number);
f57d8ffe 339 devc = g_malloc0(sizeof(struct dev_context));
cc9fd2d2 340 devc->limit_frames = 0;
bafd4890 341 devc->model = model;
569d4dbd 342 devc->format = model->series->format;
8dd0b290 343
569d4dbd
ML
344 /* DS1000 models with firmware before 0.2.4 used the old data format. */
345 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
346 version = g_strsplit(hw_info->firmware_version, ".", 0);
347 do {
348 if (!version[0] || !version[1] || !version[2])
349 break;
350 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
351 break;
352 for (i = 0; i < 3; i++) {
353 if (sr_atol(version[i], &n[i]) != SR_OK)
354 break;
355 }
356 if (i != 3)
357 break;
de285cce
BV
358 scpi->firmware_version = n[0] * 100 + n[1] * 10 + n[2];
359 if (scpi->firmware_version < 24) {
360 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
361 devc->format = FORMAT_RAW;
362 }
363 break;
0c5f2abc 364 } while (0);
8dd0b290
BV
365 g_strfreev(version);
366 }
367
368 sr_scpi_hw_info_free(hw_info);
512bb890 369
562b7ae5
SA
370 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
371 model->analog_channels);
372
821fbcad 373 for (i = 0; i < model->analog_channels; i++) {
eac0c613 374 channel_name = g_strdup_printf("CH%d", i + 1);
5e23fcab 375 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_name);
562b7ae5
SA
376
377 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
378
379 devc->analog_groups[i]->name = channel_name;
380 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
660e398f 381 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 382 devc->analog_groups[i]);
ca55277c 383 }
512bb890 384
bafd4890 385 if (devc->model->has_digital) {
16aca766 386 devc->digital_group = g_malloc0(sizeof(struct sr_channel_group));
562b7ae5 387
effb9dd1 388 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
eac0c613 389 channel_name = g_strdup_printf("D%d", i);
5e23fcab 390 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ca55277c 391 g_free(channel_name);
562b7ae5
SA
392 devc->digital_group->channels = g_slist_append(
393 devc->digital_group->channels, ch);
512bb890 394 }
562b7ae5 395 devc->digital_group->name = g_strdup("LA");
660e398f 396 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 397 devc->digital_group);
ca55277c 398 }
bafd4890
ML
399
400 for (i = 0; i < NUM_TIMEBASE; i++) {
401 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
402 devc->timebases = &timebases[i];
569d4dbd 403 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
404 devc->num_timebases = &timebases[i] - devc->timebases + 1;
405 }
406
a95f142e
UH
407 for (i = 0; i < NUM_VDIV; i++) {
408 if (!memcmp(&devc->model->series->min_vdiv,
409 &vdivs[i], sizeof(uint64_t[2]))) {
6ff1394e 410 devc->vdivs = &vdivs[i];
81b85663
AJ
411 devc->num_vdivs = NUM_VDIV - i;
412 }
a95f142e 413 }
bafd4890 414
a95f142e
UH
415 devc->buffer = g_malloc(ACQ_BUFFER_SIZE);
416 devc->data = g_malloc(ACQ_BUFFER_SIZE * sizeof(float));
babab622
ML
417
418 devc->data_source = DATA_SOURCE_LIVE;
419
cc9fd2d2
BV
420 sdi->priv = devc;
421
9d3ae01b 422 return sdi;
ca55277c 423}
512bb890 424
4f840ce9 425static GSList *scan(struct sr_dev_driver *di, GSList *options)
ca55277c 426{
41812aca 427 return sr_scpi_scan(di->context, options, probe_device);
f4816ac6
ML
428}
429
6078d2c9 430static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 431{
e1b5b7e7 432 int ret;
ae1bc1cc 433 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 434
e1b5b7e7
UH
435 if ((ret = sr_scpi_open(scpi)) < 0) {
436 sr_err("Failed to open SCPI device: %s.", sr_strerror(ret));
e0b7d23c 437 return SR_ERR;
e1b5b7e7 438 }
e0b7d23c 439
e1b5b7e7
UH
440 if ((ret = rigol_ds_get_dev_cfg(sdi)) < 0) {
441 sr_err("Failed to get device config: %s.", sr_strerror(ret));
254dd102 442 return SR_ERR;
e1b5b7e7 443 }
f4816ac6
ML
444
445 return SR_OK;
446}
447
6078d2c9 448static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 449{
ae1bc1cc 450 struct sr_scpi_dev_inst *scpi;
22c19688 451 struct dev_context *devc;
ae1bc1cc
ML
452
453 scpi = sdi->conn;
22c19688
ML
454 devc = sdi->priv;
455
f1ba6b4b
UH
456 if (!scpi)
457 return SR_ERR_BUG;
458
6e94eb41 459 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 460 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 461
f1ba6b4b 462 return sr_scpi_close(scpi);
f4816ac6
ML
463}
464
5415e602
ML
465static int analog_frame_size(const struct sr_dev_inst *sdi)
466{
467 struct dev_context *devc = sdi->priv;
ba7dd8bb
UH
468 struct sr_channel *ch;
469 int analog_channels = 0;
5415e602
ML
470 GSList *l;
471
ba7dd8bb
UH
472 for (l = sdi->channels; l; l = l->next) {
473 ch = l->data;
3f239f08 474 if (ch->type == SR_CHANNEL_ANALOG && ch->enabled)
ba7dd8bb 475 analog_channels++;
569d4dbd
ML
476 }
477
ba7dd8bb 478 if (analog_channels == 0)
824eb2ac
ML
479 return 0;
480
569d4dbd
ML
481 switch (devc->data_source) {
482 case DATA_SOURCE_LIVE:
483 return devc->model->series->live_samples;
484 case DATA_SOURCE_MEMORY:
ba7dd8bb 485 return devc->model->series->buffer_samples / analog_channels;
470140fc 486 default:
569d4dbd 487 return 0;
5415e602
ML
488 }
489}
490
d22250a9
ML
491static int digital_frame_size(const struct sr_dev_inst *sdi)
492{
493 struct dev_context *devc = sdi->priv;
494
569d4dbd
ML
495 switch (devc->data_source) {
496 case DATA_SOURCE_LIVE:
497 return devc->model->series->live_samples * 2;
498 case DATA_SOURCE_MEMORY:
499 return devc->model->series->buffer_samples * 2;
d22250a9
ML
500 default:
501 return 0;
502 }
503}
504
584560f1 505static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 506 const struct sr_channel_group *cg)
d62d7ad1 507{
e43fdd8d 508 struct dev_context *devc;
ba7dd8bb 509 struct sr_channel *ch;
2b0e4a46 510 const char *tmp_str;
c2b394d5 511 uint64_t samplerate;
2b0e4a46 512 int analog_channel = -1;
c33ff377 513 float smallest_diff = INFINITY;
2b0e4a46
AJ
514 int idx = -1;
515 unsigned i;
d62d7ad1 516
709468ba 517 if (!sdi)
e43fdd8d
BV
518 return SR_ERR_ARG;
519
709468ba
UH
520 devc = sdi->priv;
521
660e398f 522 /* If a channel group is specified, it must be a valid one. */
53b4680f 523 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 524 sr_err("Invalid channel group specified.");
969edf63 525 return SR_ERR;
be60a9e4
BV
526 }
527
53b4680f 528 if (cg) {
ba7dd8bb
UH
529 ch = g_slist_nth_data(cg->channels, 0);
530 if (!ch)
2b0e4a46 531 return SR_ERR;
3f239f08 532 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 533 if (ch->name[2] < '1' || ch->name[2] > '4')
2b0e4a46 534 return SR_ERR;
ba7dd8bb 535 analog_channel = ch->name[2] - '1';
2b0e4a46
AJ
536 }
537 }
538
584560f1 539 switch (key) {
bf622e6d 540 case SR_CONF_NUM_HDIV:
569d4dbd 541 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
542 break;
543 case SR_CONF_NUM_VDIV:
81b85663 544 *data = g_variant_new_int32(devc->num_vdivs);
f44f7e61 545 break;
babab622
ML
546 case SR_CONF_DATA_SOURCE:
547 if (devc->data_source == DATA_SOURCE_LIVE)
548 *data = g_variant_new_string("Live");
549 else if (devc->data_source == DATA_SOURCE_MEMORY)
550 *data = g_variant_new_string("Memory");
551 else
552 *data = g_variant_new_string("Segmented");
553 break;
4914dd4b
ML
554 case SR_CONF_SAMPLERATE:
555 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 556 samplerate = analog_frame_size(sdi) /
569d4dbd 557 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 558 *data = g_variant_new_uint64(samplerate);
c2b394d5 559 } else {
e1b5b7e7 560 sr_dbg("Unknown data source: %d.", devc->data_source);
4914dd4b 561 return SR_ERR_NA;
c2b394d5 562 }
4914dd4b 563 break;
2b0e4a46
AJ
564 case SR_CONF_TRIGGER_SOURCE:
565 if (!strcmp(devc->trigger_source, "ACL"))
566 tmp_str = "AC Line";
567 else if (!strcmp(devc->trigger_source, "CHAN1"))
568 tmp_str = "CH1";
569 else if (!strcmp(devc->trigger_source, "CHAN2"))
570 tmp_str = "CH2";
571 else if (!strcmp(devc->trigger_source, "CHAN3"))
572 tmp_str = "CH3";
573 else if (!strcmp(devc->trigger_source, "CHAN4"))
574 tmp_str = "CH4";
575 else
576 tmp_str = devc->trigger_source;
577 *data = g_variant_new_string(tmp_str);
578 break;
5d336f11 579 case SR_CONF_TRIGGER_SLOPE:
e1b5b7e7 580 if (!strncmp(devc->trigger_slope, "POS", 3)) {
5d336f11 581 tmp_str = "r";
e1b5b7e7 582 } else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
5d336f11 583 tmp_str = "f";
e1b5b7e7
UH
584 } else {
585 sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
5d336f11 586 return SR_ERR_NA;
e1b5b7e7 587 }
5d336f11
AJ
588 *data = g_variant_new_string(tmp_str);
589 break;
9ea62f2e
AJ
590 case SR_CONF_TRIGGER_LEVEL:
591 *data = g_variant_new_double(devc->trigger_level);
592 break;
2b0e4a46
AJ
593 case SR_CONF_TIMEBASE:
594 for (i = 0; i < devc->num_timebases; i++) {
595 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
596 float diff = fabs(devc->timebase - tb);
597 if (diff < smallest_diff) {
598 smallest_diff = diff;
599 idx = i;
600 }
601 }
e1b5b7e7
UH
602 if (idx < 0) {
603 sr_dbg("Negative timebase index: %d.", idx);
2b0e4a46 604 return SR_ERR_NA;
e1b5b7e7 605 }
2b0e4a46
AJ
606 *data = g_variant_new("(tt)", devc->timebases[idx][0],
607 devc->timebases[idx][1]);
608 break;
609 case SR_CONF_VDIV:
e1b5b7e7
UH
610 if (analog_channel < 0) {
611 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 612 return SR_ERR_NA;
e1b5b7e7 613 }
2b0e4a46
AJ
614 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
615 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
616 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
617 if (diff < smallest_diff) {
618 smallest_diff = diff;
619 idx = i;
620 }
621 }
e1b5b7e7
UH
622 if (idx < 0) {
623 sr_dbg("Negative vdiv index: %d.", idx);
2b0e4a46 624 return SR_ERR_NA;
e1b5b7e7 625 }
2b0e4a46
AJ
626 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
627 break;
628 case SR_CONF_COUPLING:
e1b5b7e7
UH
629 if (analog_channel < 0) {
630 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 631 return SR_ERR_NA;
e1b5b7e7 632 }
2b0e4a46
AJ
633 *data = g_variant_new_string(devc->coupling[analog_channel]);
634 break;
934cf6cf
AJ
635 case SR_CONF_PROBE_FACTOR:
636 if (analog_channel < 0) {
637 sr_dbg("Negative analog channel: %d.", analog_channel);
638 return SR_ERR_NA;
639 }
640 *data = g_variant_new_uint64(devc->attenuation[analog_channel]);
641 break;
d62d7ad1 642 default:
bd6fbf62 643 return SR_ERR_NA;
d62d7ad1
BV
644 }
645
646 return SR_OK;
647}
648
584560f1 649static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 650 const struct sr_channel_group *cg)
f4816ac6 651{
29d957ce 652 struct dev_context *devc;
ca9b9f48 653 uint64_t p, q;
254dd102 654 double t_dbl;
f48e0249 655 unsigned int i, j;
254dd102
BV
656 int ret;
657 const char *tmp_str;
889ef4a0 658 char buffer[16];
f4816ac6 659
b0baddef 660 devc = sdi->priv;
29d957ce 661
660e398f 662 /* If a channel group is specified, it must be a valid one. */
53b4680f 663 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 664 sr_err("Invalid channel group specified.");
969edf63 665 return SR_ERR;
be60a9e4
BV
666 }
667
f4816ac6 668 ret = SR_OK;
584560f1 669 switch (key) {
1953564a 670 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 671 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 672 break;
1953564a 673 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
674 tmp_str = g_variant_get_string(data, NULL);
675
e1b5b7e7
UH
676 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
677 sr_err("Unknown trigger slope: '%s'.",
678 (tmp_str) ? tmp_str : "NULL");
ca9b9f48 679 return SR_ERR_ARG;
e1b5b7e7 680 }
ca9b9f48 681
254dd102 682 g_free(devc->trigger_slope);
ca9b9f48 683 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 684 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 685 break;
1953564a 686 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102 687 t_dbl = g_variant_get_double(data);
e1b5b7e7
UH
688 if (t_dbl < 0.0 || t_dbl > 1.0) {
689 sr_err("Invalid horiz. trigger position: %g.", t_dbl);
254dd102 690 return SR_ERR;
e1b5b7e7 691 }
254dd102
BV
692 devc->horiz_triggerpos = t_dbl;
693 /* We have the trigger offset as a percentage of the frame, but
694 * need to express this in seconds. */
bafd4890 695 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 696 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 697 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 698 break;
9ea62f2e
AJ
699 case SR_CONF_TRIGGER_LEVEL:
700 t_dbl = g_variant_get_double(data);
701 g_ascii_formatd(buffer, sizeof(buffer), "%.3f", t_dbl);
702 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:LEV %s", buffer);
703 if (ret == SR_OK)
704 devc->trigger_level = t_dbl;
705 break;
1953564a 706 case SR_CONF_TIMEBASE:
f6a0ac9f 707 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
708 for (i = 0; i < devc->num_timebases; i++) {
709 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 710 devc->timebase = (float)p / q;
889ef4a0
AJ
711 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
712 devc->timebase);
38354d9d 713 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
714 break;
715 }
716 }
e1b5b7e7
UH
717 if (i == devc->num_timebases) {
718 sr_err("Invalid timebase index: %d.", i);
254dd102 719 ret = SR_ERR_ARG;
e1b5b7e7 720 }
e0b7d23c 721 break;
1953564a 722 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 723 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
724 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
725 if (!strcmp(trigger_sources[i], tmp_str)) {
726 g_free(devc->trigger_source);
727 devc->trigger_source = g_strdup(trigger_sources[i]);
728 if (!strcmp(devc->trigger_source, "AC Line"))
729 tmp_str = "ACL";
730 else if (!strcmp(devc->trigger_source, "CH1"))
731 tmp_str = "CHAN1";
732 else if (!strcmp(devc->trigger_source, "CH2"))
733 tmp_str = "CHAN2";
821fbcad
ML
734 else if (!strcmp(devc->trigger_source, "CH3"))
735 tmp_str = "CHAN3";
736 else if (!strcmp(devc->trigger_source, "CH4"))
737 tmp_str = "CHAN4";
254dd102
BV
738 else
739 tmp_str = (char *)devc->trigger_source;
38354d9d 740 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
741 break;
742 }
4e108ace 743 }
e1b5b7e7
UH
744 if (i == ARRAY_SIZE(trigger_sources)) {
745 sr_err("Invalid trigger source index: %d.", i);
254dd102 746 ret = SR_ERR_ARG;
e1b5b7e7 747 }
e0b7d23c 748 break;
1953564a 749 case SR_CONF_VDIV:
53b4680f 750 if (!cg) {
660e398f
UH
751 sr_err("No channel group specified.");
752 return SR_ERR_CHANNEL_GROUP;
be60a9e4 753 }
f6a0ac9f 754 g_variant_get(data, "(tt)", &p, &q);
effb9dd1 755 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 756 if (cg == devc->analog_groups[i]) {
78bcc55a 757 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
758 if (vdivs[j][0] != p || vdivs[j][1] != q)
759 continue;
760 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
761 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
762 devc->vdiv[i]);
38354d9d 763 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 764 buffer);
f48e0249 765 }
e1b5b7e7 766 sr_err("Invalid vdiv index: %d.", j);
f48e0249
ML
767 return SR_ERR_ARG;
768 }
e0b7d23c 769 }
e1b5b7e7 770 sr_dbg("Didn't set vdiv, unknown channel(group).");
f48e0249 771 return SR_ERR_NA;
1953564a 772 case SR_CONF_COUPLING:
53b4680f 773 if (!cg) {
660e398f
UH
774 sr_err("No channel group specified.");
775 return SR_ERR_CHANNEL_GROUP;
78bcc55a 776 }
f6a0ac9f 777 tmp_str = g_variant_get_string(data, NULL);
effb9dd1 778 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 779 if (cg == devc->analog_groups[i]) {
78bcc55a
BV
780 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
781 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
782 g_free(devc->coupling[i]);
783 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 784 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
785 devc->coupling[i]);
786 }
787 }
e1b5b7e7 788 sr_err("Invalid coupling index: %d.", j);
f48e0249 789 return SR_ERR_ARG;
e0b7d23c
ML
790 }
791 }
e1b5b7e7 792 sr_dbg("Didn't set coupling, unknown channel(group).");
f48e0249 793 return SR_ERR_NA;
934cf6cf
AJ
794 case SR_CONF_PROBE_FACTOR:
795 if (!cg) {
796 sr_err("No channel group specified.");
797 return SR_ERR_CHANNEL_GROUP;
798 }
799 p = g_variant_get_uint64(data);
800 for (i = 0; i < devc->model->analog_channels; i++) {
801 if (cg == devc->analog_groups[i]) {
802 for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
803 if (p == probe_factor[j]) {
804 devc->attenuation[i] = p;
805 ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
806 i + 1, p);
807 if (ret == SR_OK)
808 rigol_ds_get_dev_cfg_vertical(sdi);
809 return ret;
810 }
811 }
812 sr_err("Invalid probe factor: %"PRIu64".", p);
813 return SR_ERR_ARG;
814 }
815 }
816 sr_dbg("Didn't set probe factor, unknown channel(group).");
817 return SR_ERR_NA;
babab622
ML
818 case SR_CONF_DATA_SOURCE:
819 tmp_str = g_variant_get_string(data, NULL);
820 if (!strcmp(tmp_str, "Live"))
821 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
822 else if (devc->model->series->protocol >= PROTOCOL_V2
823 && !strcmp(tmp_str, "Memory"))
babab622 824 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 825 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
826 && !strcmp(tmp_str, "Segmented"))
827 devc->data_source = DATA_SOURCE_SEGMENTED;
e1b5b7e7
UH
828 else {
829 sr_err("Unknown data source: '%s'.", tmp_str);
babab622 830 return SR_ERR;
e1b5b7e7 831 }
babab622 832 break;
f4816ac6 833 default:
dcd438ee 834 return SR_ERR_NA;
f4816ac6
ML
835 }
836
837 return ret;
838}
839
584560f1 840static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 841 const struct sr_channel_group *cg)
a1c743fc 842{
861c447b
BV
843 GVariant *tuple, *rational[2];
844 GVariantBuilder gvb;
845 unsigned int i;
e66d1892 846 struct dev_context *devc;
e43fdd8d 847
e66d1892 848 devc = (sdi) ? sdi->priv : NULL;
be60a9e4 849
e43fdd8d 850 switch (key) {
e66d1892 851 case SR_CONF_SCAN_OPTIONS:
9a6517d1 852 case SR_CONF_DEVICE_OPTIONS:
e66d1892
UH
853 if (!cg)
854 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
562b7ae5 855 if (cg == devc->digital_group) {
584560f1
BV
856 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
857 NULL, 0, sizeof(uint32_t));
f48e0249
ML
858 return SR_OK;
859 } else {
effb9dd1 860 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 861 if (cg == devc->analog_groups[i]) {
584560f1 862 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 863 analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
f48e0249
ML
864 return SR_OK;
865 }
866 }
867 return SR_ERR_NA;
868 }
5f77dffc 869 break;
2a7b113d 870 case SR_CONF_COUPLING:
e66d1892 871 if (!cg)
660e398f 872 return SR_ERR_CHANNEL_GROUP;
58f43369
BV
873 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
874 break;
934cf6cf 875 case SR_CONF_PROBE_FACTOR:
e66d1892 876 if (!cg)
934cf6cf 877 return SR_ERR_CHANNEL_GROUP;
934cf6cf
AJ
878 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
879 probe_factor, ARRAY_SIZE(probe_factor), sizeof(uint64_t));
880 break;
e4f2b2ad 881 case SR_CONF_VDIV:
7cc1a550
ML
882 if (!devc)
883 /* Can't know this until we have the exact model. */
884 return SR_ERR_ARG;
e66d1892 885 if (!cg)
660e398f 886 return SR_ERR_CHANNEL_GROUP;
58f43369 887 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
81b85663 888 for (i = 0; i < devc->num_vdivs; i++) {
bafd4890
ML
889 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
890 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
891 tuple = g_variant_new_tuple(rational, 2);
892 g_variant_builder_add_value(&gvb, tuple);
893 }
894 *data = g_variant_builder_end(&gvb);
895 break;
41f5bd09 896 case SR_CONF_TIMEBASE:
7cc1a550
ML
897 if (!devc)
898 /* Can't know this until we have the exact model. */
899 return SR_ERR_ARG;
a31b2ccb
AJ
900 if (devc->num_timebases <= 0)
901 return SR_ERR_NA;
861c447b 902 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
903 for (i = 0; i < devc->num_timebases; i++) {
904 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
905 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
906 tuple = g_variant_new_tuple(rational, 2);
907 g_variant_builder_add_value(&gvb, tuple);
908 }
909 *data = g_variant_builder_end(&gvb);
41f5bd09 910 break;
328bafab 911 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
912 if (!devc)
913 /* Can't know this until we have the exact model. */
914 return SR_ERR_ARG;
f6a0ac9f 915 *data = g_variant_new_strv(trigger_sources,
bafd4890 916 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 917 break;
5d336f11
AJ
918 case SR_CONF_TRIGGER_SLOPE:
919 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
920 break;
babab622
ML
921 case SR_CONF_DATA_SOURCE:
922 if (!devc)
923 /* Can't know this until we have the exact model. */
924 return SR_ERR_ARG;
569d4dbd
ML
925 switch (devc->model->series->protocol) {
926 case PROTOCOL_V1:
927 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
928 break;
929 case PROTOCOL_V2:
babab622 930 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
931 break;
932 default:
933 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
934 break;
935 }
babab622 936 break;
a1c743fc 937 default:
bd6fbf62 938 return SR_ERR_NA;
a1c743fc
BV
939 }
940
941 return SR_OK;
942}
943
695dc859 944static int dev_acquisition_start(const struct sr_dev_inst *sdi)
f4816ac6 945{
ae1bc1cc 946 struct sr_scpi_dev_inst *scpi;
29d957ce 947 struct dev_context *devc;
ba7dd8bb 948 struct sr_channel *ch;
f76c24f6 949 struct sr_datafeed_packet packet;
702f42e8 950 gboolean some_digital;
254dd102 951 GSList *l;
29d957ce 952
ae1bc1cc 953 scpi = sdi->conn;
29d957ce
UH
954 devc = sdi->priv;
955
51b294cd
ML
956 devc->num_frames = 0;
957
702f42e8 958 some_digital = FALSE;
ba7dd8bb
UH
959 for (l = sdi->channels; l; l = l->next) {
960 ch = l->data;
961 sr_dbg("handling channel %s", ch->name);
3f239f08 962 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 963 if (ch->enabled)
702f42e8
ML
964 devc->enabled_channels = g_slist_append(
965 devc->enabled_channels, ch);
ba7dd8bb 966 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 967 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
968 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
969 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 970 return SR_ERR;
ba7dd8bb 971 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 972 }
3f239f08 973 } else if (ch->type == SR_CHANNEL_LOGIC) {
01dd7a4c
ML
974 /* Only one list entry for older protocols. All channels are
975 * retrieved together when this entry is processed. */
702f42e8 976 if (ch->enabled && (
01dd7a4c 977 devc->model->series->protocol > PROTOCOL_V3 ||
702f42e8
ML
978 !some_digital))
979 devc->enabled_channels = g_slist_append(
980 devc->enabled_channels, ch);
ba7dd8bb 981 if (ch->enabled) {
702f42e8 982 some_digital = TRUE;
04e8e01e
ML
983 /* Turn on LA module if currently off. */
984 if (!devc->la_enabled) {
702f42e8 985 if (rigol_ds_config_set(sdi,
01dd7a4c 986 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 987 ":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
04e8e01e
ML
988 return SR_ERR;
989 devc->la_enabled = TRUE;
990 }
991 }
ba7dd8bb 992 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 993 /* Enabled channel is currently disabled, or vice versa. */
702f42e8 994 if (rigol_ds_config_set(sdi,
01dd7a4c 995 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 996 ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
ba7dd8bb 997 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 998 return SR_ERR;
ba7dd8bb 999 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 1000 }
254dd102
BV
1001 }
1002 }
1fed20cb 1003
702f42e8 1004 if (!devc->enabled_channels)
254dd102 1005 return SR_ERR;
e0b7d23c 1006
ba7dd8bb 1007 /* Turn off LA module if on and no digital channels selected. */
702f42e8
ML
1008 if (devc->la_enabled && !some_digital)
1009 if (rigol_ds_config_set(sdi,
01dd7a4c 1010 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 1011 ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
1012 return SR_ERR;
1013
e086b750
ML
1014 /* Set memory mode. */
1015 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
1016 sr_err("Data source 'Segmented' not yet supported");
1017 return SR_ERR;
1018 }
1019
1020 devc->analog_frame_size = analog_frame_size(sdi);
1021 devc->digital_frame_size = digital_frame_size(sdi);
1022
569d4dbd
ML
1023 switch (devc->model->series->protocol) {
1024 case PROTOCOL_V2:
99af83b7 1025 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 1026 return SR_ERR;
569d4dbd
ML
1027 break;
1028 case PROTOCOL_V3:
e086b750
ML
1029 /* Apparently for the DS2000 the memory
1030 * depth can only be set in Running state -
1031 * this matches the behaviour of the UI. */
38354d9d 1032 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1033 return SR_ERR;
e086b750
ML
1034 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1035 devc->analog_frame_size) != SR_OK)
1036 return SR_ERR;
1037 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1038 return SR_ERR;
569d4dbd
ML
1039 break;
1040 default:
1041 break;
1fed20cb
ML
1042 }
1043
e086b750
ML
1044 if (devc->data_source == DATA_SOURCE_LIVE)
1045 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1046 return SR_ERR;
1047
102f1239
BV
1048 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1049 rigol_ds_receive, (void *)sdi);
e0b7d23c 1050
bee2b016 1051 std_session_send_df_header(sdi);
e0b7d23c 1052
702f42e8 1053 devc->channel_entry = devc->enabled_channels;
821fbcad 1054
e086b750
ML
1055 if (rigol_ds_capture_start(sdi) != SR_OK)
1056 return SR_ERR;
f4816ac6 1057
f76c24f6
ML
1058 /* Start of first frame. */
1059 packet.type = SR_DF_FRAME_BEGIN;
695dc859 1060 sr_session_send(sdi, &packet);
f76c24f6 1061
f4816ac6
ML
1062 return SR_OK;
1063}
1064
695dc859 1065static int dev_acquisition_stop(struct sr_dev_inst *sdi)
f4816ac6 1066{
29d957ce 1067 struct dev_context *devc;
ae1bc1cc 1068 struct sr_scpi_dev_inst *scpi;
29d957ce 1069
29d957ce
UH
1070 devc = sdi->priv;
1071
bee2b016 1072 std_session_send_df_end(sdi);
b751cf7a 1073
702f42e8
ML
1074 g_slist_free(devc->enabled_channels);
1075 devc->enabled_channels = NULL;
ae1bc1cc 1076 scpi = sdi->conn;
102f1239 1077 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
1078
1079 return SR_OK;
1080}
1081
dd5c48a6 1082static struct sr_dev_driver rigol_ds_driver_info = {
3086efdd
ML
1083 .name = "rigol-ds",
1084 .longname = "Rigol DS",
f4816ac6 1085 .api_version = 1,
c2fdcc25 1086 .init = std_init,
700d6b64 1087 .cleanup = std_cleanup,
6078d2c9 1088 .scan = scan,
c01bf34c 1089 .dev_list = std_dev_list,
3b412e3a 1090 .dev_clear = dev_clear,
d62d7ad1 1091 .config_get = config_get,
035a1078 1092 .config_set = config_set,
a1c743fc 1093 .config_list = config_list,
6078d2c9
UH
1094 .dev_open = dev_open,
1095 .dev_close = dev_close,
254dd102
BV
1096 .dev_acquisition_start = dev_acquisition_start,
1097 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 1098 .context = NULL,
f4816ac6 1099};
dd5c48a6 1100SR_REGISTER_DEV_DRIVER(rigol_ds_driver_info);