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