]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
rigol-ds: Use common rigol_ds_config_set() function throughout.
[libsigrok.git] / 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
e0b7d23c
ML
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
2b0e4a46 26#include <math.h>
f4816ac6
ML
27#include <glib.h>
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
31
ca55277c
ML
32static const int32_t hwopts[] = {
33 SR_CONF_CONN,
0dc7b43e 34 SR_CONF_SERIALCOMM
ca55277c
ML
35};
36
f6a0ac9f 37static const int32_t hwcaps[] = {
1953564a 38 SR_CONF_OSCILLOSCOPE,
1953564a
BV
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
d62d7ad1 43 SR_CONF_NUM_TIMEBASE,
c1bcb8cc 44 SR_CONF_LIMIT_FRAMES,
4914dd4b 45 SR_CONF_SAMPLERATE,
f48e0249
ML
46};
47
48static const int32_t analog_hwcaps[] = {
d62d7ad1 49 SR_CONF_NUM_VDIV,
f48e0249 50 SR_CONF_VDIV,
78bcc55a 51 SR_CONF_COUPLING,
babab622 52 SR_CONF_DATA_SOURCE,
e0b7d23c
ML
53};
54
f6a0ac9f 55static const uint64_t timebases[][2] = {
e0b7d23c 56 /* nanoseconds */
8e06edf5 57 { 1, 1000000000 },
e0b7d23c
ML
58 { 2, 1000000000 },
59 { 5, 1000000000 },
60 { 10, 1000000000 },
61 { 20, 1000000000 },
62 { 50, 1000000000 },
63 { 100, 1000000000 },
64 { 500, 1000000000 },
65 /* microseconds */
66 { 1, 1000000 },
67 { 2, 1000000 },
68 { 5, 1000000 },
69 { 10, 1000000 },
70 { 20, 1000000 },
71 { 50, 1000000 },
72 { 100, 1000000 },
73 { 200, 1000000 },
74 { 500, 1000000 },
75 /* milliseconds */
76 { 1, 1000 },
77 { 2, 1000 },
78 { 5, 1000 },
79 { 10, 1000 },
80 { 20, 1000 },
81 { 50, 1000 },
82 { 100, 1000 },
83 { 200, 1000 },
84 { 500, 1000 },
85 /* seconds */
86 { 1, 1 },
87 { 2, 1 },
88 { 5, 1 },
89 { 10, 1 },
90 { 20, 1 },
91 { 50, 1 },
bafd4890
ML
92 { 100, 1 },
93 { 200, 1 },
94 { 500, 1 },
8e06edf5 95 { 1000, 1 },
e0b7d23c
ML
96};
97
f6a0ac9f 98static const uint64_t vdivs[][2] = {
bafd4890
ML
99 /* microvolts */
100 { 500, 1000000 },
e0b7d23c 101 /* millivolts */
bafd4890 102 { 1, 1000 },
e0b7d23c
ML
103 { 2, 1000 },
104 { 5, 1000 },
105 { 10, 1000 },
106 { 20, 1000 },
107 { 50, 1000 },
108 { 100, 1000 },
109 { 200, 1000 },
110 { 500, 1000 },
111 /* volts */
112 { 1, 1 },
113 { 2, 1 },
114 { 5, 1 },
115 { 10, 1 },
e0b7d23c
ML
116};
117
bafd4890
ML
118#define NUM_TIMEBASE ARRAY_SIZE(timebases)
119#define NUM_VDIV ARRAY_SIZE(vdivs)
120
e0b7d23c
ML
121static const char *trigger_sources[] = {
122 "CH1",
123 "CH2",
821fbcad
ML
124 "CH3",
125 "CH4",
e0b7d23c
ML
126 "EXT",
127 "AC Line",
6bb192bc
ML
128 "D0",
129 "D1",
130 "D2",
131 "D3",
132 "D4",
133 "D5",
134 "D6",
135 "D7",
136 "D8",
137 "D9",
138 "D10",
139 "D11",
140 "D12",
141 "D13",
142 "D14",
143 "D15",
e0b7d23c
ML
144};
145
146static const char *coupling[] = {
147 "AC",
148 "DC",
149 "GND",
e0b7d23c
ML
150};
151
babab622
ML
152/* Do not change the order of entries */
153static const char *data_sources[] = {
154 "Live",
155 "Memory",
156 "Segmented",
157};
158
159/*
160 * name, series, protocol flavor, min timebase, max timebase, min vdiv,
161 * digital channels, number of horizontal divs
162 */
10afee13
ML
163
164#define RIGOL "Rigol Technologies"
165#define AGILENT "Agilent Technologies"
fcdebbe8
BV
166#define RIGOL_SHORT "Rigol"
167#define AGILENT_SHORT "Agilent"
10afee13 168
bafd4890 169static const struct rigol_ds_model supported_models[] = {
470140fc
ML
170 {RIGOL, "DS1052E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
171 {RIGOL, "DS1102E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
172 {RIGOL, "DS1152E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
173 {RIGOL, "DS1052D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
174 {RIGOL, "DS1102D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
175 {RIGOL, "DS1152D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
821fbcad
ML
176 {RIGOL, "DS2072", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
177 {RIGOL, "DS2102", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
178 {RIGOL, "DS2202", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
036d378a
AJ
179 {RIGOL, "DS2302", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
180 {RIGOL, "DS2072A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
181 {RIGOL, "DS2102A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
182 {RIGOL, "DS2202A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
183 {RIGOL, "DS2302A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
821fbcad
ML
184 {RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
185 {RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
186 {RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
187 {RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
188 {RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
189 {RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
190 {RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
191 {RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
192 {RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
193 {RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
227a0981
ML
194 {AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
195 {AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
196 {AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
821fbcad 197 {AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
227a0981
ML
198 {AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
199 {AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
512bb890
BV
200};
201
3086efdd
ML
202SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
203static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 204
fa85f376 205static void clear_helper(void *priv)
f4816ac6 206{
f4816ac6 207 struct dev_context *devc;
f4816ac6 208
ba358ffd 209 devc = priv;
babab622
ML
210 g_free(devc->data);
211 g_free(devc->buffer);
fa85f376
UH
212 g_free(devc->coupling[0]);
213 g_free(devc->coupling[1]);
214 g_free(devc->trigger_source);
215 g_free(devc->trigger_slope);
ba358ffd
BV
216 g_slist_free(devc->analog_groups[0].probes);
217 g_slist_free(devc->analog_groups[1].probes);
218 g_slist_free(devc->digital_group.probes);
fa85f376 219}
f4816ac6 220
3b412e3a 221static int dev_clear(void)
fa85f376
UH
222{
223 return std_dev_clear(di, clear_helper);
f4816ac6
ML
224}
225
6078d2c9 226static int init(struct sr_context *sr_ctx)
f4816ac6 227{
f6beaac5 228 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
229}
230
3520422f 231static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
f4816ac6 232{
cc9fd2d2
BV
233 struct dev_context *devc;
234 struct sr_dev_inst *sdi;
ae1bc1cc
ML
235 struct sr_scpi_dev_inst *scpi;
236 struct sr_scpi_hw_info *hw_info;
cc9fd2d2 237 struct sr_probe *probe;
8dd0b290 238 long n[3];
f6a0ac9f 239 unsigned int i;
bafd4890 240 const struct rigol_ds_model *model = NULL;
8dd0b290 241 gchar *channel_name, *vendor, **version;
fb6e5ba8 242
46a743c1 243 *devices = NULL;
0dc7b43e 244
c3515cea
AJ
245 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
246 return SR_ERR;
9bd4c956 247
ae1bc1cc 248 if (sr_scpi_open(scpi) != SR_OK) {
10afee13 249 sr_info("Couldn't open SCPI device.");
ae1bc1cc 250 sr_scpi_free(scpi);
9bd4c956 251 return SR_ERR;
ae1bc1cc 252 };
9bd4c956 253
ae1bc1cc
ML
254 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
255 sr_info("Couldn't get IDN response.");
256 sr_scpi_close(scpi);
257 sr_scpi_free(scpi);
258 return SR_ERR;
ca55277c 259 }
e0b7d23c 260
ca55277c 261 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
10afee13
ML
262 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
263 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 264 model = &supported_models[i];
ca55277c 265 break;
fb6e5ba8 266 }
ca55277c 267 }
fb6e5ba8 268
fcdebbe8
BV
269 if (!strcmp(hw_info->manufacturer, RIGOL))
270 vendor = RIGOL_SHORT;
271 else if (!strcmp(hw_info->manufacturer, AGILENT))
272 vendor = AGILENT_SHORT;
273 else
274 vendor = hw_info->manufacturer;
bafd4890 275 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
fcdebbe8 276 vendor, hw_info->model,
ae1bc1cc
ML
277 hw_info->firmware_version))) {
278 sr_scpi_hw_info_free(hw_info);
b4936bae 279 sr_scpi_close(scpi);
ae1bc1cc 280 sr_scpi_free(scpi);
ca55277c
ML
281 return SR_ERR_NA;
282 }
fb6e5ba8 283
b4936bae 284 sr_scpi_close(scpi);
ae1bc1cc
ML
285
286 sdi->conn = scpi;
fb6e5ba8 287
cc9fd2d2 288 sdi->driver = di;
ae1bc1cc 289 sdi->inst_type = SR_INST_SCPI;
512bb890 290
cc9fd2d2 291 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 292 return SR_ERR_MALLOC;
ae1bc1cc 293
cc9fd2d2 294 devc->limit_frames = 0;
bafd4890 295 devc->model = model;
8dd0b290
BV
296 devc->protocol = model->protocol;
297
298 /* DS1000 models with firmware before 0.2.4 used the old
299 * legacy protocol. */
300 if (model->series == RIGOL_DS1000) {
301 version = g_strsplit(hw_info->firmware_version, ".", 0);
302 do {
303 if (!version[0] || !version[1] || !version[2])
304 break;
305 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
306 break;
307 for (i = 0; i < 3; i++) {
308 if (sr_atol(version[i], &n[i]) != SR_OK)
309 break;
310 }
311 if (i != 3)
312 break;
313 if (n[0] != 0 || n[1] > 2)
314 break;
315 if (n[1] == 2 && n[2] > 3)
316 break;
317 sr_dbg("Found DS1000 firmware < 0.2.4, using old protocol.");
318 devc->protocol = PROTOCOL_LEGACY;
319 } while(0);
320 g_strfreev(version);
321 }
322
323 sr_scpi_hw_info_free(hw_info);
512bb890 324
821fbcad
ML
325 for (i = 0; i < model->analog_channels; i++) {
326 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
ca55277c 327 return SR_ERR_MALLOC;
821fbcad 328 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
ca55277c 329 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
330 devc->analog_groups[i].name = channel_name;
331 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
332 sdi->probe_groups = g_slist_append(sdi->probe_groups,
333 &devc->analog_groups[i]);
ca55277c 334 }
512bb890 335
bafd4890 336 if (devc->model->has_digital) {
ca55277c
ML
337 for (i = 0; i < 16; i++) {
338 if (!(channel_name = g_strdup_printf("D%d", i)))
339 return SR_ERR_MALLOC;
340 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
341 g_free(channel_name);
342 if (!probe)
343 return SR_ERR_MALLOC;
344 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
345 devc->digital_group.probes = g_slist_append(
346 devc->digital_group.probes, probe);
512bb890 347 }
b3916147
ML
348 devc->digital_group.name = "LA";
349 sdi->probe_groups = g_slist_append(sdi->probe_groups,
350 &devc->digital_group);
ca55277c 351 }
bafd4890
ML
352
353 for (i = 0; i < NUM_TIMEBASE; i++) {
354 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
355 devc->timebases = &timebases[i];
356 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
357 devc->num_timebases = &timebases[i] - devc->timebases + 1;
358 }
359
0709197d
ML
360 for (i = 0; i < NUM_VDIV; i++)
361 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 362 devc->vdivs = &vdivs[i];
bafd4890 363
babab622
ML
364 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
365 return SR_ERR_MALLOC;
366 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
367 return SR_ERR_MALLOC;
368
369 devc->data_source = DATA_SOURCE_LIVE;
370
cc9fd2d2
BV
371 sdi->priv = devc;
372
373 *devices = g_slist_append(NULL, sdi);
512bb890 374
ca55277c
ML
375 return SR_OK;
376}
512bb890 377
6078d2c9 378static GSList *scan(GSList *options)
ca55277c
ML
379{
380 struct drv_context *drvc;
ca55277c 381 struct sr_config *src;
cc9fd2d2 382 GSList *l, *devices;
ca55277c 383 GDir *dir;
ca55277c 384 int ret;
cc9fd2d2
BV
385 const gchar *dev_name;
386 gchar *port = NULL;
0dc7b43e 387 gchar *serialcomm = NULL;
fb6e5ba8 388
ca55277c 389 drvc = di->priv;
d2e0b1fa 390
ca55277c
ML
391 for (l = options; l; l = l->next) {
392 src = l->data;
0dc7b43e
ML
393 switch (src->key) {
394 case SR_CONF_CONN:
cc9fd2d2 395 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 396 break;
0dc7b43e
ML
397 case SR_CONF_SERIALCOMM:
398 serialcomm = (char *)g_variant_get_string(src->data, NULL);
399 break;
fb6e5ba8 400 }
ca55277c 401 }
fb6e5ba8 402
46a743c1 403 devices = NULL;
cc9fd2d2 404 if (port) {
0dc7b43e
ML
405 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
406 g_free(port);
407 if (serialcomm)
408 g_free(serialcomm);
ca55277c 409 return NULL;
0dc7b43e 410 }
ca55277c 411 } else {
da970d24
BV
412 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
413 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
414 return NULL;
ca55277c 415 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 416 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 417 continue;
cc9fd2d2 418 port = g_strconcat("/dev/", dev_name, NULL);
0dc7b43e 419 ret = probe_port(port, serialcomm, &devices);
cc9fd2d2 420 g_free(port);
0dc7b43e
ML
421 if (serialcomm)
422 g_free(serialcomm);
ca55277c
ML
423 if (ret == SR_ERR_MALLOC) {
424 g_dir_close(dir);
ca55277c 425 return NULL;
6bb192bc
ML
426 }
427 }
ca55277c
ML
428 g_dir_close(dir);
429 }
f4816ac6 430
46a743c1
BV
431 /* Tack a copy of the newly found devices onto the driver list. */
432 l = g_slist_copy(devices);
433 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 434
f4816ac6
ML
435 return devices;
436}
437
6078d2c9 438static GSList *dev_list(void)
f4816ac6 439{
0e94d524 440 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
441}
442
6078d2c9 443static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 444{
ae1bc1cc 445 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 446
ae1bc1cc 447 if (sr_scpi_open(scpi) < 0)
e0b7d23c 448 return SR_ERR;
e0b7d23c 449
3086efdd 450 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 451 return SR_ERR;
f4816ac6 452
46a743c1 453 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 454
f4816ac6
ML
455 return SR_OK;
456}
457
6078d2c9 458static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 459{
ae1bc1cc 460 struct sr_scpi_dev_inst *scpi;
22c19688 461 struct dev_context *devc;
ae1bc1cc
ML
462
463 scpi = sdi->conn;
22c19688
ML
464 devc = sdi->priv;
465
466 if (devc->model->series != RIGOL_VS5000)
38354d9d 467 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 468
ae1bc1cc
ML
469 if (scpi) {
470 if (sr_scpi_close(scpi) < 0)
471 return SR_ERR;
cc9fd2d2
BV
472 sdi->status = SR_ST_INACTIVE;
473 }
f4816ac6
ML
474
475 return SR_OK;
476}
477
6078d2c9 478static int cleanup(void)
f4816ac6 479{
3b412e3a 480 return dev_clear();
f4816ac6
ML
481}
482
5415e602
ML
483static int analog_frame_size(const struct sr_dev_inst *sdi)
484{
485 struct dev_context *devc = sdi->priv;
486 struct sr_probe *probe;
487 int analog_probes = 0;
488 GSList *l;
489
470140fc
ML
490 switch (devc->model->series) {
491 case RIGOL_VS5000:
492 return VS5000_ANALOG_LIVE_WAVEFORM_SIZE;
493 case RIGOL_DS1000:
494 return DS1000_ANALOG_LIVE_WAVEFORM_SIZE;
495 default:
5415e602
ML
496 for (l = sdi->probes; l; l = l->next) {
497 probe = l->data;
498 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
499 analog_probes++;
500 }
501 if (devc->data_source == DATA_SOURCE_MEMORY) {
502 if (analog_probes == 1)
503 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
504 else
505 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
506 } else {
507 if (devc->model->series == AGILENT_DSO1000)
508 return DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
509 else
510 return DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
511 }
512 }
513}
514
d22250a9
ML
515static int digital_frame_size(const struct sr_dev_inst *sdi)
516{
517 struct dev_context *devc = sdi->priv;
518
519 switch (devc->model->series) {
520 case RIGOL_VS5000:
521 return VS5000_DIGITAL_WAVEFORM_SIZE;
522 case RIGOL_DS1000:
523 return DS1000_DIGITAL_WAVEFORM_SIZE;
524 default:
525 return 0;
526 }
527}
528
8f996b89
ML
529static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
530 const struct sr_probe_group *probe_group)
d62d7ad1 531{
e43fdd8d 532 struct dev_context *devc;
2b0e4a46
AJ
533 struct sr_probe *probe;
534 const char *tmp_str;
c2b394d5 535 uint64_t samplerate;
2b0e4a46
AJ
536 int analog_channel = -1;
537 float smallest_diff = 0.0000000001;
538 int idx = -1;
539 unsigned i;
d62d7ad1 540
e43fdd8d
BV
541 if (!sdi || !(devc = sdi->priv))
542 return SR_ERR_ARG;
543
be60a9e4 544 /* If a probe group is specified, it must be a valid one. */
c2b394d5 545 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
546 sr_err("Invalid probe group specified.");
547 return SR_ERR;
be60a9e4
BV
548 }
549
2b0e4a46
AJ
550 if (probe_group) {
551 probe = g_slist_nth_data(probe_group->probes, 0);
552 if (!probe)
553 return SR_ERR;
554 if (probe->type == SR_PROBE_ANALOG) {
555 if (probe->name[2] < '1' || probe->name[2] > '4')
556 return SR_ERR;
557 analog_channel = probe->name[2] - '1';
558 }
559 }
560
d62d7ad1
BV
561 switch (id) {
562 case SR_CONF_NUM_TIMEBASE:
0709197d 563 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
d62d7ad1
BV
564 break;
565 case SR_CONF_NUM_VDIV:
72ecba02 566 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
567 case SR_CONF_DATA_SOURCE:
568 if (devc->data_source == DATA_SOURCE_LIVE)
569 *data = g_variant_new_string("Live");
570 else if (devc->data_source == DATA_SOURCE_MEMORY)
571 *data = g_variant_new_string("Memory");
572 else
573 *data = g_variant_new_string("Segmented");
574 break;
4914dd4b
ML
575 case SR_CONF_SAMPLERATE:
576 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 577 samplerate = analog_frame_size(sdi) /
4914dd4b
ML
578 (devc->timebase * devc->model->num_horizontal_divs);
579 *data = g_variant_new_uint64(samplerate);
c2b394d5 580 } else {
4914dd4b 581 return SR_ERR_NA;
c2b394d5 582 }
4914dd4b 583 break;
2b0e4a46
AJ
584 case SR_CONF_TRIGGER_SOURCE:
585 if (!strcmp(devc->trigger_source, "ACL"))
586 tmp_str = "AC Line";
587 else if (!strcmp(devc->trigger_source, "CHAN1"))
588 tmp_str = "CH1";
589 else if (!strcmp(devc->trigger_source, "CHAN2"))
590 tmp_str = "CH2";
591 else if (!strcmp(devc->trigger_source, "CHAN3"))
592 tmp_str = "CH3";
593 else if (!strcmp(devc->trigger_source, "CHAN4"))
594 tmp_str = "CH4";
595 else
596 tmp_str = devc->trigger_source;
597 *data = g_variant_new_string(tmp_str);
598 break;
599 case SR_CONF_TIMEBASE:
600 for (i = 0; i < devc->num_timebases; i++) {
601 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
602 float diff = fabs(devc->timebase - tb);
603 if (diff < smallest_diff) {
604 smallest_diff = diff;
605 idx = i;
606 }
607 }
608 if (idx < 0)
609 return SR_ERR_NA;
610 *data = g_variant_new("(tt)", devc->timebases[idx][0],
611 devc->timebases[idx][1]);
612 break;
613 case SR_CONF_VDIV:
614 if (analog_channel < 0)
615 return SR_ERR_NA;
616 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
617 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
618 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
619 if (diff < smallest_diff) {
620 smallest_diff = diff;
621 idx = i;
622 }
623 }
624 if (idx < 0)
625 return SR_ERR_NA;
626 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
627 break;
628 case SR_CONF_COUPLING:
629 if (analog_channel < 0)
630 return SR_ERR_NA;
631 *data = g_variant_new_string(devc->coupling[analog_channel]);
632 break;
d62d7ad1 633 default:
bd6fbf62 634 return SR_ERR_NA;
d62d7ad1
BV
635 }
636
637 return SR_OK;
638}
639
8f996b89
ML
640static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
641 const struct sr_probe_group *probe_group)
f4816ac6 642{
29d957ce 643 struct dev_context *devc;
f6a0ac9f 644 uint64_t tmp_u64, p, q;
254dd102 645 double t_dbl;
f48e0249 646 unsigned int i, j;
254dd102
BV
647 int ret;
648 const char *tmp_str;
889ef4a0 649 char buffer[16];
f4816ac6 650
e43fdd8d
BV
651 if (!(devc = sdi->priv))
652 return SR_ERR_ARG;
29d957ce 653
e73ffd42
BV
654 if (sdi->status != SR_ST_ACTIVE)
655 return SR_ERR_DEV_CLOSED;
f4816ac6 656
be60a9e4 657 /* If a probe group is specified, it must be a valid one. */
c2b394d5 658 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
659 sr_err("Invalid probe group specified.");
660 return SR_ERR;
be60a9e4
BV
661 }
662
f4816ac6 663 ret = SR_OK;
035a1078 664 switch (id) {
1953564a 665 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 666 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 667 break;
1953564a 668 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 669 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
670 if (tmp_u64 != 0 && tmp_u64 != 1)
671 return SR_ERR;
672 g_free(devc->trigger_slope);
673 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
38354d9d 674 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 675 break;
1953564a 676 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
677 t_dbl = g_variant_get_double(data);
678 if (t_dbl < 0.0 || t_dbl > 1.0)
679 return SR_ERR;
680 devc->horiz_triggerpos = t_dbl;
681 /* We have the trigger offset as a percentage of the frame, but
682 * need to express this in seconds. */
bafd4890 683 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 684 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 685 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 686 break;
1953564a 687 case SR_CONF_TIMEBASE:
f6a0ac9f 688 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
689 for (i = 0; i < devc->num_timebases; i++) {
690 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 691 devc->timebase = (float)p / q;
889ef4a0
AJ
692 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
693 devc->timebase);
38354d9d 694 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
695 break;
696 }
697 }
bafd4890 698 if (i == devc->num_timebases)
254dd102 699 ret = SR_ERR_ARG;
e0b7d23c 700 break;
1953564a 701 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 702 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
703 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
704 if (!strcmp(trigger_sources[i], tmp_str)) {
705 g_free(devc->trigger_source);
706 devc->trigger_source = g_strdup(trigger_sources[i]);
707 if (!strcmp(devc->trigger_source, "AC Line"))
708 tmp_str = "ACL";
709 else if (!strcmp(devc->trigger_source, "CH1"))
710 tmp_str = "CHAN1";
711 else if (!strcmp(devc->trigger_source, "CH2"))
712 tmp_str = "CHAN2";
821fbcad
ML
713 else if (!strcmp(devc->trigger_source, "CH3"))
714 tmp_str = "CHAN3";
715 else if (!strcmp(devc->trigger_source, "CH4"))
716 tmp_str = "CHAN4";
254dd102
BV
717 else
718 tmp_str = (char *)devc->trigger_source;
38354d9d 719 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
720 break;
721 }
4e108ace 722 }
254dd102
BV
723 if (i == ARRAY_SIZE(trigger_sources))
724 ret = SR_ERR_ARG;
e0b7d23c 725 break;
1953564a 726 case SR_CONF_VDIV:
be60a9e4
BV
727 if (!probe_group) {
728 sr_err("No probe group specified.");
729 return SR_ERR_PROBE_GROUP;
730 }
f6a0ac9f 731 g_variant_get(data, "(tt)", &p, &q);
f48e0249 732 for (i = 0; i < 2; i++) {
78bcc55a
BV
733 if (probe_group == &devc->analog_groups[i]) {
734 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
735 if (vdivs[j][0] != p || vdivs[j][1] != q)
736 continue;
737 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
738 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
739 devc->vdiv[i]);
38354d9d 740 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 741 buffer);
f48e0249
ML
742 }
743 return SR_ERR_ARG;
744 }
e0b7d23c 745 }
f48e0249 746 return SR_ERR_NA;
1953564a 747 case SR_CONF_COUPLING:
78bcc55a
BV
748 if (!probe_group) {
749 sr_err("No probe group specified.");
750 return SR_ERR_PROBE_GROUP;
751 }
f6a0ac9f 752 tmp_str = g_variant_get_string(data, NULL);
f48e0249 753 for (i = 0; i < 2; i++) {
78bcc55a
BV
754 if (probe_group == &devc->analog_groups[i]) {
755 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
756 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
757 g_free(devc->coupling[i]);
758 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 759 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
760 devc->coupling[i]);
761 }
762 }
763 return SR_ERR_ARG;
e0b7d23c
ML
764 }
765 }
f48e0249 766 return SR_ERR_NA;
babab622
ML
767 case SR_CONF_DATA_SOURCE:
768 tmp_str = g_variant_get_string(data, NULL);
769 if (!strcmp(tmp_str, "Live"))
770 devc->data_source = DATA_SOURCE_LIVE;
771 else if (!strcmp(tmp_str, "Memory"))
772 devc->data_source = DATA_SOURCE_MEMORY;
470140fc 773 else if (devc->model->series >= RIGOL_DS1000Z
babab622
ML
774 && !strcmp(tmp_str, "Segmented"))
775 devc->data_source = DATA_SOURCE_SEGMENTED;
776 else
777 return SR_ERR;
778 break;
f4816ac6 779 default:
bd6fbf62 780 ret = SR_ERR_NA;
29d957ce 781 break;
f4816ac6
ML
782 }
783
784 return ret;
785}
786
8f996b89
ML
787static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
788 const struct sr_probe_group *probe_group)
a1c743fc 789{
861c447b
BV
790 GVariant *tuple, *rational[2];
791 GVariantBuilder gvb;
792 unsigned int i;
7cc1a550
ML
793 struct dev_context *devc = NULL;
794
795 if (sdi)
796 devc = sdi->priv;
8f996b89 797
e43fdd8d 798 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
799 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
800 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
801 return SR_OK;
802 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
803 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
804 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
805 return SR_OK;
806 }
807
808 /* Every other option requires a valid device instance. */
809 if (!sdi || !(devc = sdi->priv))
810 return SR_ERR_ARG;
811
be60a9e4
BV
812 /* If a probe group is specified, it must be a valid one. */
813 if (probe_group) {
814 if (probe_group != &devc->analog_groups[0]
815 && probe_group != &devc->analog_groups[1]) {
816 sr_err("Invalid probe group specified.");
817 return SR_ERR;
818 }
819 }
820
e43fdd8d 821 switch (key) {
9a6517d1 822 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
823 if (!probe_group) {
824 sr_err("No probe group specified.");
825 return SR_ERR_PROBE_GROUP;
826 }
e43fdd8d 827 if (probe_group == &devc->digital_group) {
f48e0249
ML
828 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
829 NULL, 0, sizeof(int32_t));
830 return SR_OK;
831 } else {
832 for (i = 0; i < 2; i++) {
833 if (probe_group == &devc->analog_groups[i]) {
834 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
835 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
836 return SR_OK;
837 }
838 }
839 return SR_ERR_NA;
840 }
5f77dffc 841 break;
2a7b113d 842 case SR_CONF_COUPLING:
be60a9e4
BV
843 if (!probe_group) {
844 sr_err("No probe group specified.");
845 return SR_ERR_PROBE_GROUP;
f48e0249 846 }
58f43369
BV
847 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
848 break;
e4f2b2ad 849 case SR_CONF_VDIV:
7cc1a550
ML
850 if (!devc)
851 /* Can't know this until we have the exact model. */
852 return SR_ERR_ARG;
be60a9e4
BV
853 if (!probe_group) {
854 sr_err("No probe group specified.");
855 return SR_ERR_PROBE_GROUP;
861c447b 856 }
58f43369 857 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 858 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
859 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
860 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
861 tuple = g_variant_new_tuple(rational, 2);
862 g_variant_builder_add_value(&gvb, tuple);
863 }
864 *data = g_variant_builder_end(&gvb);
865 break;
41f5bd09 866 case SR_CONF_TIMEBASE:
7cc1a550
ML
867 if (!devc)
868 /* Can't know this until we have the exact model. */
869 return SR_ERR_ARG;
a31b2ccb
AJ
870 if (devc->num_timebases <= 0)
871 return SR_ERR_NA;
861c447b 872 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
873 for (i = 0; i < devc->num_timebases; i++) {
874 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
875 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
876 tuple = g_variant_new_tuple(rational, 2);
877 g_variant_builder_add_value(&gvb, tuple);
878 }
879 *data = g_variant_builder_end(&gvb);
41f5bd09 880 break;
328bafab 881 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
882 if (!devc)
883 /* Can't know this until we have the exact model. */
884 return SR_ERR_ARG;
f6a0ac9f 885 *data = g_variant_new_strv(trigger_sources,
bafd4890 886 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 887 break;
babab622
ML
888 case SR_CONF_DATA_SOURCE:
889 if (!devc)
890 /* Can't know this until we have the exact model. */
891 return SR_ERR_ARG;
892 /* This needs tweaking by series/model! */
893 if (devc->model->series == RIGOL_DS2000)
894 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
895 else
896 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
897 break;
a1c743fc 898 default:
bd6fbf62 899 return SR_ERR_NA;
a1c743fc
BV
900 }
901
902 return SR_OK;
903}
904
254dd102 905static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 906{
ae1bc1cc 907 struct sr_scpi_dev_inst *scpi;
29d957ce 908 struct dev_context *devc;
254dd102 909 struct sr_probe *probe;
f76c24f6 910 struct sr_datafeed_packet packet;
254dd102 911 GSList *l;
29d957ce 912
e73ffd42
BV
913 if (sdi->status != SR_ST_ACTIVE)
914 return SR_ERR_DEV_CLOSED;
e0b7d23c 915
ae1bc1cc 916 scpi = sdi->conn;
29d957ce
UH
917 devc = sdi->priv;
918
51b294cd
ML
919 devc->num_frames = 0;
920
254dd102
BV
921 for (l = sdi->probes; l; l = l->next) {
922 probe = l->data;
6bb192bc
ML
923 sr_dbg("handling probe %s", probe->name);
924 if (probe->type == SR_PROBE_ANALOG) {
925 if (probe->enabled)
926 devc->enabled_analog_probes = g_slist_append(
927 devc->enabled_analog_probes, probe);
928 if (probe->enabled != devc->analog_channels[probe->index]) {
929 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 930 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", probe->index + 1,
6396b0a7 931 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 932 return SR_ERR;
904fd29b 933 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
934 }
935 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 936 if (probe->enabled) {
6bb192bc
ML
937 devc->enabled_digital_probes = g_slist_append(
938 devc->enabled_digital_probes, probe);
04e8e01e
ML
939 /* Turn on LA module if currently off. */
940 if (!devc->la_enabled) {
38354d9d 941 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
942 return SR_ERR;
943 devc->la_enabled = TRUE;
944 }
945 }
6bb192bc
ML
946 if (probe->enabled != devc->digital_channels[probe->index]) {
947 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 948 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", probe->index,
6396b0a7 949 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 950 return SR_ERR;
904fd29b 951 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 952 }
254dd102
BV
953 }
954 }
1fed20cb 955
6bb192bc 956 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 957 return SR_ERR;
e0b7d23c 958
04e8e01e
ML
959 /* Turn off LA module if on and no digital probes selected. */
960 if (devc->la_enabled && !devc->enabled_digital_probes)
38354d9d 961 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
962 return SR_ERR;
963
1fed20cb 964 if (devc->data_source == DATA_SOURCE_LIVE) {
38354d9d 965 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb
ML
966 return SR_ERR;
967 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
968 if (devc->model->series != RIGOL_DS2000) {
969 sr_err("Data source 'Memory' not supported for this device");
970 return SR_ERR;
971 }
972 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
973 sr_err("Data source 'Segmented' not yet supported");
974 return SR_ERR;
975 }
976
ae1bc1cc 977 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
978
979 /* Send header packet to the session bus. */
29a27196 980 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 981
821fbcad
ML
982 if (devc->enabled_analog_probes)
983 devc->channel_entry = devc->enabled_analog_probes;
984 else
985 devc->channel_entry = devc->enabled_digital_probes;
986
5415e602 987 devc->analog_frame_size = analog_frame_size(sdi);
d22250a9 988 devc->digital_frame_size = digital_frame_size(sdi);
5415e602 989
470140fc 990 if (devc->model->series < RIGOL_DS1000Z) {
bafd4890 991 /* Fetch the first frame. */
677f85d0
ML
992 if (rigol_ds_channel_start(sdi) != SR_OK)
993 return SR_ERR;
6bb192bc 994 } else {
bafd4890 995 if (devc->enabled_analog_probes) {
c2b394d5 996 if (devc->data_source == DATA_SOURCE_MEMORY) {
babab622
ML
997 /* Apparently for the DS2000 the memory
998 * depth can only be set in Running state -
999 * this matches the behaviour of the UI. */
38354d9d 1000 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
babab622 1001 return SR_ERR;
38354d9d 1002 if (rigol_ds_config_set(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
babab622 1003 return SR_ERR;
38354d9d 1004 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
babab622 1005 return SR_ERR;
0d9f5a12 1006 }
babab622 1007 if (rigol_ds_capture_start(sdi) != SR_OK)
bafd4890
ML
1008 return SR_ERR;
1009 }
6bb192bc 1010 }
f4816ac6 1011
f76c24f6
ML
1012 /* Start of first frame. */
1013 packet.type = SR_DF_FRAME_BEGIN;
1014 sr_session_send(cb_data, &packet);
1015
f4816ac6
ML
1016 return SR_OK;
1017}
1018
254dd102 1019static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1020{
29d957ce 1021 struct dev_context *devc;
ae1bc1cc 1022 struct sr_scpi_dev_inst *scpi;
b751cf7a 1023 struct sr_datafeed_packet packet;
29d957ce 1024
f4816ac6
ML
1025 (void)cb_data;
1026
29d957ce
UH
1027 devc = sdi->priv;
1028
f4816ac6
ML
1029 if (sdi->status != SR_ST_ACTIVE) {
1030 sr_err("Device inactive, can't stop acquisition.");
1031 return SR_ERR;
1032 }
1033
b751cf7a
ML
1034 /* End of last frame. */
1035 packet.type = SR_DF_END;
1036 sr_session_send(sdi, &packet);
1037
6bb192bc
ML
1038 g_slist_free(devc->enabled_analog_probes);
1039 g_slist_free(devc->enabled_digital_probes);
1040 devc->enabled_analog_probes = NULL;
1041 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1042 scpi = sdi->conn;
1043 sr_scpi_source_remove(scpi);
f4816ac6
ML
1044
1045 return SR_OK;
1046}
1047
3086efdd
ML
1048SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1049 .name = "rigol-ds",
1050 .longname = "Rigol DS",
f4816ac6 1051 .api_version = 1,
6078d2c9
UH
1052 .init = init,
1053 .cleanup = cleanup,
1054 .scan = scan,
1055 .dev_list = dev_list,
3b412e3a 1056 .dev_clear = dev_clear,
d62d7ad1 1057 .config_get = config_get,
035a1078 1058 .config_set = config_set,
a1c743fc 1059 .config_list = config_list,
6078d2c9
UH
1060 .dev_open = dev_open,
1061 .dev_close = dev_close,
254dd102
BV
1062 .dev_acquisition_start = dev_acquisition_start,
1063 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1064 .priv = NULL,
1065};