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