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