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