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