]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
sr_dev_close(): Set status to SR_ST_INACTIVE.
[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
ML
447
448 return SR_OK;
449}
450
6078d2c9 451static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 452{
ae1bc1cc 453 struct sr_scpi_dev_inst *scpi;
22c19688 454 struct dev_context *devc;
ae1bc1cc
ML
455
456 scpi = sdi->conn;
22c19688
ML
457 devc = sdi->priv;
458
f1ba6b4b
UH
459 if (!scpi)
460 return SR_ERR_BUG;
461
6e94eb41 462 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 463 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 464
f1ba6b4b 465 return sr_scpi_close(scpi);
f4816ac6
ML
466}
467
5415e602
ML
468static int analog_frame_size(const struct sr_dev_inst *sdi)
469{
470 struct dev_context *devc = sdi->priv;
ba7dd8bb
UH
471 struct sr_channel *ch;
472 int analog_channels = 0;
5415e602
ML
473 GSList *l;
474
ba7dd8bb
UH
475 for (l = sdi->channels; l; l = l->next) {
476 ch = l->data;
3f239f08 477 if (ch->type == SR_CHANNEL_ANALOG && ch->enabled)
ba7dd8bb 478 analog_channels++;
569d4dbd
ML
479 }
480
ba7dd8bb 481 if (analog_channels == 0)
824eb2ac
ML
482 return 0;
483
569d4dbd
ML
484 switch (devc->data_source) {
485 case DATA_SOURCE_LIVE:
486 return devc->model->series->live_samples;
487 case DATA_SOURCE_MEMORY:
ba7dd8bb 488 return devc->model->series->buffer_samples / analog_channels;
470140fc 489 default:
569d4dbd 490 return 0;
5415e602
ML
491 }
492}
493
d22250a9
ML
494static int digital_frame_size(const struct sr_dev_inst *sdi)
495{
496 struct dev_context *devc = sdi->priv;
497
569d4dbd
ML
498 switch (devc->data_source) {
499 case DATA_SOURCE_LIVE:
500 return devc->model->series->live_samples * 2;
501 case DATA_SOURCE_MEMORY:
502 return devc->model->series->buffer_samples * 2;
d22250a9
ML
503 default:
504 return 0;
505 }
506}
507
584560f1 508static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 509 const struct sr_channel_group *cg)
d62d7ad1 510{
e43fdd8d 511 struct dev_context *devc;
ba7dd8bb 512 struct sr_channel *ch;
2b0e4a46 513 const char *tmp_str;
c2b394d5 514 uint64_t samplerate;
2b0e4a46 515 int analog_channel = -1;
c33ff377 516 float smallest_diff = INFINITY;
2b0e4a46
AJ
517 int idx = -1;
518 unsigned i;
d62d7ad1 519
709468ba 520 if (!sdi)
e43fdd8d
BV
521 return SR_ERR_ARG;
522
709468ba
UH
523 devc = sdi->priv;
524
660e398f 525 /* If a channel group is specified, it must be a valid one. */
53b4680f 526 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 527 sr_err("Invalid channel group specified.");
969edf63 528 return SR_ERR;
be60a9e4
BV
529 }
530
53b4680f 531 if (cg) {
ba7dd8bb
UH
532 ch = g_slist_nth_data(cg->channels, 0);
533 if (!ch)
2b0e4a46 534 return SR_ERR;
3f239f08 535 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 536 if (ch->name[2] < '1' || ch->name[2] > '4')
2b0e4a46 537 return SR_ERR;
ba7dd8bb 538 analog_channel = ch->name[2] - '1';
2b0e4a46
AJ
539 }
540 }
541
584560f1 542 switch (key) {
bf622e6d 543 case SR_CONF_NUM_HDIV:
569d4dbd 544 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
545 break;
546 case SR_CONF_NUM_VDIV:
81b85663 547 *data = g_variant_new_int32(devc->num_vdivs);
f44f7e61 548 break;
babab622
ML
549 case SR_CONF_DATA_SOURCE:
550 if (devc->data_source == DATA_SOURCE_LIVE)
551 *data = g_variant_new_string("Live");
552 else if (devc->data_source == DATA_SOURCE_MEMORY)
553 *data = g_variant_new_string("Memory");
554 else
555 *data = g_variant_new_string("Segmented");
556 break;
4914dd4b
ML
557 case SR_CONF_SAMPLERATE:
558 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 559 samplerate = analog_frame_size(sdi) /
569d4dbd 560 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 561 *data = g_variant_new_uint64(samplerate);
c2b394d5 562 } else {
e1b5b7e7 563 sr_dbg("Unknown data source: %d.", devc->data_source);
4914dd4b 564 return SR_ERR_NA;
c2b394d5 565 }
4914dd4b 566 break;
2b0e4a46
AJ
567 case SR_CONF_TRIGGER_SOURCE:
568 if (!strcmp(devc->trigger_source, "ACL"))
569 tmp_str = "AC Line";
570 else if (!strcmp(devc->trigger_source, "CHAN1"))
571 tmp_str = "CH1";
572 else if (!strcmp(devc->trigger_source, "CHAN2"))
573 tmp_str = "CH2";
574 else if (!strcmp(devc->trigger_source, "CHAN3"))
575 tmp_str = "CH3";
576 else if (!strcmp(devc->trigger_source, "CHAN4"))
577 tmp_str = "CH4";
578 else
579 tmp_str = devc->trigger_source;
580 *data = g_variant_new_string(tmp_str);
581 break;
5d336f11 582 case SR_CONF_TRIGGER_SLOPE:
e1b5b7e7 583 if (!strncmp(devc->trigger_slope, "POS", 3)) {
5d336f11 584 tmp_str = "r";
e1b5b7e7 585 } else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
5d336f11 586 tmp_str = "f";
e1b5b7e7
UH
587 } else {
588 sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
5d336f11 589 return SR_ERR_NA;
e1b5b7e7 590 }
5d336f11
AJ
591 *data = g_variant_new_string(tmp_str);
592 break;
9ea62f2e
AJ
593 case SR_CONF_TRIGGER_LEVEL:
594 *data = g_variant_new_double(devc->trigger_level);
595 break;
2b0e4a46
AJ
596 case SR_CONF_TIMEBASE:
597 for (i = 0; i < devc->num_timebases; i++) {
598 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
599 float diff = fabs(devc->timebase - tb);
600 if (diff < smallest_diff) {
601 smallest_diff = diff;
602 idx = i;
603 }
604 }
e1b5b7e7
UH
605 if (idx < 0) {
606 sr_dbg("Negative timebase index: %d.", idx);
2b0e4a46 607 return SR_ERR_NA;
e1b5b7e7 608 }
2b0e4a46
AJ
609 *data = g_variant_new("(tt)", devc->timebases[idx][0],
610 devc->timebases[idx][1]);
611 break;
612 case SR_CONF_VDIV:
e1b5b7e7
UH
613 if (analog_channel < 0) {
614 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 615 return SR_ERR_NA;
e1b5b7e7 616 }
2b0e4a46
AJ
617 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
618 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
619 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
620 if (diff < smallest_diff) {
621 smallest_diff = diff;
622 idx = i;
623 }
624 }
e1b5b7e7
UH
625 if (idx < 0) {
626 sr_dbg("Negative vdiv index: %d.", idx);
2b0e4a46 627 return SR_ERR_NA;
e1b5b7e7 628 }
2b0e4a46
AJ
629 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
630 break;
631 case SR_CONF_COUPLING:
e1b5b7e7
UH
632 if (analog_channel < 0) {
633 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 634 return SR_ERR_NA;
e1b5b7e7 635 }
2b0e4a46
AJ
636 *data = g_variant_new_string(devc->coupling[analog_channel]);
637 break;
934cf6cf
AJ
638 case SR_CONF_PROBE_FACTOR:
639 if (analog_channel < 0) {
640 sr_dbg("Negative analog channel: %d.", analog_channel);
641 return SR_ERR_NA;
642 }
643 *data = g_variant_new_uint64(devc->attenuation[analog_channel]);
644 break;
d62d7ad1 645 default:
bd6fbf62 646 return SR_ERR_NA;
d62d7ad1
BV
647 }
648
649 return SR_OK;
650}
651
584560f1 652static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 653 const struct sr_channel_group *cg)
f4816ac6 654{
29d957ce 655 struct dev_context *devc;
ca9b9f48 656 uint64_t p, q;
254dd102 657 double t_dbl;
f48e0249 658 unsigned int i, j;
254dd102
BV
659 int ret;
660 const char *tmp_str;
889ef4a0 661 char buffer[16];
f4816ac6 662
b0baddef 663 devc = sdi->priv;
29d957ce 664
660e398f 665 /* If a channel group is specified, it must be a valid one. */
53b4680f 666 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 667 sr_err("Invalid channel group specified.");
969edf63 668 return SR_ERR;
be60a9e4
BV
669 }
670
f4816ac6 671 ret = SR_OK;
584560f1 672 switch (key) {
1953564a 673 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 674 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 675 break;
1953564a 676 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
677 tmp_str = g_variant_get_string(data, NULL);
678
e1b5b7e7
UH
679 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
680 sr_err("Unknown trigger slope: '%s'.",
681 (tmp_str) ? tmp_str : "NULL");
ca9b9f48 682 return SR_ERR_ARG;
e1b5b7e7 683 }
ca9b9f48 684
254dd102 685 g_free(devc->trigger_slope);
ca9b9f48 686 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 687 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 688 break;
1953564a 689 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102 690 t_dbl = g_variant_get_double(data);
e1b5b7e7
UH
691 if (t_dbl < 0.0 || t_dbl > 1.0) {
692 sr_err("Invalid horiz. trigger position: %g.", t_dbl);
254dd102 693 return SR_ERR;
e1b5b7e7 694 }
254dd102
BV
695 devc->horiz_triggerpos = t_dbl;
696 /* We have the trigger offset as a percentage of the frame, but
697 * need to express this in seconds. */
bafd4890 698 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 699 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 700 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 701 break;
9ea62f2e
AJ
702 case SR_CONF_TRIGGER_LEVEL:
703 t_dbl = g_variant_get_double(data);
704 g_ascii_formatd(buffer, sizeof(buffer), "%.3f", t_dbl);
705 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:LEV %s", buffer);
706 if (ret == SR_OK)
707 devc->trigger_level = t_dbl;
708 break;
1953564a 709 case SR_CONF_TIMEBASE:
f6a0ac9f 710 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
711 for (i = 0; i < devc->num_timebases; i++) {
712 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 713 devc->timebase = (float)p / q;
889ef4a0
AJ
714 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
715 devc->timebase);
38354d9d 716 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
717 break;
718 }
719 }
e1b5b7e7
UH
720 if (i == devc->num_timebases) {
721 sr_err("Invalid timebase index: %d.", i);
254dd102 722 ret = SR_ERR_ARG;
e1b5b7e7 723 }
e0b7d23c 724 break;
1953564a 725 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 726 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
727 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
728 if (!strcmp(trigger_sources[i], tmp_str)) {
729 g_free(devc->trigger_source);
730 devc->trigger_source = g_strdup(trigger_sources[i]);
731 if (!strcmp(devc->trigger_source, "AC Line"))
732 tmp_str = "ACL";
733 else if (!strcmp(devc->trigger_source, "CH1"))
734 tmp_str = "CHAN1";
735 else if (!strcmp(devc->trigger_source, "CH2"))
736 tmp_str = "CHAN2";
821fbcad
ML
737 else if (!strcmp(devc->trigger_source, "CH3"))
738 tmp_str = "CHAN3";
739 else if (!strcmp(devc->trigger_source, "CH4"))
740 tmp_str = "CHAN4";
254dd102
BV
741 else
742 tmp_str = (char *)devc->trigger_source;
38354d9d 743 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
744 break;
745 }
4e108ace 746 }
e1b5b7e7
UH
747 if (i == ARRAY_SIZE(trigger_sources)) {
748 sr_err("Invalid trigger source index: %d.", i);
254dd102 749 ret = SR_ERR_ARG;
e1b5b7e7 750 }
e0b7d23c 751 break;
1953564a 752 case SR_CONF_VDIV:
53b4680f 753 if (!cg) {
660e398f
UH
754 sr_err("No channel group specified.");
755 return SR_ERR_CHANNEL_GROUP;
be60a9e4 756 }
f6a0ac9f 757 g_variant_get(data, "(tt)", &p, &q);
effb9dd1 758 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 759 if (cg == devc->analog_groups[i]) {
78bcc55a 760 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
761 if (vdivs[j][0] != p || vdivs[j][1] != q)
762 continue;
763 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
764 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
765 devc->vdiv[i]);
38354d9d 766 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 767 buffer);
f48e0249 768 }
e1b5b7e7 769 sr_err("Invalid vdiv index: %d.", j);
f48e0249
ML
770 return SR_ERR_ARG;
771 }
e0b7d23c 772 }
e1b5b7e7 773 sr_dbg("Didn't set vdiv, unknown channel(group).");
f48e0249 774 return SR_ERR_NA;
1953564a 775 case SR_CONF_COUPLING:
53b4680f 776 if (!cg) {
660e398f
UH
777 sr_err("No channel group specified.");
778 return SR_ERR_CHANNEL_GROUP;
78bcc55a 779 }
f6a0ac9f 780 tmp_str = g_variant_get_string(data, NULL);
effb9dd1 781 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 782 if (cg == devc->analog_groups[i]) {
78bcc55a
BV
783 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
784 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
785 g_free(devc->coupling[i]);
786 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 787 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
788 devc->coupling[i]);
789 }
790 }
e1b5b7e7 791 sr_err("Invalid coupling index: %d.", j);
f48e0249 792 return SR_ERR_ARG;
e0b7d23c
ML
793 }
794 }
e1b5b7e7 795 sr_dbg("Didn't set coupling, unknown channel(group).");
f48e0249 796 return SR_ERR_NA;
934cf6cf
AJ
797 case SR_CONF_PROBE_FACTOR:
798 if (!cg) {
799 sr_err("No channel group specified.");
800 return SR_ERR_CHANNEL_GROUP;
801 }
802 p = g_variant_get_uint64(data);
803 for (i = 0; i < devc->model->analog_channels; i++) {
804 if (cg == devc->analog_groups[i]) {
805 for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
806 if (p == probe_factor[j]) {
807 devc->attenuation[i] = p;
808 ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
809 i + 1, p);
810 if (ret == SR_OK)
811 rigol_ds_get_dev_cfg_vertical(sdi);
812 return ret;
813 }
814 }
815 sr_err("Invalid probe factor: %"PRIu64".", p);
816 return SR_ERR_ARG;
817 }
818 }
819 sr_dbg("Didn't set probe factor, unknown channel(group).");
820 return SR_ERR_NA;
babab622
ML
821 case SR_CONF_DATA_SOURCE:
822 tmp_str = g_variant_get_string(data, NULL);
823 if (!strcmp(tmp_str, "Live"))
824 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
825 else if (devc->model->series->protocol >= PROTOCOL_V2
826 && !strcmp(tmp_str, "Memory"))
babab622 827 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 828 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
829 && !strcmp(tmp_str, "Segmented"))
830 devc->data_source = DATA_SOURCE_SEGMENTED;
e1b5b7e7
UH
831 else {
832 sr_err("Unknown data source: '%s'.", tmp_str);
babab622 833 return SR_ERR;
e1b5b7e7 834 }
babab622 835 break;
f4816ac6 836 default:
dcd438ee 837 return SR_ERR_NA;
f4816ac6
ML
838 }
839
840 return ret;
841}
842
584560f1 843static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 844 const struct sr_channel_group *cg)
a1c743fc 845{
861c447b
BV
846 GVariant *tuple, *rational[2];
847 GVariantBuilder gvb;
848 unsigned int i;
7cc1a550
ML
849 struct dev_context *devc = NULL;
850
d73aacf1 851 /* SR_CONF_SCAN_OPTIONS is always valid, regardless of sdi or channel group. */
e43fdd8d 852 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1 853 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
a0e0bb41 854 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
e43fdd8d 855 return SR_OK;
d73aacf1
SA
856 }
857
858 /* If sdi is NULL, nothing except SR_CONF_DEVICE_OPTIONS can be provided. */
859 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
584560f1 860 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
d73aacf1 861 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
e43fdd8d
BV
862 return SR_OK;
863 }
864
865 /* Every other option requires a valid device instance. */
4d399734 866 if (!sdi)
e43fdd8d 867 return SR_ERR_ARG;
4d399734 868 devc = sdi->priv;
e43fdd8d 869
660e398f 870 /* If a channel group is specified, it must be a valid one. */
40c2c915
ML
871 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
872 sr_err("Invalid channel group specified.");
873 return SR_ERR;
be60a9e4
BV
874 }
875
e43fdd8d 876 switch (key) {
9a6517d1 877 case SR_CONF_DEVICE_OPTIONS:
53b4680f 878 if (!cg) {
d73aacf1
SA
879 /* If cg is NULL, only the SR_CONF_DEVICE_OPTIONS that are not
880 * specific to a channel group must be returned. */
881 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
882 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
883 return SR_OK;
be60a9e4 884 }
562b7ae5 885 if (cg == devc->digital_group) {
584560f1
BV
886 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
887 NULL, 0, sizeof(uint32_t));
f48e0249
ML
888 return SR_OK;
889 } else {
effb9dd1 890 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 891 if (cg == devc->analog_groups[i]) {
584560f1 892 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 893 analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
f48e0249
ML
894 return SR_OK;
895 }
896 }
897 return SR_ERR_NA;
898 }
5f77dffc 899 break;
2a7b113d 900 case SR_CONF_COUPLING:
53b4680f 901 if (!cg) {
660e398f
UH
902 sr_err("No channel group specified.");
903 return SR_ERR_CHANNEL_GROUP;
f48e0249 904 }
58f43369
BV
905 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
906 break;
934cf6cf
AJ
907 case SR_CONF_PROBE_FACTOR:
908 if (!cg) {
909 sr_err("No channel group specified.");
910 return SR_ERR_CHANNEL_GROUP;
911 }
912 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
913 probe_factor, ARRAY_SIZE(probe_factor), sizeof(uint64_t));
914 break;
e4f2b2ad 915 case SR_CONF_VDIV:
7cc1a550
ML
916 if (!devc)
917 /* Can't know this until we have the exact model. */
918 return SR_ERR_ARG;
53b4680f 919 if (!cg) {
660e398f
UH
920 sr_err("No channel group specified.");
921 return SR_ERR_CHANNEL_GROUP;
861c447b 922 }
58f43369 923 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
81b85663 924 for (i = 0; i < devc->num_vdivs; i++) {
bafd4890
ML
925 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
926 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
927 tuple = g_variant_new_tuple(rational, 2);
928 g_variant_builder_add_value(&gvb, tuple);
929 }
930 *data = g_variant_builder_end(&gvb);
931 break;
41f5bd09 932 case SR_CONF_TIMEBASE:
7cc1a550
ML
933 if (!devc)
934 /* Can't know this until we have the exact model. */
935 return SR_ERR_ARG;
a31b2ccb
AJ
936 if (devc->num_timebases <= 0)
937 return SR_ERR_NA;
861c447b 938 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
939 for (i = 0; i < devc->num_timebases; i++) {
940 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
941 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
942 tuple = g_variant_new_tuple(rational, 2);
943 g_variant_builder_add_value(&gvb, tuple);
944 }
945 *data = g_variant_builder_end(&gvb);
41f5bd09 946 break;
328bafab 947 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
948 if (!devc)
949 /* Can't know this until we have the exact model. */
950 return SR_ERR_ARG;
f6a0ac9f 951 *data = g_variant_new_strv(trigger_sources,
bafd4890 952 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 953 break;
5d336f11
AJ
954 case SR_CONF_TRIGGER_SLOPE:
955 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
956 break;
babab622
ML
957 case SR_CONF_DATA_SOURCE:
958 if (!devc)
959 /* Can't know this until we have the exact model. */
960 return SR_ERR_ARG;
569d4dbd
ML
961 switch (devc->model->series->protocol) {
962 case PROTOCOL_V1:
963 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
964 break;
965 case PROTOCOL_V2:
babab622 966 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
967 break;
968 default:
969 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
970 break;
971 }
babab622 972 break;
a1c743fc 973 default:
bd6fbf62 974 return SR_ERR_NA;
a1c743fc
BV
975 }
976
977 return SR_OK;
978}
979
695dc859 980static int dev_acquisition_start(const struct sr_dev_inst *sdi)
f4816ac6 981{
ae1bc1cc 982 struct sr_scpi_dev_inst *scpi;
29d957ce 983 struct dev_context *devc;
ba7dd8bb 984 struct sr_channel *ch;
f76c24f6 985 struct sr_datafeed_packet packet;
702f42e8 986 gboolean some_digital;
254dd102 987 GSList *l;
29d957ce 988
ae1bc1cc 989 scpi = sdi->conn;
29d957ce
UH
990 devc = sdi->priv;
991
51b294cd
ML
992 devc->num_frames = 0;
993
702f42e8 994 some_digital = FALSE;
ba7dd8bb
UH
995 for (l = sdi->channels; l; l = l->next) {
996 ch = l->data;
997 sr_dbg("handling channel %s", ch->name);
3f239f08 998 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 999 if (ch->enabled)
702f42e8
ML
1000 devc->enabled_channels = g_slist_append(
1001 devc->enabled_channels, ch);
ba7dd8bb 1002 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 1003 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
1004 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
1005 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 1006 return SR_ERR;
ba7dd8bb 1007 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 1008 }
3f239f08 1009 } else if (ch->type == SR_CHANNEL_LOGIC) {
01dd7a4c
ML
1010 /* Only one list entry for older protocols. All channels are
1011 * retrieved together when this entry is processed. */
702f42e8 1012 if (ch->enabled && (
01dd7a4c 1013 devc->model->series->protocol > PROTOCOL_V3 ||
702f42e8
ML
1014 !some_digital))
1015 devc->enabled_channels = g_slist_append(
1016 devc->enabled_channels, ch);
ba7dd8bb 1017 if (ch->enabled) {
702f42e8 1018 some_digital = TRUE;
04e8e01e
ML
1019 /* Turn on LA module if currently off. */
1020 if (!devc->la_enabled) {
702f42e8 1021 if (rigol_ds_config_set(sdi,
01dd7a4c 1022 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 1023 ":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
04e8e01e
ML
1024 return SR_ERR;
1025 devc->la_enabled = TRUE;
1026 }
1027 }
ba7dd8bb 1028 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 1029 /* Enabled channel is currently disabled, or vice versa. */
702f42e8 1030 if (rigol_ds_config_set(sdi,
01dd7a4c 1031 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 1032 ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
ba7dd8bb 1033 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 1034 return SR_ERR;
ba7dd8bb 1035 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 1036 }
254dd102
BV
1037 }
1038 }
1fed20cb 1039
702f42e8 1040 if (!devc->enabled_channels)
254dd102 1041 return SR_ERR;
e0b7d23c 1042
ba7dd8bb 1043 /* Turn off LA module if on and no digital channels selected. */
702f42e8
ML
1044 if (devc->la_enabled && !some_digital)
1045 if (rigol_ds_config_set(sdi,
01dd7a4c 1046 devc->model->series->protocol >= PROTOCOL_V3 ?
702f42e8 1047 ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
1048 return SR_ERR;
1049
e086b750
ML
1050 /* Set memory mode. */
1051 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
1052 sr_err("Data source 'Segmented' not yet supported");
1053 return SR_ERR;
1054 }
1055
1056 devc->analog_frame_size = analog_frame_size(sdi);
1057 devc->digital_frame_size = digital_frame_size(sdi);
1058
569d4dbd
ML
1059 switch (devc->model->series->protocol) {
1060 case PROTOCOL_V2:
99af83b7 1061 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 1062 return SR_ERR;
569d4dbd
ML
1063 break;
1064 case PROTOCOL_V3:
e086b750
ML
1065 /* Apparently for the DS2000 the memory
1066 * depth can only be set in Running state -
1067 * this matches the behaviour of the UI. */
38354d9d 1068 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1069 return SR_ERR;
e086b750
ML
1070 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1071 devc->analog_frame_size) != SR_OK)
1072 return SR_ERR;
1073 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1074 return SR_ERR;
569d4dbd
ML
1075 break;
1076 default:
1077 break;
1fed20cb
ML
1078 }
1079
e086b750
ML
1080 if (devc->data_source == DATA_SOURCE_LIVE)
1081 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1082 return SR_ERR;
1083
102f1239
BV
1084 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1085 rigol_ds_receive, (void *)sdi);
e0b7d23c 1086
bee2b016 1087 std_session_send_df_header(sdi);
e0b7d23c 1088
702f42e8 1089 devc->channel_entry = devc->enabled_channels;
821fbcad 1090
e086b750
ML
1091 if (rigol_ds_capture_start(sdi) != SR_OK)
1092 return SR_ERR;
f4816ac6 1093
f76c24f6
ML
1094 /* Start of first frame. */
1095 packet.type = SR_DF_FRAME_BEGIN;
695dc859 1096 sr_session_send(sdi, &packet);
f76c24f6 1097
f4816ac6
ML
1098 return SR_OK;
1099}
1100
695dc859 1101static int dev_acquisition_stop(struct sr_dev_inst *sdi)
f4816ac6 1102{
29d957ce 1103 struct dev_context *devc;
ae1bc1cc 1104 struct sr_scpi_dev_inst *scpi;
29d957ce 1105
29d957ce
UH
1106 devc = sdi->priv;
1107
bee2b016 1108 std_session_send_df_end(sdi);
b751cf7a 1109
702f42e8
ML
1110 g_slist_free(devc->enabled_channels);
1111 devc->enabled_channels = NULL;
ae1bc1cc 1112 scpi = sdi->conn;
102f1239 1113 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
1114
1115 return SR_OK;
1116}
1117
dd5c48a6 1118static struct sr_dev_driver rigol_ds_driver_info = {
3086efdd
ML
1119 .name = "rigol-ds",
1120 .longname = "Rigol DS",
f4816ac6 1121 .api_version = 1,
c2fdcc25 1122 .init = std_init,
700d6b64 1123 .cleanup = std_cleanup,
6078d2c9 1124 .scan = scan,
c01bf34c 1125 .dev_list = std_dev_list,
3b412e3a 1126 .dev_clear = dev_clear,
d62d7ad1 1127 .config_get = config_get,
035a1078 1128 .config_set = config_set,
a1c743fc 1129 .config_list = config_list,
6078d2c9
UH
1130 .dev_open = dev_open,
1131 .dev_close = dev_close,
254dd102
BV
1132 .dev_acquisition_start = dev_acquisition_start,
1133 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 1134 .context = NULL,
f4816ac6 1135};
dd5c48a6 1136SR_REGISTER_DEV_DRIVER(rigol_ds_driver_info);