2 * This file is part of the libsigrok project.
4 * Copyright (C) 2020 Timo Kokkonen <tjko@iki.fi>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 static struct sr_dev_driver rigol_dg_driver_info;
27 static const uint32_t scanopts[] = {
31 static const uint32_t drvopts[] = {
32 SR_CONF_SIGNAL_GENERATOR,
35 static const uint32_t dg1000z_devopts[] = {
37 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
38 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
41 static const uint32_t dg1000z_devopts_cg[] = {
42 SR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,
43 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
44 SR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
45 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
46 SR_CONF_OFFSET | SR_CONF_GET | SR_CONF_SET,
47 SR_CONF_PHASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
48 SR_CONF_DUTY_CYCLE | SR_CONF_GET | SR_CONF_SET,
51 static const double phase_min_max_step[] = { 0.0, 360.0, 0.001 };
53 #define WAVEFORM_DEFAULT WFO_FREQUENCY | WFO_AMPLITUDE | WFO_OFFSET | WFO_PHASE
55 static const struct waveform_spec dg810_waveforms[] = {
56 { "SIN", WF_SINE, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
57 { "SQU", WF_SQUARE, 1.0E-6, 5.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
58 { "RAMP", WF_RAMP, 1.0E-6, 0.2E+6, 1.0E-6, WAVEFORM_DEFAULT },
59 { "PULSE", WF_PULSE, 1.0E-6, 5.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
60 { "USER", WF_ARB, 1.0E-6, 5.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
61 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
62 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
65 static const struct channel_spec dg811_channels[] = {
66 { "CH1", ARRAY_AND_SIZE(dg810_waveforms) },
69 static const struct channel_spec dg812_channels[] = {
70 { "CH1", ARRAY_AND_SIZE(dg810_waveforms) },
71 { "CH2", ARRAY_AND_SIZE(dg810_waveforms) },
74 static const struct waveform_spec dg820_waveforms[] = {
75 { "SIN", WF_SINE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
76 { "SQU", WF_SQUARE, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
77 { "RAMP", WF_RAMP, 1.0E-6, 0.5E+6, 1.0E-6, WAVEFORM_DEFAULT },
78 { "PULSE", WF_PULSE, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
79 { "USER", WF_ARB, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
80 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
81 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
84 static const struct channel_spec dg821_channels[] = {
85 { "CH1", ARRAY_AND_SIZE(dg820_waveforms) },
88 static const struct channel_spec dg822_channels[] = {
89 { "CH1", ARRAY_AND_SIZE(dg820_waveforms) },
90 { "CH2", ARRAY_AND_SIZE(dg820_waveforms) },
93 static const struct waveform_spec dg830_waveforms[] = {
94 { "SIN", WF_SINE, 1.0E-6, 35.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
95 { "SQU", WF_SQUARE, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
96 { "RAMP", WF_RAMP, 1.0E-6, 1.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
97 { "PULSE", WF_PULSE, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
98 { "USER", WF_ARB, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
99 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
100 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
103 static const struct channel_spec dg831_channels[] = {
104 { "CH1", ARRAY_AND_SIZE(dg830_waveforms) },
107 static const struct channel_spec dg832_channels[] = {
108 { "CH1", ARRAY_AND_SIZE(dg830_waveforms) },
109 { "CH2", ARRAY_AND_SIZE(dg830_waveforms) },
112 static const struct waveform_spec dg952_waveforms[] = {
113 { "SIN", WF_SINE, 1.0E-6, 50.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
114 { "SQU", WF_SQUARE, 1.0E-6, 15.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
115 { "RAMP", WF_RAMP, 1.0E-6, 1.5E+6, 1.0E-6, WAVEFORM_DEFAULT },
116 { "PULSE", WF_PULSE, 1.0E-6, 15.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
117 { "USER", WF_ARB, 1.0E-6, 15.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
118 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
119 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
122 static const struct channel_spec dg952_channels[] = {
123 { "CH1", ARRAY_AND_SIZE(dg952_waveforms) },
124 { "CH2", ARRAY_AND_SIZE(dg952_waveforms) },
127 static const struct waveform_spec dg972_waveforms[] = {
128 { "SIN", WF_SINE, 1.0E-6, 70.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
129 { "SQU", WF_SQUARE, 1.0E-6, 20.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
130 { "RAMP", WF_RAMP, 1.0E-6, 1.5E+6, 1.0E-6, WAVEFORM_DEFAULT },
131 { "PULSE", WF_PULSE, 1.0E-6, 20.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
132 { "USER", WF_ARB, 1.0E-6, 20.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
133 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
134 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
137 static const struct channel_spec dg972_channels[] = {
138 { "CH1", ARRAY_AND_SIZE(dg972_waveforms) },
139 { "CH2", ARRAY_AND_SIZE(dg972_waveforms) },
142 static const struct waveform_spec dg992_waveforms[] = {
143 { "SIN", WF_SINE, 1.0E-6, 100.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
144 { "SQU", WF_SQUARE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
145 { "RAMP", WF_RAMP, 1.0E-6, 2.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
146 { "PULSE", WF_PULSE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
147 { "USER", WF_ARB, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
148 { "NOISE", WF_NOISE, 100.0E+6, 100.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
149 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
152 static const struct channel_spec dg992_channels[] = {
153 { "CH1", ARRAY_AND_SIZE(dg992_waveforms) },
154 { "CH2", ARRAY_AND_SIZE(dg992_waveforms) },
157 static const struct waveform_spec dg1022z_waveforms[] = {
158 { "SIN", WF_SINE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
159 { "SQU", WF_SQUARE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
160 { "RAMP", WF_RAMP, 1.0E-6, 0.5E+6, 1.0E-6, WAVEFORM_DEFAULT },
161 { "PULSE", WF_PULSE, 1.0E-6, 15.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
162 { "USER", WF_ARB, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
163 { "NOISE", WF_NOISE, 25.0E+6, 25.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
164 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
167 static const struct channel_spec dg1022z_channels[] = {
168 { "CH1", ARRAY_AND_SIZE(dg1022z_waveforms) },
169 { "CH2", ARRAY_AND_SIZE(dg1022z_waveforms) },
172 static const struct waveform_spec dg1032z_waveforms[] = {
173 { "SIN", WF_SINE, 1.0E-6, 30.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
174 { "SQU", WF_SQUARE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
175 { "RAMP", WF_RAMP, 1.0E-6, 0.5E+6, 1.0E-6, WAVEFORM_DEFAULT },
176 { "PULSE", WF_PULSE, 1.0E-6, 15.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
177 { "USER", WF_ARB, 1.0E-6, 10.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
178 { "NOISE", WF_NOISE, 30.0E+6, 30.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
179 { "DC", WF_DC, 0.0E-0 , 0.0E+0, 0.0E-0, WFO_OFFSET },
182 static const struct channel_spec dg1032z_channels[] = {
183 { "CH1", ARRAY_AND_SIZE(dg1032z_waveforms) },
184 { "CH2", ARRAY_AND_SIZE(dg1032z_waveforms) },
187 static const struct waveform_spec dg1062z_waveforms[] = {
188 { "SIN", WF_SINE, 1.0E-6, 60.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
189 { "SQU", WF_SQUARE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
190 { "RAMP", WF_RAMP, 1.0E-6, 1.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
191 { "PULSE", WF_PULSE, 1.0E-6, 25.0E+6, 1.0E-6, WAVEFORM_DEFAULT | WFO_DUTY_CYCLE },
192 { "USER", WF_ARB, 1.0E-6, 20.0E+6, 1.0E-6, WAVEFORM_DEFAULT },
193 { "NOISE", WF_NOISE, 60.0E+6, 60.0E+6, 0.0E-0, WFO_AMPLITUDE | WFO_OFFSET },
194 { "DC", WF_DC, 0.0E-0, 0.0E+0, 0.0E-0, WFO_OFFSET },
197 static const struct channel_spec dg1062z_channels[] = {
198 { "CH1", ARRAY_AND_SIZE(dg1062z_waveforms) },
199 { "CH2", ARRAY_AND_SIZE(dg1062z_waveforms) },
202 static const struct scpi_command cmdset_dg1000z[] = {
203 { PSG_CMD_SETUP_LOCAL, "SYST:KLOC:STATE OFF", },
204 /* { PSG_CMD_SELECT_CHANNEL, "SYST:CHAN:CUR CH%s", }, */
205 { PSG_CMD_GET_CHANNEL, "SYST:CHAN:CUR?", },
206 { PSG_CMD_GET_ENABLED, "OUTP%s:STATE?", },
207 { PSG_CMD_SET_ENABLE, "OUTP%s:STATE ON", },
208 { PSG_CMD_SET_DISABLE, "OUTP%s:STATE OFF", },
209 { PSG_CMD_GET_SOURCE, "SOUR%s:APPL?", },
210 { PSG_CMD_SET_SOURCE, "SOUR%s:APPL:%s", },
211 { PSG_CMD_GET_FREQUENCY, "SOUR%s:FREQ?", },
212 { PSG_CMD_SET_FREQUENCY, "SOUR%s:FREQ %f", },
213 { PSG_CMD_GET_AMPLITUDE, "SOUR%s:VOLT?", },
214 { PSG_CMD_SET_AMPLITUDE, "SOUR%s:VOLT %f", },
215 { PSG_CMD_GET_OFFSET, "SOUR%s:VOLT:OFFS?", },
216 { PSG_CMD_SET_OFFSET, "SOUR%s:VOLT:OFFS %f", },
217 { PSG_CMD_GET_PHASE, "SOUR%s:PHAS?", },
218 { PSG_CMD_SET_PHASE, "SOUR%s:PHAS %f", },
219 { PSG_CMD_GET_DCYCL_PULSE, "SOUR%s:FUNC:PULS:DCYC?", },
220 { PSG_CMD_SET_DCYCL_PULSE, "SOUR%s:FUNC:PULS:DCYC %f", },
221 { PSG_CMD_GET_DCYCL_SQUARE, "SOUR%s:FUNC:SQU:DCYC?", },
222 { PSG_CMD_SET_DCYCL_SQUARE, "SOUR%s:FUNC:SQU:DCYC %f", },
223 { PSG_CMD_COUNTER_GET_ENABLED, "COUN:STAT?", },
224 { PSG_CMD_COUNTER_SET_ENABLE, "COUN:STAT ON", },
225 { PSG_CMD_COUNTER_SET_DISABLE, "COUN:STAT OFF", },
226 { PSG_CMD_COUNTER_MEASURE, "COUN:MEAS?", },
230 static const struct device_spec device_models[] = {
231 { "Rigol Technologies", "DG811",
232 ARRAY_AND_SIZE(dg1000z_devopts),
233 ARRAY_AND_SIZE(dg1000z_devopts_cg),
234 ARRAY_AND_SIZE(dg811_channels),
237 { "Rigol Technologies", "DG812",
238 ARRAY_AND_SIZE(dg1000z_devopts),
239 ARRAY_AND_SIZE(dg1000z_devopts_cg),
240 ARRAY_AND_SIZE(dg812_channels),
243 { "Rigol Technologies", "DG821",
244 ARRAY_AND_SIZE(dg1000z_devopts),
245 ARRAY_AND_SIZE(dg1000z_devopts_cg),
246 ARRAY_AND_SIZE(dg821_channels),
249 { "Rigol Technologies", "DG822",
250 ARRAY_AND_SIZE(dg1000z_devopts),
251 ARRAY_AND_SIZE(dg1000z_devopts_cg),
252 ARRAY_AND_SIZE(dg822_channels),
255 { "Rigol Technologies", "DG831",
256 ARRAY_AND_SIZE(dg1000z_devopts),
257 ARRAY_AND_SIZE(dg1000z_devopts_cg),
258 ARRAY_AND_SIZE(dg831_channels),
261 { "Rigol Technologies", "DG832",
262 ARRAY_AND_SIZE(dg1000z_devopts),
263 ARRAY_AND_SIZE(dg1000z_devopts_cg),
264 ARRAY_AND_SIZE(dg832_channels),
267 { "Rigol Technologies", "DG952",
268 ARRAY_AND_SIZE(dg1000z_devopts),
269 ARRAY_AND_SIZE(dg1000z_devopts_cg),
270 ARRAY_AND_SIZE(dg952_channels),
273 { "Rigol Technologies", "DG972",
274 ARRAY_AND_SIZE(dg1000z_devopts),
275 ARRAY_AND_SIZE(dg1000z_devopts_cg),
276 ARRAY_AND_SIZE(dg972_channels),
279 { "Rigol Technologies", "DG992",
280 ARRAY_AND_SIZE(dg1000z_devopts),
281 ARRAY_AND_SIZE(dg1000z_devopts_cg),
282 ARRAY_AND_SIZE(dg992_channels),
285 { "Rigol Technologies", "DG1022Z",
286 ARRAY_AND_SIZE(dg1000z_devopts),
287 ARRAY_AND_SIZE(dg1000z_devopts_cg),
288 ARRAY_AND_SIZE(dg1022z_channels),
291 { "Rigol Technologies", "DG1032Z",
292 ARRAY_AND_SIZE(dg1000z_devopts),
293 ARRAY_AND_SIZE(dg1000z_devopts_cg),
294 ARRAY_AND_SIZE(dg1032z_channels),
297 { "Rigol Technologies", "DG1062Z",
298 ARRAY_AND_SIZE(dg1000z_devopts),
299 ARRAY_AND_SIZE(dg1000z_devopts_cg),
300 ARRAY_AND_SIZE(dg1062z_channels),
305 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
307 struct sr_dev_inst *sdi;
308 struct dev_context *devc;
309 struct sr_scpi_hw_info *hw_info;
310 const struct device_spec *device;
311 const struct scpi_command *cmdset;
312 struct sr_channel *ch;
313 struct sr_channel_group *cg;
315 unsigned int i, ch_idx;
322 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK)
326 for (i = 0; i < ARRAY_SIZE(device_models); i++) {
327 if (g_ascii_strcasecmp(hw_info->manufacturer,
328 device_models[i].vendor) != 0)
330 if (g_ascii_strcasecmp(hw_info->model,
331 device_models[i].model) != 0)
333 device = &device_models[i];
334 cmdset = device_models[i].cmdset;
340 sdi = g_malloc0(sizeof(*sdi));
341 sdi->vendor = g_strdup(hw_info->manufacturer);
342 sdi->model = g_strdup(hw_info->model);
343 sdi->version = g_strdup(hw_info->firmware_version);
344 sdi->serial_num = g_strdup(hw_info->serial_number);
346 sdi->driver = &rigol_dg_driver_info;
347 sdi->inst_type = SR_INST_SCPI;
349 devc = g_malloc0(sizeof(*devc));
350 devc->cmdset = cmdset;
351 devc->device = device;
352 devc->ch_status = g_malloc0((device->num_channels + 1) *
353 sizeof(devc->ch_status[0]));
354 sr_sw_limits_init(&devc->limits);
357 /* Create channel group and channel for each device channel. */
359 for (i = 0; i < device->num_channels; i++) {
360 ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE,
361 device->channels[i].name);
362 cg = g_malloc0(sizeof(*cg));
363 snprintf(tmp, sizeof(tmp), "%u", i + 1);
364 cg->name = g_strdup(tmp);
365 cg->channels = g_slist_append(cg->channels, ch);
367 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
370 /* Create channels for the frequency counter output. */
371 ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, "FREQ1");
372 ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, "PERIOD1");
373 ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, "DUTY1");
374 ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, "WIDTH1");
376 /* Put device back to "local" mode, in case only a scan was done... */
377 command = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_SETUP_LOCAL);
378 if (command && *command) {
379 sr_scpi_get_opc(scpi);
380 sr_scpi_send(scpi, command);
383 sr_scpi_hw_info_free(hw_info);
388 sr_scpi_hw_info_free(hw_info);
390 sr_dev_inst_free(sdi);
395 static GSList *scan(struct sr_dev_driver *di, GSList *options)
397 return sr_scpi_scan(di->context, options, probe_device);
400 static int dev_open(struct sr_dev_inst *sdi)
402 return sr_scpi_open(sdi->conn);
405 static int dev_close(struct sr_dev_inst *sdi)
407 struct dev_context *devc;
408 struct sr_scpi_dev_inst *scpi;
416 /* Put unit back to "local" mode. */
417 command = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_SETUP_LOCAL);
418 if (command && *command) {
419 sr_scpi_get_opc(scpi);
420 sr_scpi_send(scpi, command);
423 return sr_scpi_close(sdi->conn);
426 static int config_get(uint32_t key, GVariant **data,
427 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
429 struct dev_context *devc;
430 struct sr_scpi_dev_inst *scpi;
431 struct sr_channel *ch;
432 struct channel_status *ch_status;
433 const struct sr_key_info *kinfo;
443 kinfo = sr_key_info_get(SR_KEY_CONFIG, key);
447 case SR_CONF_LIMIT_SAMPLES:
448 case SR_CONF_LIMIT_MSEC:
449 ret = sr_sw_limits_config_get(&devc->limits, key, data);
452 sr_dbg("%s: Unsupported key: %d (%s)", __func__,
453 (int)key, (kinfo ? kinfo->name : "unknown"));
458 ch = cg->channels->data;
459 ch_status = &devc->ch_status[ch->index];
462 case SR_CONF_ENABLED:
463 sr_scpi_get_opc(scpi);
464 ret = sr_scpi_cmd_resp(sdi, devc->cmdset,
465 PSG_CMD_SELECT_CHANNEL, cg->name, data,
466 G_VARIANT_TYPE_BOOLEAN, PSG_CMD_GET_ENABLED,
469 case SR_CONF_PATTERN_MODE:
470 if ((ret = rigol_dg_get_channel_state(sdi, cg)) == SR_OK) {
471 *data = g_variant_new_string(
472 rigol_dg_waveform_to_string(
476 case SR_CONF_OUTPUT_FREQUENCY:
477 if ((ret = rigol_dg_get_channel_state(sdi, cg)) == SR_OK)
478 *data = g_variant_new_double(ch_status->freq);
480 case SR_CONF_AMPLITUDE:
481 if ((ret = rigol_dg_get_channel_state(sdi, cg)) == SR_OK)
482 *data = g_variant_new_double(ch_status->ampl);
485 if ((ret = rigol_dg_get_channel_state(sdi, cg)) == SR_OK)
486 *data = g_variant_new_double(ch_status->offset);
489 if ((ret = rigol_dg_get_channel_state(sdi, cg)) == SR_OK)
490 *data = g_variant_new_double(ch_status->phase);
492 case SR_CONF_DUTY_CYCLE:
493 if ((ret = rigol_dg_get_channel_state(sdi, cg)) != SR_OK)
495 if (ch_status->wf == WF_SQUARE) {
496 cmd = PSG_CMD_GET_DCYCL_SQUARE;
497 } else if (ch_status->wf == WF_PULSE) {
498 cmd = PSG_CMD_GET_DCYCL_PULSE;
503 sr_scpi_get_opc(scpi);
504 ret = sr_scpi_cmd_resp(sdi, devc->cmdset,
505 PSG_CMD_SELECT_CHANNEL, cg->name, data,
506 G_VARIANT_TYPE_DOUBLE, cmd, cg->name);
509 sr_dbg("%s: Unsupported (cg) key: %d (%s)", __func__,
510 (int)key, (kinfo ? kinfo->name : "unknown"));
519 static int config_set(uint32_t key, GVariant *data,
520 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
522 struct dev_context *devc;
523 struct sr_scpi_dev_inst *scpi;
524 struct sr_channel *ch;
525 const struct channel_spec *ch_spec;
526 struct channel_status *ch_status;
527 const struct sr_key_info *kinfo;
530 const char *mode, *mode_name, *new_mode;
538 kinfo = sr_key_info_get(SR_KEY_CONFIG, key);
544 case SR_CONF_LIMIT_MSEC:
545 case SR_CONF_LIMIT_SAMPLES:
546 ret = sr_sw_limits_config_set(&devc->limits, key, data);
549 sr_dbg("%s: Unsupported key: %d (%s)", __func__,
550 (int)key, (kinfo ? kinfo->name : "unknown"));
555 ch = cg->channels->data;
556 ch_spec = &devc->device->channels[ch->index];
557 ch_status = &devc->ch_status[ch->index];
559 if ((ret = rigol_dg_get_channel_state(sdi, cg)) != SR_OK)
561 sr_scpi_get_opc(scpi);
564 case SR_CONF_ENABLED:
565 if (g_variant_get_boolean(data))
566 cmd = PSG_CMD_SET_ENABLE;
568 cmd = PSG_CMD_SET_DISABLE;
569 ret = sr_scpi_cmd(sdi, devc->cmdset,
570 PSG_CMD_SELECT_CHANNEL, cg->name, cmd, cg->name);
572 case SR_CONF_PATTERN_MODE:
575 mode = g_variant_get_string(data, NULL);
576 for (i = 0; i < ch_spec->num_waveforms; i++) {
577 mode_name = rigol_dg_waveform_to_string(
578 ch_spec->waveforms[i].waveform);
579 if (g_ascii_strncasecmp(mode, mode_name,
580 strlen(mode_name)) == 0)
581 new_mode = ch_spec->waveforms[i].name;
584 ret = sr_scpi_cmd(sdi, devc->cmdset,
585 PSG_CMD_SELECT_CHANNEL, cg->name,
586 PSG_CMD_SET_SOURCE, cg->name, new_mode);
588 case SR_CONF_OUTPUT_FREQUENCY:
590 if (!(ch_status->wf_spec->opts & WFO_FREQUENCY))
592 ret = sr_scpi_cmd(sdi, devc->cmdset,
593 PSG_CMD_SELECT_CHANNEL, cg->name,
594 PSG_CMD_SET_FREQUENCY, cg->name,
595 g_variant_get_double(data));
597 case SR_CONF_AMPLITUDE:
599 if (!(ch_status->wf_spec->opts & WFO_AMPLITUDE))
601 ret = sr_scpi_cmd(sdi, devc->cmdset,
602 PSG_CMD_SELECT_CHANNEL, cg->name,
603 PSG_CMD_SET_AMPLITUDE, cg->name,
604 g_variant_get_double(data));
608 if (!(ch_status->wf_spec->opts & WFO_OFFSET))
610 ret = sr_scpi_cmd(sdi, devc->cmdset,
611 PSG_CMD_SELECT_CHANNEL, cg->name,
612 PSG_CMD_SET_OFFSET, cg->name,
613 g_variant_get_double(data));
617 if (!(ch_status->wf_spec->opts & WFO_PHASE))
619 ret = sr_scpi_cmd(sdi, devc->cmdset,
620 PSG_CMD_SELECT_CHANNEL, cg->name,
621 PSG_CMD_SET_PHASE, cg->name,
622 g_variant_get_double(data));
624 case SR_CONF_DUTY_CYCLE:
626 if (!(ch_status->wf_spec->opts & WFO_DUTY_CYCLE))
628 if (ch_status->wf == WF_SQUARE)
629 cmd = PSG_CMD_SET_DCYCL_SQUARE;
630 else if (ch_status->wf == WF_PULSE)
631 cmd = PSG_CMD_SET_DCYCL_PULSE;
634 ret = sr_scpi_cmd(sdi, devc->cmdset,
635 PSG_CMD_SELECT_CHANNEL, cg->name,
636 cmd, cg->name, g_variant_get_double(data));
639 sr_dbg("%s: Unsupported key: %d (%s)", __func__,
640 (int)key, (kinfo ? kinfo->name : "unknown"));
649 static int config_list(uint32_t key, GVariant **data,
650 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
652 struct dev_context *devc;
653 struct sr_channel *ch;
654 const struct channel_spec *ch_spec;
655 const struct waveform_spec *wf_spec;
656 struct channel_status *ch_status;
667 case SR_CONF_SCAN_OPTIONS:
668 case SR_CONF_DEVICE_OPTIONS:
669 return std_opts_config_list(key, data, sdi, cg,
670 ARRAY_AND_SIZE(scanopts),
671 ARRAY_AND_SIZE(drvopts),
672 (devc && devc->device) ? devc->device->devopts : NULL,
673 (devc && devc->device) ? devc->device->num_devopts : 0);
678 if (!devc || !devc->device)
680 ch = cg->channels->data;
681 ch_spec = &devc->device->channels[ch->index];
682 ch_status = &devc->ch_status[ch->index];
685 case SR_CONF_DEVICE_OPTIONS:
686 *data = std_gvar_array_u32(devc->device->devopts_cg,
687 devc->device->num_devopts_cg);
689 case SR_CONF_PATTERN_MODE:
690 b = g_variant_builder_new(G_VARIANT_TYPE("as"));
691 for (i = 0; i < ch_spec->num_waveforms; i++) {
692 g_variant_builder_add(b, "s",
693 rigol_dg_waveform_to_string(
694 ch_spec->waveforms[i].waveform));
696 *data = g_variant_new("as", b);
697 g_variant_builder_unref(b);
699 case SR_CONF_OUTPUT_FREQUENCY:
701 * Frequency range depends on the currently active
704 if (rigol_dg_get_channel_state(sdi, cg) != SR_OK)
706 wf_spec = rigol_dg_get_waveform_spec(ch_spec,
710 fspec[0] = wf_spec->freq_min;
711 fspec[1] = wf_spec->freq_max;
712 fspec[2] = wf_spec->freq_step;
713 *data = std_gvar_min_max_step_array(fspec);
716 *data = std_gvar_min_max_step_array(phase_min_max_step);
726 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
728 struct dev_context *devc;
729 struct sr_scpi_dev_inst *scpi;
745 cmd = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_COUNTER_GET_ENABLED);
747 /* Check if counter is currently enabled. */
748 ret = sr_scpi_get_string(scpi, cmd, &response);
751 if (g_ascii_strncasecmp(response, "RUN", strlen("RUN")) == 0)
752 devc->counter_enabled = TRUE;
754 devc->counter_enabled = FALSE;
756 if (!devc->counter_enabled) {
757 /* Enable counter if it was not already running. */
758 cmd = sr_scpi_cmd_get(devc->cmdset,
759 PSG_CMD_COUNTER_SET_ENABLE);
762 sr_scpi_get_opc(scpi);
763 ret = sr_scpi_send(scpi, cmd);
768 sr_sw_limits_acquisition_start(&devc->limits);
769 ret = std_session_send_df_header(sdi);
771 ret = sr_scpi_source_add(sdi->session, scpi,
772 G_IO_IN, 100, rigol_dg_receive_data,
782 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
784 struct dev_context *devc;
785 struct sr_scpi_dev_inst *scpi;
796 cmd = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_COUNTER_SET_DISABLE);
797 if (cmd && *cmd && !devc->counter_enabled) {
799 * If counter was not running when acquisiton started,
802 sr_scpi_get_opc(scpi);
803 ret = sr_scpi_send(scpi, cmd);
806 sr_scpi_source_remove(sdi->session, scpi);
807 std_session_send_df_end(sdi);
812 static struct sr_dev_driver rigol_dg_driver_info = {
814 .longname = "Rigol DG Series",
817 .cleanup = std_cleanup,
819 .dev_list = std_dev_list,
820 .dev_clear = std_dev_clear,
821 .config_get = config_get,
822 .config_set = config_set,
823 .config_list = config_list,
824 .dev_open = dev_open,
825 .dev_close = dev_close,
826 .dev_acquisition_start = dev_acquisition_start,
827 .dev_acquisition_stop = dev_acquisition_stop,
830 SR_REGISTER_DEV_DRIVER(rigol_dg_driver_info);