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