]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
drivers: Factor out std_gvar_min_max_step_thresholds().
[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
6b82c3e5 56static const uint32_t devopts_cg_analog[] = {
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 843 unsigned int i;
e66d1892 844 struct dev_context *devc;
e43fdd8d 845
e66d1892 846 devc = (sdi) ? sdi->priv : NULL;
be60a9e4 847
e43fdd8d 848 switch (key) {
e66d1892 849 case SR_CONF_SCAN_OPTIONS:
9a6517d1 850 case SR_CONF_DEVICE_OPTIONS:
e66d1892
UH
851 if (!cg)
852 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
562b7ae5 853 if (cg == devc->digital_group) {
584560f1
BV
854 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
855 NULL, 0, sizeof(uint32_t));
f48e0249
ML
856 return SR_OK;
857 } else {
effb9dd1 858 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 859 if (cg == devc->analog_groups[i]) {
584560f1 860 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
6b82c3e5 861 devopts_cg_analog, ARRAY_SIZE(devopts_cg_analog), sizeof(uint32_t));
f48e0249
ML
862 return SR_OK;
863 }
864 }
865 return SR_ERR_NA;
866 }
5f77dffc 867 break;
2a7b113d 868 case SR_CONF_COUPLING:
e66d1892 869 if (!cg)
660e398f 870 return SR_ERR_CHANNEL_GROUP;
58f43369
BV
871 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
872 break;
934cf6cf 873 case SR_CONF_PROBE_FACTOR:
e66d1892 874 if (!cg)
934cf6cf 875 return SR_ERR_CHANNEL_GROUP;
934cf6cf
AJ
876 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
877 probe_factor, ARRAY_SIZE(probe_factor), sizeof(uint64_t));
878 break;
e4f2b2ad 879 case SR_CONF_VDIV:
7cc1a550
ML
880 if (!devc)
881 /* Can't know this until we have the exact model. */
882 return SR_ERR_ARG;
e66d1892 883 if (!cg)
660e398f 884 return SR_ERR_CHANNEL_GROUP;
db944f16 885 *data = std_gvar_tuple_array((const uint64_t (*)[][2])devc->vdivs, devc->num_vdivs);
58f43369 886 break;
41f5bd09 887 case SR_CONF_TIMEBASE:
7cc1a550
ML
888 if (!devc)
889 /* Can't know this until we have the exact model. */
890 return SR_ERR_ARG;
a31b2ccb
AJ
891 if (devc->num_timebases <= 0)
892 return SR_ERR_NA;
db944f16 893 *data = std_gvar_tuple_array((const uint64_t (*)[][2])devc->timebases, devc->num_timebases);
41f5bd09 894 break;
328bafab 895 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
896 if (!devc)
897 /* Can't know this until we have the exact model. */
898 return SR_ERR_ARG;
f6a0ac9f 899 *data = g_variant_new_strv(trigger_sources,
bafd4890 900 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 901 break;
5d336f11
AJ
902 case SR_CONF_TRIGGER_SLOPE:
903 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
904 break;
babab622
ML
905 case SR_CONF_DATA_SOURCE:
906 if (!devc)
907 /* Can't know this until we have the exact model. */
908 return SR_ERR_ARG;
569d4dbd
ML
909 switch (devc->model->series->protocol) {
910 case PROTOCOL_V1:
911 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
912 break;
913 case PROTOCOL_V2:
babab622 914 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
915 break;
916 default:
917 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
918 break;
919 }
babab622 920 break;
a1c743fc 921 default:
bd6fbf62 922 return SR_ERR_NA;
a1c743fc
BV
923 }
924
925 return SR_OK;
926}
927
695dc859 928static int dev_acquisition_start(const struct sr_dev_inst *sdi)
f4816ac6 929{
ae1bc1cc 930 struct sr_scpi_dev_inst *scpi;
29d957ce 931 struct dev_context *devc;
ba7dd8bb 932 struct sr_channel *ch;
f76c24f6 933 struct sr_datafeed_packet packet;
702f42e8 934 gboolean some_digital;
254dd102 935 GSList *l;
29d957ce 936
ae1bc1cc 937 scpi = sdi->conn;
29d957ce
UH
938 devc = sdi->priv;
939
51b294cd
ML
940 devc->num_frames = 0;
941
702f42e8 942 some_digital = FALSE;
ba7dd8bb
UH
943 for (l = sdi->channels; l; l = l->next) {
944 ch = l->data;
945 sr_dbg("handling channel %s", ch->name);
3f239f08 946 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 947 if (ch->enabled)
702f42e8
ML
948 devc->enabled_channels = g_slist_append(
949 devc->enabled_channels, ch);
ba7dd8bb 950 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 951 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
952 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
953 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 954 return SR_ERR;
ba7dd8bb 955 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 956 }
3f239f08 957 } else if (ch->type == SR_CHANNEL_LOGIC) {
01dd7a4c
ML
958 /* Only one list entry for older protocols. All channels are
959 * retrieved together when this entry is processed. */
702f42e8 960 if (ch->enabled && (
01dd7a4c 961 devc->model->series->protocol > PROTOCOL_V3 ||
702f42e8
ML
962 !some_digital))
963 devc->enabled_channels = g_slist_append(
964 devc->enabled_channels, ch);
ba7dd8bb 965 if (ch->enabled) {
702f42e8 966 some_digital = TRUE;
04e8e01e
ML
967 /* Turn on LA module if currently off. */
968 if (!devc->la_enabled) {
702f42e8 969 if (rigol_ds_config_set(sdi,
01dd7a4c 970 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 971 ":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
04e8e01e
ML
972 return SR_ERR;
973 devc->la_enabled = TRUE;
974 }
975 }
ba7dd8bb 976 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 977 /* Enabled channel is currently disabled, or vice versa. */
702f42e8 978 if (rigol_ds_config_set(sdi,
01dd7a4c 979 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 980 ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
ba7dd8bb 981 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 982 return SR_ERR;
ba7dd8bb 983 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 984 }
254dd102
BV
985 }
986 }
1fed20cb 987
702f42e8 988 if (!devc->enabled_channels)
254dd102 989 return SR_ERR;
e0b7d23c 990
ba7dd8bb 991 /* Turn off LA module if on and no digital channels selected. */
702f42e8
ML
992 if (devc->la_enabled && !some_digital)
993 if (rigol_ds_config_set(sdi,
01dd7a4c 994 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 995 ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
996 return SR_ERR;
997
e086b750
ML
998 /* Set memory mode. */
999 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
1000 sr_err("Data source 'Segmented' not yet supported");
1001 return SR_ERR;
1002 }
1003
1004 devc->analog_frame_size = analog_frame_size(sdi);
1005 devc->digital_frame_size = digital_frame_size(sdi);
1006
569d4dbd
ML
1007 switch (devc->model->series->protocol) {
1008 case PROTOCOL_V2:
99af83b7 1009 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 1010 return SR_ERR;
569d4dbd
ML
1011 break;
1012 case PROTOCOL_V3:
e086b750
ML
1013 /* Apparently for the DS2000 the memory
1014 * depth can only be set in Running state -
1015 * this matches the behaviour of the UI. */
38354d9d 1016 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1017 return SR_ERR;
e086b750
ML
1018 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1019 devc->analog_frame_size) != SR_OK)
1020 return SR_ERR;
1021 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1022 return SR_ERR;
569d4dbd
ML
1023 break;
1024 default:
1025 break;
1fed20cb
ML
1026 }
1027
e086b750
ML
1028 if (devc->data_source == DATA_SOURCE_LIVE)
1029 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1030 return SR_ERR;
1031
102f1239
BV
1032 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1033 rigol_ds_receive, (void *)sdi);
e0b7d23c 1034
bee2b016 1035 std_session_send_df_header(sdi);
e0b7d23c 1036
702f42e8 1037 devc->channel_entry = devc->enabled_channels;
821fbcad 1038
e086b750
ML
1039 if (rigol_ds_capture_start(sdi) != SR_OK)
1040 return SR_ERR;
f4816ac6 1041
f76c24f6
ML
1042 /* Start of first frame. */
1043 packet.type = SR_DF_FRAME_BEGIN;
695dc859 1044 sr_session_send(sdi, &packet);
f76c24f6 1045
f4816ac6
ML
1046 return SR_OK;
1047}
1048
695dc859 1049static int dev_acquisition_stop(struct sr_dev_inst *sdi)
f4816ac6 1050{
29d957ce 1051 struct dev_context *devc;
ae1bc1cc 1052 struct sr_scpi_dev_inst *scpi;
29d957ce 1053
29d957ce
UH
1054 devc = sdi->priv;
1055
bee2b016 1056 std_session_send_df_end(sdi);
b751cf7a 1057
702f42e8
ML
1058 g_slist_free(devc->enabled_channels);
1059 devc->enabled_channels = NULL;
ae1bc1cc 1060 scpi = sdi->conn;
102f1239 1061 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
1062
1063 return SR_OK;
1064}
1065
dd5c48a6 1066static struct sr_dev_driver rigol_ds_driver_info = {
3086efdd
ML
1067 .name = "rigol-ds",
1068 .longname = "Rigol DS",
f4816ac6 1069 .api_version = 1,
c2fdcc25 1070 .init = std_init,
700d6b64 1071 .cleanup = std_cleanup,
6078d2c9 1072 .scan = scan,
c01bf34c 1073 .dev_list = std_dev_list,
3b412e3a 1074 .dev_clear = dev_clear,
d62d7ad1 1075 .config_get = config_get,
035a1078 1076 .config_set = config_set,
a1c743fc 1077 .config_list = config_list,
6078d2c9
UH
1078 .dev_open = dev_open,
1079 .dev_close = dev_close,
254dd102
BV
1080 .dev_acquisition_start = dev_acquisition_start,
1081 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 1082 .context = NULL,
f4816ac6 1083};
dd5c48a6 1084SR_REGISTER_DEV_DRIVER(rigol_ds_driver_info);