]> sigrok.org Git - libsigrok.git/blob - hardware/rigol-ds1xx2/api.c
06b69db7c4ce1c75d5c9bc0762e3b86c8f126de2
[libsigrok.git] / hardware / rigol-ds1xx2 / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib.h>
26 #include "libsigrok.h"
27 #include "libsigrok-internal.h"
28 #include "protocol.h"
29
30 #define NUM_TIMEBASE  12
31 #define NUM_VDIV      8
32
33 static const int32_t hwopts[] = {
34         SR_CONF_CONN,
35 };
36
37 static const int32_t hwcaps[] = {
38         SR_CONF_OSCILLOSCOPE,
39         SR_CONF_TIMEBASE,
40         SR_CONF_TRIGGER_SOURCE,
41         SR_CONF_TRIGGER_SLOPE,
42         SR_CONF_HORIZ_TRIGGERPOS,
43         SR_CONF_NUM_TIMEBASE,
44 };
45
46 static const int32_t analog_hwcaps[] = {
47         SR_CONF_NUM_VDIV,
48         SR_CONF_VDIV,
49         SR_CONF_COUPLING
50 };
51
52 static const uint64_t timebases[][2] = {
53         /* nanoseconds */
54         { 2, 1000000000 },
55         { 5, 1000000000 },
56         { 10, 1000000000 },
57         { 20, 1000000000 },
58         { 50, 1000000000 },
59         { 100, 1000000000 },
60         { 500, 1000000000 },
61         /* microseconds */
62         { 1, 1000000 },
63         { 2, 1000000 },
64         { 5, 1000000 },
65         { 10, 1000000 },
66         { 20, 1000000 },
67         { 50, 1000000 },
68         { 100, 1000000 },
69         { 200, 1000000 },
70         { 500, 1000000 },
71         /* milliseconds */
72         { 1, 1000 },
73         { 2, 1000 },
74         { 5, 1000 },
75         { 10, 1000 },
76         { 20, 1000 },
77         { 50, 1000 },
78         { 100, 1000 },
79         { 200, 1000 },
80         { 500, 1000 },
81         /* seconds */
82         { 1, 1 },
83         { 2, 1 },
84         { 5, 1 },
85         { 10, 1 },
86         { 20, 1 },
87         { 50, 1 },
88 };
89
90 static const uint64_t vdivs[][2] = {
91         /* millivolts */
92         { 2, 1000 },
93         { 5, 1000 },
94         { 10, 1000 },
95         { 20, 1000 },
96         { 50, 1000 },
97         { 100, 1000 },
98         { 200, 1000 },
99         { 500, 1000 },
100         /* volts */
101         { 1, 1 },
102         { 2, 1 },
103         { 5, 1 },
104         { 10, 1 },
105 };
106
107 static const char *trigger_sources[] = {
108         "CH1",
109         "CH2",
110         "EXT",
111         "AC Line",
112         "D0",
113         "D1",
114         "D2",
115         "D3",
116         "D4",
117         "D5",
118         "D6",
119         "D7",
120         "D8",
121         "D9",
122         "D10",
123         "D11",
124         "D12",
125         "D13",
126         "D14",
127         "D15",
128 };
129
130 static const char *coupling[] = {
131         "AC",
132         "DC",
133         "GND",
134 };
135
136 static const char *supported_models[] = {
137         "DS1052E",
138         "DS1102E",
139         "DS1152E",
140         "DS1052D",
141         "DS1102D",
142         "DS1152D",
143 };
144
145 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
146 static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
147
148 static void clear_helper(void *priv)
149 {
150         struct dev_context *devc;
151
152         for (l = drvc->instances; l; l = l->next) {
153                 if (!(sdi = l->data))
154                         continue;
155
156                 if (sdi->conn)
157                         sr_serial_dev_inst_free(sdi->conn);
158
159                 g_slist_free(sdi->probe_groups);
160
161                 if (!(devc = sdi->priv))
162                         continue;
163
164                 g_free(devc->device);
165                 g_free(devc->coupling[0]);
166                 g_free(devc->coupling[1]);
167                 g_free(devc->trigger_source);
168                 g_free(devc->trigger_slope);
169                 g_slist_free(devc->analog_groups[0].probes);
170                 g_slist_free(devc->analog_groups[1].probes);
171                 g_slist_free(devc->digital_group.probes);
172                 close(devc->fd);
173
174                 sr_dev_inst_free(sdi);
175         }
176
177         g_free(devc->coupling[0]);
178         g_free(devc->coupling[1]);
179         g_free(devc->trigger_source);
180         g_free(devc->trigger_slope);
181 }
182
183 static int dev_clear(void)
184 {
185         return std_dev_clear(di, clear_helper);
186 }
187
188 static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
189 {
190         va_list args;
191         char buf[256];
192
193         va_start(args, format);
194         vsnprintf(buf, 255, format, args);
195         va_end(args);
196         if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
197                 return SR_ERR;
198
199         /* When setting a bunch of parameters in a row, the DS1052E scrambles
200          * some of them unless there is at least 100ms delay in between. */
201         sr_spew("delay %dms", 100);
202         g_usleep(100000);
203
204         return SR_OK;
205 }
206
207 static int init(struct sr_context *sr_ctx)
208 {
209         return std_init(sr_ctx, di, LOG_PREFIX);
210 }
211
212 static int probe_port(const char *port, GSList **devices)
213 {
214         struct dev_context *devc;
215         struct sr_dev_inst *sdi;
216         struct sr_serial_dev_inst *serial;
217         struct sr_probe *probe;
218         unsigned int i;
219         int len, num_tokens;
220         gboolean matched, has_digital;
221         const char *manufacturer, *model, *version;
222         char buf[256];
223         gchar **tokens, *channel_name;
224
225         *devices = NULL;
226         if (!(serial = sr_serial_dev_inst_new(port, NULL)))
227                 return SR_ERR_MALLOC;
228
229         if (serial_open(serial, SERIAL_RDWR) != SR_OK)
230                 return SR_ERR;
231         len = serial_write(serial, "*IDN?", 5);
232         len = serial_read(serial, buf, sizeof(buf));
233         if (serial_close(serial) != SR_OK)
234                 return SR_ERR;
235
236         sr_serial_dev_inst_free(serial);
237
238         if (len == 0)
239                 return SR_ERR_NA;
240
241         buf[len] = 0;
242         tokens = g_strsplit(buf, ",", 0);
243         sr_dbg("response: %s [%s]", port, buf);
244
245         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
246
247         if (num_tokens < 4) {
248                 g_strfreev(tokens);
249                 return SR_ERR_NA;
250         }
251
252         manufacturer = tokens[0];
253         model = tokens[1];
254         version = tokens[3];
255
256         if (strcmp(manufacturer, "Rigol Technologies")) {
257                 g_strfreev(tokens);
258                 return SR_ERR_NA;
259         }
260
261         matched = has_digital = FALSE;
262         for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
263                 if (!strcmp(model, supported_models[i])) {
264                         matched = TRUE;
265                         has_digital = g_str_has_suffix(model, "D");
266                         break;
267                 }
268         }
269
270         if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
271                 manufacturer, model, version))) {
272                 g_strfreev(tokens);
273                 return SR_ERR_NA;
274         }
275
276         g_strfreev(tokens);
277
278         if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
279                 return SR_ERR_MALLOC;
280         sdi->driver = di;
281         sdi->inst_type = SR_INST_SERIAL;
282
283         if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
284                 return SR_ERR_MALLOC;
285         devc->limit_frames = 0;
286         devc->has_digital = has_digital;
287
288         for (i = 0; i < 2; i++) {
289                 channel_name = (i == 0 ? "CH1" : "CH2");
290                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name)))
291                         return SR_ERR_MALLOC;
292                 sdi->probes = g_slist_append(sdi->probes, probe);
293                 devc->analog_groups[i].name = channel_name;
294                 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
295                 sdi->probe_groups = g_slist_append(sdi->probe_groups,
296                                 &devc->analog_groups[i]);
297         }
298
299         if (devc->has_digital) {
300                 for (i = 0; i < 16; i++) {
301                         if (!(channel_name = g_strdup_printf("D%d", i)))
302                                 return SR_ERR_MALLOC;
303                         probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
304                         g_free(channel_name);
305                         if (!probe)
306                                 return SR_ERR_MALLOC;
307                         sdi->probes = g_slist_append(sdi->probes, probe);
308                         devc->digital_group.probes = g_slist_append(
309                                         devc->digital_group.probes, probe);
310                         devc->digital_group.name = "LA";
311                         sdi->probe_groups = g_slist_append(sdi->probe_groups,
312                                         &devc->digital_group);
313                 }
314         }
315         sdi->priv = devc;
316
317         *devices = g_slist_append(NULL, sdi);
318
319         return SR_OK;
320 }
321
322 static GSList *scan(GSList *options)
323 {
324         struct drv_context *drvc;
325         struct sr_config *src;
326         GSList *l, *devices;
327         GDir *dir;
328         int ret;
329         const gchar *dev_name;
330         gchar *port = NULL;
331
332         drvc = di->priv;
333
334         for (l = options; l; l = l->next) {
335                 src = l->data;
336                 if (src->key == SR_CONF_CONN) {
337                         port = (char *)g_variant_get_string(src->data, NULL);
338                         break;
339                 }
340         }
341
342         devices = NULL;
343         if (port) {
344                 if (probe_port(port, &devices) == SR_ERR_MALLOC)
345                         return NULL;
346         } else {
347                 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
348                         if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
349                                 return NULL;
350                 while ((dev_name = g_dir_read_name(dir))) {
351                         if (strncmp(dev_name, "usbtmc", 6))
352                                 continue;
353                         port = g_strconcat("/dev/", dev_name, NULL);
354                         ret = probe_port(port, &devices);
355                         g_free(port);
356                         if (ret == SR_ERR_MALLOC) {
357                                 g_dir_close(dir);
358                                 return NULL;
359                         }
360                 }
361                 g_dir_close(dir);
362         }
363
364         /* Tack a copy of the newly found devices onto the driver list. */
365         l = g_slist_copy(devices);
366         drvc->instances = g_slist_concat(drvc->instances, l);
367
368         return devices;
369 }
370
371 static GSList *dev_list(void)
372 {
373         return ((struct drv_context *)(di->priv))->instances;
374 }
375
376 static int dev_open(struct sr_dev_inst *sdi)
377 {
378
379         if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
380                 return SR_ERR;
381
382         if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
383                 return SR_ERR;
384
385         sdi->status = SR_ST_ACTIVE;
386
387         return SR_OK;
388 }
389
390 static int dev_close(struct sr_dev_inst *sdi)
391 {
392         struct sr_serial_dev_inst *serial;
393
394         serial = sdi->conn;
395         if (serial && serial->fd != -1) {
396                 serial_close(serial);
397                 sdi->status = SR_ST_INACTIVE;
398         }
399
400         return SR_OK;
401 }
402
403 static int cleanup(void)
404 {
405         return dev_clear();
406 }
407
408 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
409                 const struct sr_probe_group *probe_group)
410 {
411         struct dev_context *devc = sdi->priv;
412         unsigned int i;
413
414         switch (id) {
415         case SR_CONF_NUM_TIMEBASE:
416                 *data = g_variant_new_int32(NUM_TIMEBASE);
417                 break;
418         case SR_CONF_NUM_VDIV:
419                 for (i = 0; i < 2; i++) {
420                         if (probe_group == &devc->analog_groups[i])
421                         {
422                                 *data = g_variant_new_int32(NUM_VDIV);
423                                 return SR_OK;
424                         }
425                 }
426                 return SR_ERR_NA;
427         default:
428                 return SR_ERR_NA;
429         }
430
431         return SR_OK;
432 }
433
434 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
435                 const struct sr_probe_group *probe_group)
436 {
437         struct dev_context *devc;
438         uint64_t tmp_u64, p, q;
439         double t_dbl;
440         unsigned int i, j;
441         int ret;
442         const char *tmp_str;
443
444         devc = sdi->priv;
445
446         if (sdi->status != SR_ST_ACTIVE)
447                 return SR_ERR_DEV_CLOSED;
448
449         ret = SR_OK;
450         switch (id) {
451         case SR_CONF_LIMIT_FRAMES:
452                 devc->limit_frames = g_variant_get_uint64(data);
453                 break;
454         case SR_CONF_TRIGGER_SLOPE:
455                 tmp_u64 = g_variant_get_uint64(data);
456                 if (tmp_u64 != 0 && tmp_u64 != 1)
457                         return SR_ERR;
458                 g_free(devc->trigger_slope);
459                 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
460                 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
461                 break;
462         case SR_CONF_HORIZ_TRIGGERPOS:
463                 t_dbl = g_variant_get_double(data);
464                 if (t_dbl < 0.0 || t_dbl > 1.0)
465                         return SR_ERR;
466                 devc->horiz_triggerpos = t_dbl;
467                 /* We have the trigger offset as a percentage of the frame, but
468                  * need to express this in seconds. */
469                 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
470                 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
471                 break;
472         case SR_CONF_TIMEBASE:
473                 g_variant_get(data, "(tt)", &p, &q);
474                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
475                         if (timebases[i][0] == p && timebases[i][1] == q) {
476                                 devc->timebase = (float)p / q;
477                                 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
478                                 break;
479                         }
480                 }
481                 if (i == ARRAY_SIZE(timebases))
482                         ret = SR_ERR_ARG;
483                 break;
484         case SR_CONF_TRIGGER_SOURCE:
485                 tmp_str = g_variant_get_string(data, NULL);
486                 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
487                         if (!strcmp(trigger_sources[i], tmp_str)) {
488                                 g_free(devc->trigger_source);
489                                 devc->trigger_source = g_strdup(trigger_sources[i]);
490                                 if (!strcmp(devc->trigger_source, "AC Line"))
491                                         tmp_str = "ACL";
492                                 else if (!strcmp(devc->trigger_source, "CH1"))
493                                         tmp_str = "CHAN1";
494                                 else if (!strcmp(devc->trigger_source, "CH2"))
495                                         tmp_str = "CHAN2";
496                                 else
497                                         tmp_str = (char *)devc->trigger_source;
498                                 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
499                                 break;
500                         }
501                 }
502                 if (i == ARRAY_SIZE(trigger_sources))
503                         ret = SR_ERR_ARG;
504                 break;
505         case SR_CONF_VDIV:
506                 g_variant_get(data, "(tt)", &p, &q);
507                 for (i = 0; i < 2; i++) {
508                         if (probe_group == &devc->analog_groups[i])
509                         {
510                                 for (j = 0; j < ARRAY_SIZE(vdivs); j++)
511                                 {
512                                         if (vdivs[j][0] != p || vdivs[j][1] != q)
513                                                 continue;
514                                         devc->vdiv[i] = (float)p / q;
515                                         return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
516                                                         devc->vdiv[i]);
517                                 }
518                                 return SR_ERR_ARG;
519                         }
520                 }
521                 return SR_ERR_NA;
522         case SR_CONF_COUPLING:
523                 tmp_str = g_variant_get_string(data, NULL);
524                 for (i = 0; i < 2; i++) {
525                         if (probe_group == &devc->analog_groups[i])
526                         {
527                                 for (j = 0; j < ARRAY_SIZE(coupling); j++)
528                                 {
529                                         if (!strcmp(tmp_str, coupling[j]))
530                                         {
531                                                 g_free(devc->coupling[i]);
532                                                 devc->coupling[i] = g_strdup(coupling[j]);
533                                                 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
534                                                                 devc->coupling[i]);
535                                         }
536                                 }
537                                 return SR_ERR_ARG;
538                         }
539                 }
540                 return SR_ERR_NA;
541         default:
542                 ret = SR_ERR_NA;
543                 break;
544         }
545
546         return ret;
547 }
548
549 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
550                 const struct sr_probe_group *probe_group)
551 {
552         GVariant *tuple, *rational[2];
553         GVariantBuilder gvb;
554         unsigned int i;
555         struct dev_context *devc = sdi->priv;
556
557         switch (key) {
558         case SR_CONF_SCAN_OPTIONS:
559                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
560                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
561                 break;
562         case SR_CONF_DEVICE_OPTIONS:
563                 if (probe_group == NULL) {
564                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
565                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
566                         return SR_OK;
567                 } else if (probe_group == &devc->digital_group) {
568                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
569                                 NULL, 0, sizeof(int32_t));
570                         return SR_OK;
571                 } else {
572                         for (i = 0; i < 2; i++) {
573                                 if (probe_group == &devc->analog_groups[i]) {
574                                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
575                                                 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
576                                         return SR_OK;
577                                 }
578                         }
579                         return SR_ERR_NA;
580                 }
581         case SR_CONF_COUPLING:
582                 for (i = 0; i < 2; i++) {
583                         if (probe_group == &devc->analog_groups[i]) {
584                                 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
585                                 return SR_OK;
586                         }
587                 }
588                 return SR_ERR_NA;
589         case SR_CONF_VDIV:
590                 for (i = 0; i < 2; i++) {
591                         if (probe_group == &devc->analog_groups[i]) {
592                                 rational[0] = g_variant_new_uint64(vdivs[i][0]);
593                                 rational[1] = g_variant_new_uint64(vdivs[i][1]);
594                                 *data = g_variant_new_tuple(rational, 2);
595                                 return SR_OK;
596                         }
597                 }
598                 return SR_ERR_NA;
599         case SR_CONF_TIMEBASE:
600                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
601                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
602                         rational[0] = g_variant_new_uint64(timebases[i][0]);
603                         rational[1] = g_variant_new_uint64(timebases[i][1]);
604                         tuple = g_variant_new_tuple(rational, 2);
605                         g_variant_builder_add_value(&gvb, tuple);
606                 }
607                 *data = g_variant_builder_end(&gvb);
608                 break;
609         case SR_CONF_TRIGGER_SOURCE:
610                 if (!sdi || !sdi->priv)
611                         /* Can't know this until we have the exact model. */
612                         return SR_ERR_ARG;
613                 *data = g_variant_new_strv(trigger_sources,
614                                 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
615                 break;
616         default:
617                 return SR_ERR_NA;
618         }
619
620         return SR_OK;
621 }
622
623 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
624 {
625         struct sr_serial_dev_inst *serial;
626         struct dev_context *devc;
627         struct sr_probe *probe;
628         GSList *l;
629         char cmd[256];
630
631         if (sdi->status != SR_ST_ACTIVE)
632                 return SR_ERR_DEV_CLOSED;
633
634         serial = sdi->conn;
635         devc = sdi->priv;
636
637         for (l = sdi->probes; l; l = l->next) {
638                 probe = l->data;
639                 sr_dbg("handling probe %s", probe->name);
640                 if (probe->type == SR_PROBE_ANALOG) {
641                         if (probe->enabled)
642                                 devc->enabled_analog_probes = g_slist_append(
643                                                 devc->enabled_analog_probes, probe);
644                         if (probe->enabled != devc->analog_channels[probe->index]) {
645                                 /* Enabled channel is currently disabled, or vice versa. */
646                                 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
647                                                 probe->enabled ? "ON" : "OFF");
648                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
649                                         return SR_ERR;
650                         }
651                 } else if (probe->type == SR_PROBE_LOGIC) {
652                         if (probe->enabled)
653                                 devc->enabled_digital_probes = g_slist_append(
654                                                 devc->enabled_digital_probes, probe);
655                         if (probe->enabled != devc->digital_channels[probe->index]) {
656                                 /* Enabled channel is currently disabled, or vice versa. */
657                                 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
658                                                 probe->enabled ? "ON" : "OFF");
659                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
660                                         return SR_ERR;
661                         }
662                 }
663         }
664         if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
665                 return SR_ERR;
666
667         sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
668
669         /* Send header packet to the session bus. */
670         std_session_send_df_header(cb_data, LOG_PREFIX);
671
672         /* Fetch the first frame. */
673         if (devc->enabled_analog_probes) {
674                 devc->channel_frame = devc->enabled_analog_probes->data;
675                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
676                                 devc->channel_frame->index + 1) != SR_OK)
677                         return SR_ERR;
678         } else {
679                 devc->channel_frame = devc->enabled_digital_probes->data;
680                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
681                         return SR_ERR;
682         }
683
684         devc->num_frame_bytes = 0;
685
686         return SR_OK;
687 }
688
689 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
690 {
691         struct dev_context *devc;
692         struct sr_serial_dev_inst *serial;
693
694         (void)cb_data;
695
696         devc = sdi->priv;
697
698         if (sdi->status != SR_ST_ACTIVE) {
699                 sr_err("Device inactive, can't stop acquisition.");
700                 return SR_ERR;
701         }
702
703         g_slist_free(devc->enabled_analog_probes);
704         g_slist_free(devc->enabled_digital_probes);
705         devc->enabled_analog_probes = NULL;
706         devc->enabled_digital_probes = NULL;
707         serial = sdi->conn;
708         sr_source_remove(serial->fd);
709
710         return SR_OK;
711 }
712
713 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
714         .name = "rigol-ds1xx2",
715         .longname = "Rigol DS1xx2",
716         .api_version = 1,
717         .init = init,
718         .cleanup = cleanup,
719         .scan = scan,
720         .dev_list = dev_list,
721         .dev_clear = dev_clear,
722         .config_get = config_get,
723         .config_set = config_set,
724         .config_list = config_list,
725         .dev_open = dev_open,
726         .dev_close = dev_close,
727         .dev_acquisition_start = dev_acquisition_start,
728         .dev_acquisition_stop = dev_acquisition_stop,
729         .priv = NULL,
730 };