]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
drivers: Start counting at 0 for some loops.
[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
584560f1 635 switch (key) {
1953564a 636 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 637 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 638 break;
1953564a 639 case SR_CONF_TRIGGER_SLOPE:
697fb6dd 640 if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
ca9b9f48 641 return SR_ERR_ARG;
254dd102 642 g_free(devc->trigger_slope);
697fb6dd 643 devc->trigger_slope = g_strdup((trigger_slopes[idx][0] == 'r') ? "POS" : "NEG");
758906aa 644 return rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
1953564a 645 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102 646 t_dbl = g_variant_get_double(data);
e1b5b7e7
UH
647 if (t_dbl < 0.0 || t_dbl > 1.0) {
648 sr_err("Invalid horiz. trigger position: %g.", t_dbl);
254dd102 649 return SR_ERR;
e1b5b7e7 650 }
254dd102
BV
651 devc->horiz_triggerpos = t_dbl;
652 /* We have the trigger offset as a percentage of the frame, but
653 * need to express this in seconds. */
bafd4890 654 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 655 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
758906aa 656 return rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
9ea62f2e
AJ
657 case SR_CONF_TRIGGER_LEVEL:
658 t_dbl = g_variant_get_double(data);
659 g_ascii_formatd(buffer, sizeof(buffer), "%.3f", t_dbl);
660 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:LEV %s", buffer);
661 if (ret == SR_OK)
662 devc->trigger_level = t_dbl;
758906aa 663 return ret;
1953564a 664 case SR_CONF_TIMEBASE:
697fb6dd
UH
665 if ((idx = std_u64_tuple_idx(data, devc->timebases, devc->num_timebases)) < 0)
666 return SR_ERR_ARG;
667 devc->timebase = (float)devc->timebases[idx][0] / devc->timebases[idx][1];
668 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
669 devc->timebase);
758906aa 670 return rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
1953564a 671 case SR_CONF_TRIGGER_SOURCE:
697fb6dd
UH
672 if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
673 return SR_ERR_ARG;
674 g_free(devc->trigger_source);
675 devc->trigger_source = g_strdup(trigger_sources[idx]);
676 if (!strcmp(devc->trigger_source, "AC Line"))
677 tmp_str = "ACL";
678 else if (!strcmp(devc->trigger_source, "CH1"))
679 tmp_str = "CHAN1";
680 else if (!strcmp(devc->trigger_source, "CH2"))
681 tmp_str = "CHAN2";
682 else if (!strcmp(devc->trigger_source, "CH3"))
683 tmp_str = "CHAN3";
684 else if (!strcmp(devc->trigger_source, "CH4"))
685 tmp_str = "CHAN4";
686 else
687 tmp_str = (char *)devc->trigger_source;
758906aa 688 return rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
1953564a 689 case SR_CONF_VDIV:
9e411f4b 690 if (!cg)
660e398f 691 return SR_ERR_CHANNEL_GROUP;
effb9dd1 692 for (i = 0; i < devc->model->analog_channels; i++) {
697fb6dd
UH
693 if (cg != devc->analog_groups[i])
694 continue;
695 if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
f48e0249 696 return SR_ERR_ARG;
697fb6dd
UH
697 devc->vdiv[i] = (float)vdivs[idx][0] / vdivs[idx][1];
698 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
699 devc->vdiv[i]);
700 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
701 buffer);
e0b7d23c 702 }
e1b5b7e7 703 sr_dbg("Didn't set vdiv, unknown channel(group).");
f48e0249 704 return SR_ERR_NA;
1953564a 705 case SR_CONF_COUPLING:
9e411f4b 706 if (!cg)
660e398f 707 return SR_ERR_CHANNEL_GROUP;
effb9dd1 708 for (i = 0; i < devc->model->analog_channels; i++) {
697fb6dd
UH
709 if (cg != devc->analog_groups[i])
710 continue;
711 if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
f48e0249 712 return SR_ERR_ARG;
697fb6dd
UH
713 g_free(devc->coupling[i]);
714 devc->coupling[i] = g_strdup(coupling[idx]);
715 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
716 devc->coupling[i]);
e0b7d23c 717 }
e1b5b7e7 718 sr_dbg("Didn't set coupling, unknown channel(group).");
f48e0249 719 return SR_ERR_NA;
934cf6cf 720 case SR_CONF_PROBE_FACTOR:
9e411f4b 721 if (!cg)
934cf6cf 722 return SR_ERR_CHANNEL_GROUP;
934cf6cf
AJ
723 p = g_variant_get_uint64(data);
724 for (i = 0; i < devc->model->analog_channels; i++) {
697fb6dd
UH
725 if (cg != devc->analog_groups[i])
726 continue;
727 if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(probe_factor))) < 0)
934cf6cf 728 return SR_ERR_ARG;
697fb6dd
UH
729 devc->attenuation[i] = probe_factor[idx];
730 ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
731 i + 1, p);
732 if (ret == SR_OK)
733 rigol_ds_get_dev_cfg_vertical(sdi);
734 return ret;
934cf6cf
AJ
735 }
736 sr_dbg("Didn't set probe factor, unknown channel(group).");
737 return SR_ERR_NA;
babab622
ML
738 case SR_CONF_DATA_SOURCE:
739 tmp_str = g_variant_get_string(data, NULL);
740 if (!strcmp(tmp_str, "Live"))
741 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
742 else if (devc->model->series->protocol >= PROTOCOL_V2
743 && !strcmp(tmp_str, "Memory"))
babab622 744 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 745 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
746 && !strcmp(tmp_str, "Segmented"))
747 devc->data_source = DATA_SOURCE_SEGMENTED;
e1b5b7e7
UH
748 else {
749 sr_err("Unknown data source: '%s'.", tmp_str);
babab622 750 return SR_ERR;
e1b5b7e7 751 }
babab622 752 break;
f4816ac6 753 default:
dcd438ee 754 return SR_ERR_NA;
f4816ac6
ML
755 }
756
758906aa 757 return SR_OK;
f4816ac6
ML
758}
759
dd7a72ea
UH
760static int config_list(uint32_t key, GVariant **data,
761 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
a1c743fc 762{
861c447b 763 unsigned int i;
e66d1892 764 struct dev_context *devc;
e43fdd8d 765
e66d1892 766 devc = (sdi) ? sdi->priv : NULL;
be60a9e4 767
e43fdd8d 768 switch (key) {
e66d1892 769 case SR_CONF_SCAN_OPTIONS:
9a6517d1 770 case SR_CONF_DEVICE_OPTIONS:
e66d1892
UH
771 if (!cg)
772 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
562b7ae5 773 if (cg == devc->digital_group) {
105df674 774 *data = std_gvar_array_u32(NULL, 0);
f48e0249
ML
775 return SR_OK;
776 } else {
effb9dd1 777 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 778 if (cg == devc->analog_groups[i]) {
53012da6 779 *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_analog));
f48e0249
ML
780 return SR_OK;
781 }
782 }
783 return SR_ERR_NA;
784 }
5f77dffc 785 break;
2a7b113d 786 case SR_CONF_COUPLING:
e66d1892 787 if (!cg)
660e398f 788 return SR_ERR_CHANNEL_GROUP;
53012da6 789 *data = g_variant_new_strv(ARRAY_AND_SIZE(coupling));
58f43369 790 break;
934cf6cf 791 case SR_CONF_PROBE_FACTOR:
e66d1892 792 if (!cg)
934cf6cf 793 return SR_ERR_CHANNEL_GROUP;
53012da6 794 *data = std_gvar_array_u64(ARRAY_AND_SIZE(probe_factor));
934cf6cf 795 break;
e4f2b2ad 796 case SR_CONF_VDIV:
7cc1a550
ML
797 if (!devc)
798 /* Can't know this until we have the exact model. */
799 return SR_ERR_ARG;
e66d1892 800 if (!cg)
660e398f 801 return SR_ERR_CHANNEL_GROUP;
58ffcf97 802 *data = std_gvar_tuple_array(devc->vdivs, devc->num_vdivs);
58f43369 803 break;
41f5bd09 804 case SR_CONF_TIMEBASE:
7cc1a550
ML
805 if (!devc)
806 /* Can't know this until we have the exact model. */
807 return SR_ERR_ARG;
a31b2ccb
AJ
808 if (devc->num_timebases <= 0)
809 return SR_ERR_NA;
58ffcf97 810 *data = std_gvar_tuple_array(devc->timebases, devc->num_timebases);
41f5bd09 811 break;
328bafab 812 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
813 if (!devc)
814 /* Can't know this until we have the exact model. */
815 return SR_ERR_ARG;
f6a0ac9f 816 *data = g_variant_new_strv(trigger_sources,
bafd4890 817 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 818 break;
5d336f11 819 case SR_CONF_TRIGGER_SLOPE:
53012da6 820 *data = g_variant_new_strv(ARRAY_AND_SIZE(trigger_slopes));
5d336f11 821 break;
babab622
ML
822 case SR_CONF_DATA_SOURCE:
823 if (!devc)
824 /* Can't know this until we have the exact model. */
825 return SR_ERR_ARG;
569d4dbd
ML
826 switch (devc->model->series->protocol) {
827 case PROTOCOL_V1:
828 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
829 break;
830 case PROTOCOL_V2:
babab622 831 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
832 break;
833 default:
53012da6 834 *data = g_variant_new_strv(ARRAY_AND_SIZE(data_sources));
569d4dbd
ML
835 break;
836 }
babab622 837 break;
a1c743fc 838 default:
bd6fbf62 839 return SR_ERR_NA;
a1c743fc
BV
840 }
841
842 return SR_OK;
843}
844
695dc859 845static int dev_acquisition_start(const struct sr_dev_inst *sdi)
f4816ac6 846{
ae1bc1cc 847 struct sr_scpi_dev_inst *scpi;
29d957ce 848 struct dev_context *devc;
ba7dd8bb 849 struct sr_channel *ch;
f76c24f6 850 struct sr_datafeed_packet packet;
702f42e8 851 gboolean some_digital;
254dd102 852 GSList *l;
29d957ce 853
ae1bc1cc 854 scpi = sdi->conn;
29d957ce
UH
855 devc = sdi->priv;
856
51b294cd
ML
857 devc->num_frames = 0;
858
702f42e8 859 some_digital = FALSE;
ba7dd8bb
UH
860 for (l = sdi->channels; l; l = l->next) {
861 ch = l->data;
862 sr_dbg("handling channel %s", ch->name);
3f239f08 863 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 864 if (ch->enabled)
702f42e8
ML
865 devc->enabled_channels = g_slist_append(
866 devc->enabled_channels, ch);
ba7dd8bb 867 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 868 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
869 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
870 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 871 return SR_ERR;
ba7dd8bb 872 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 873 }
3f239f08 874 } else if (ch->type == SR_CHANNEL_LOGIC) {
01dd7a4c
ML
875 /* Only one list entry for older protocols. All channels are
876 * retrieved together when this entry is processed. */
702f42e8 877 if (ch->enabled && (
01dd7a4c 878 devc->model->series->protocol > PROTOCOL_V3 ||
702f42e8
ML
879 !some_digital))
880 devc->enabled_channels = g_slist_append(
881 devc->enabled_channels, ch);
ba7dd8bb 882 if (ch->enabled) {
702f42e8 883 some_digital = TRUE;
04e8e01e
ML
884 /* Turn on LA module if currently off. */
885 if (!devc->la_enabled) {
702f42e8 886 if (rigol_ds_config_set(sdi,
01dd7a4c 887 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 888 ":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
04e8e01e
ML
889 return SR_ERR;
890 devc->la_enabled = TRUE;
891 }
892 }
ba7dd8bb 893 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 894 /* Enabled channel is currently disabled, or vice versa. */
702f42e8 895 if (rigol_ds_config_set(sdi,
01dd7a4c 896 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 897 ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
ba7dd8bb 898 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 899 return SR_ERR;
ba7dd8bb 900 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 901 }
254dd102
BV
902 }
903 }
1fed20cb 904
702f42e8 905 if (!devc->enabled_channels)
254dd102 906 return SR_ERR;
e0b7d23c 907
ba7dd8bb 908 /* Turn off LA module if on and no digital channels selected. */
702f42e8
ML
909 if (devc->la_enabled && !some_digital)
910 if (rigol_ds_config_set(sdi,
01dd7a4c 911 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 912 ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
913 return SR_ERR;
914
e086b750
ML
915 /* Set memory mode. */
916 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
917 sr_err("Data source 'Segmented' not yet supported");
918 return SR_ERR;
919 }
920
921 devc->analog_frame_size = analog_frame_size(sdi);
922 devc->digital_frame_size = digital_frame_size(sdi);
923
569d4dbd
ML
924 switch (devc->model->series->protocol) {
925 case PROTOCOL_V2:
99af83b7 926 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 927 return SR_ERR;
569d4dbd
ML
928 break;
929 case PROTOCOL_V3:
e086b750
ML
930 /* Apparently for the DS2000 the memory
931 * depth can only be set in Running state -
932 * this matches the behaviour of the UI. */
38354d9d 933 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 934 return SR_ERR;
e086b750
ML
935 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
936 devc->analog_frame_size) != SR_OK)
937 return SR_ERR;
938 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 939 return SR_ERR;
569d4dbd
ML
940 break;
941 default:
942 break;
1fed20cb
ML
943 }
944
e086b750
ML
945 if (devc->data_source == DATA_SOURCE_LIVE)
946 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
947 return SR_ERR;
948
102f1239
BV
949 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
950 rigol_ds_receive, (void *)sdi);
e0b7d23c 951
bee2b016 952 std_session_send_df_header(sdi);
e0b7d23c 953
702f42e8 954 devc->channel_entry = devc->enabled_channels;
821fbcad 955
e086b750
ML
956 if (rigol_ds_capture_start(sdi) != SR_OK)
957 return SR_ERR;
f4816ac6 958
f76c24f6
ML
959 /* Start of first frame. */
960 packet.type = SR_DF_FRAME_BEGIN;
695dc859 961 sr_session_send(sdi, &packet);
f76c24f6 962
f4816ac6
ML
963 return SR_OK;
964}
965
695dc859 966static int dev_acquisition_stop(struct sr_dev_inst *sdi)
f4816ac6 967{
29d957ce 968 struct dev_context *devc;
ae1bc1cc 969 struct sr_scpi_dev_inst *scpi;
29d957ce 970
29d957ce
UH
971 devc = sdi->priv;
972
bee2b016 973 std_session_send_df_end(sdi);
b751cf7a 974
702f42e8
ML
975 g_slist_free(devc->enabled_channels);
976 devc->enabled_channels = NULL;
ae1bc1cc 977 scpi = sdi->conn;
102f1239 978 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
979
980 return SR_OK;
981}
982
dd5c48a6 983static struct sr_dev_driver rigol_ds_driver_info = {
3086efdd
ML
984 .name = "rigol-ds",
985 .longname = "Rigol DS",
f4816ac6 986 .api_version = 1,
c2fdcc25 987 .init = std_init,
700d6b64 988 .cleanup = std_cleanup,
6078d2c9 989 .scan = scan,
c01bf34c 990 .dev_list = std_dev_list,
3b412e3a 991 .dev_clear = dev_clear,
d62d7ad1 992 .config_get = config_get,
035a1078 993 .config_set = config_set,
a1c743fc 994 .config_list = config_list,
6078d2c9
UH
995 .dev_open = dev_open,
996 .dev_close = dev_close,
254dd102
BV
997 .dev_acquisition_start = dev_acquisition_start,
998 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 999 .context = NULL,
f4816ac6 1000};
dd5c48a6 1001SR_REGISTER_DEV_DRIVER(rigol_ds_driver_info);