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