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