]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
Code drop from DreamSourceLabs first source release.
[libsigrok.git] / hardware / demo / demo.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
6  * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
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 2 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, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <math.h>
27 #ifdef _WIN32
28 #include <io.h>
29 #include <fcntl.h>
30 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
31 #endif
32 #include "libsigrok.h"
33 #include "libsigrok-internal.h"
34
35 /* Message logging helpers with subsystem-specific prefix string. */
36 #define LOG_PREFIX "demo: "
37 #define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
38 #define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
39 #define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
40 #define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
41 #define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
42 #define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
43
44 /* TODO: Number of probes should be configurable. */
45 #define NUM_PROBES             16
46
47 #define DEMONAME               "Demo device"
48
49 /* The size of chunks to send through the session bus. */
50 /* TODO: Should be configurable. */
51 #define BUFSIZE                1024*1024
52
53 #define PERIOD                  4000
54
55 #define PI 3.14159265
56
57 #define CONST_LEN               50
58
59 /* Supported patterns which we can generate */
60 enum {
61     PATTERN_SINE = 0,
62     PATTERN_SQUARE = 1,
63     PATTERN_TRIANGLE = 2,
64     PATTERN_SAWTOOTH = 3,
65     PATTERN_RANDOM = 4,
66 };
67 static const char *pattern_strings[] = {
68     "Sine",
69     "Square",
70     "Triangle",
71     "Sawtooth",
72     "Random",
73 };
74
75 /* Private, per-device-instance driver context. */
76 struct dev_context {
77         struct sr_dev_inst *sdi;
78         int pipe_fds[2];
79         GIOChannel *channel;
80         uint64_t cur_samplerate;
81         uint64_t limit_samples;
82         uint64_t limit_msec;
83         uint8_t sample_generator;
84         uint64_t samples_counter;
85         void *cb_data;
86         int64_t starttime;
87     int stop;
88
89     int trigger_stage;
90     uint16_t trigger_mask;
91     uint16_t trigger_value;
92     uint16_t trigger_edge;
93 };
94
95 static const int hwcaps[] = {
96         SR_CONF_LOGIC_ANALYZER,
97         SR_CONF_DEMO_DEV,
98         SR_CONF_SAMPLERATE,
99         SR_CONF_PATTERN_MODE,
100         SR_CONF_LIMIT_SAMPLES,
101         SR_CONF_LIMIT_MSEC,
102         SR_CONF_CONTINUOUS,
103 };
104
105 static const int hwoptions[] = {
106     SR_CONF_PATTERN_MODE,
107 };
108
109 static const uint64_t samplerates[] = {
110     SR_KHZ(10),
111     SR_KHZ(20),
112     SR_KHZ(50),
113     SR_KHZ(100),
114     SR_KHZ(200),
115     SR_KHZ(500),
116     SR_MHZ(1),
117     SR_MHZ(2),
118     SR_MHZ(5),
119     SR_MHZ(10),
120     SR_MHZ(20),
121     SR_MHZ(50),
122     SR_MHZ(100),
123     SR_MHZ(200),
124 };
125
126
127
128 /* We name the probes 0-7 on our demo driver. */
129 static const char *probe_names[NUM_PROBES + 1] = {
130     "Channel 0", "Channel 1", "Channel 2", "Channel 3",
131     "Channel 4", "Channel 5", "Channel 6", "Channel 7",
132     "Channel 8", "Channel 9", "Channel 10", "Channel 11",
133     "Channel 12", "Channel 13", "Channel 14", "Channel 15",
134         NULL,
135 };
136
137 /* Private, per-device-instance driver context. */
138 /* TODO: struct context as with the other drivers. */
139
140 /* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
141 SR_PRIV struct sr_dev_driver demo_driver_info;
142 static struct sr_dev_driver *di = &demo_driver_info;
143
144 extern struct ds_trigger *trigger;
145
146 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
147
148 static int clear_instances(void)
149 {
150         /* Nothing needed so far. */
151
152         return SR_OK;
153 }
154
155 static int hw_init(struct sr_context *sr_ctx)
156 {
157         return std_hw_init(sr_ctx, di, LOG_PREFIX);
158 }
159
160 static GSList *hw_scan(GSList *options)
161 {
162         struct sr_dev_inst *sdi;
163         struct sr_probe *probe;
164         struct drv_context *drvc;
165         struct dev_context *devc;
166         GSList *devices;
167         int i;
168
169         (void)options;
170
171         drvc = di->priv;
172
173         devices = NULL;
174
175     sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
176         if (!sdi) {
177         sr_err("Device instance creation failed.");
178                 return NULL;
179         }
180         sdi->driver = di;
181
182         devices = g_slist_append(devices, sdi);
183         drvc->instances = g_slist_append(drvc->instances, sdi);
184
185         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
186                 sr_err("Device context malloc failed.");
187                 return NULL;
188         }
189
190         devc->sdi = sdi;
191     devc->cur_samplerate = SR_MHZ(200);
192         devc->limit_samples = 0;
193         devc->limit_msec = 0;
194     devc->sample_generator = PATTERN_SINE;
195
196         sdi->priv = devc;
197
198     if (sdi->mode == LOGIC) {
199         for (i = 0; probe_names[i]; i++) {
200             if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
201                     probe_names[i])))
202                 return NULL;
203             sdi->probes = g_slist_append(sdi->probes, probe);
204         }
205     } else if (sdi->mode == ANALOG) {
206         for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) {
207             if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
208                     probe_names[i])))
209                 return NULL;
210             sdi->probes = g_slist_append(sdi->probes, probe);
211         }
212     }
213
214         return devices;
215 }
216
217 static GSList *hw_dev_list(void)
218 {
219         return ((struct drv_context *)(di->priv))->instances;
220 }
221
222 static int hw_dev_open(struct sr_dev_inst *sdi)
223 {
224         (void)sdi;
225
226         sdi->status = SR_ST_ACTIVE;
227
228         return SR_OK;
229 }
230
231 static int hw_dev_close(struct sr_dev_inst *sdi)
232 {
233         (void)sdi;
234
235     sdi->status = SR_ST_INACTIVE;
236
237         return SR_OK;
238 }
239
240 static int hw_cleanup(void)
241 {
242         GSList *l;
243         struct sr_dev_inst *sdi;
244         struct drv_context *drvc;
245         int ret = SR_OK;
246
247         if (!(drvc = di->priv))
248                 return SR_OK;
249
250         /* Properly close and free all devices. */
251         for (l = drvc->instances; l; l = l->next) {
252                 if (!(sdi = l->data)) {
253                         /* Log error, but continue cleaning up the rest. */
254                         sr_err("%s: sdi was NULL, continuing", __func__);
255                         ret = SR_ERR_BUG;
256                         continue;
257                 }
258                 sr_dev_inst_free(sdi);
259         }
260         g_slist_free(drvc->instances);
261         drvc->instances = NULL;
262
263         return ret;
264 }
265
266 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
267 {
268         struct dev_context *const devc = sdi->priv;
269
270         switch (id) {
271         case SR_CONF_SAMPLERATE:
272                 *data = g_variant_new_uint64(devc->cur_samplerate);
273                 break;
274         case SR_CONF_LIMIT_SAMPLES:
275                 *data = g_variant_new_uint64(devc->limit_samples);
276                 break;
277         case SR_CONF_LIMIT_MSEC:
278                 *data = g_variant_new_uint64(devc->limit_msec);
279                 break;
280     case SR_CONF_DEVICE_MODE:
281         *data = g_variant_new_string(mode_strings[sdi->mode]);
282         break;
283     case SR_CONF_PATTERN_MODE:
284         *data = g_variant_new_string(pattern_strings[devc->sample_generator]);
285                 break;
286         default:
287                 return SR_ERR_NA;
288         }
289
290         return SR_OK;
291 }
292
293 static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi)
294 {
295     int i, ret;
296         const char *stropt;
297     struct sr_probe *probe;
298
299         struct dev_context *const devc = sdi->priv;
300
301         if (sdi->status != SR_ST_ACTIVE)
302                 return SR_ERR_DEV_CLOSED;
303
304         if (id == SR_CONF_SAMPLERATE) {
305                 devc->cur_samplerate = g_variant_get_uint64(data);
306                 sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
307                        devc->cur_samplerate);
308                 ret = SR_OK;
309         } else if (id == SR_CONF_LIMIT_SAMPLES) {
310                 devc->limit_msec = 0;
311                 devc->limit_samples = g_variant_get_uint64(data);
312                 sr_dbg("%s: setting limit_samples to %" PRIu64, __func__,
313                        devc->limit_samples);
314                 ret = SR_OK;
315         } else if (id == SR_CONF_LIMIT_MSEC) {
316                 devc->limit_msec = g_variant_get_uint64(data);
317                 devc->limit_samples = 0;
318                 sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
319                        devc->limit_msec);
320         ret = SR_OK;
321     } else if (id == SR_CONF_DEVICE_MODE) {
322         stropt = g_variant_get_string(data, NULL);
323         ret = SR_OK;
324         if (!strcmp(stropt, mode_strings[LOGIC])) {
325             sdi->mode = LOGIC;
326             sr_dev_probes_free(sdi);
327             for (i = 0; probe_names[i]; i++) {
328                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
329                         probe_names[i])))
330                     ret = SR_ERR;
331                 else
332                     sdi->probes = g_slist_append(sdi->probes, probe);
333             }
334         } else if (!strcmp(stropt, mode_strings[ANALOG])) {
335             sdi->mode = ANALOG;
336             sr_dev_probes_free(sdi);
337             for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) {
338                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
339                         probe_names[i])))
340                     ret = SR_ERR;
341                 else
342                     sdi->probes = g_slist_append(sdi->probes, probe);
343             }
344         } else {
345             ret = SR_ERR;
346         }
347         sr_dbg("%s: setting mode to %d", __func__, sdi->mode);
348     }else if (id == SR_CONF_PATTERN_MODE) {
349                 stropt = g_variant_get_string(data, NULL);
350         ret = SR_OK;
351         if (!strcmp(stropt, pattern_strings[PATTERN_SINE])) {
352             devc->sample_generator = PATTERN_SINE;
353         } else if (!strcmp(stropt, pattern_strings[PATTERN_SQUARE])) {
354             devc->sample_generator = PATTERN_SQUARE;
355         } else if (!strcmp(stropt, pattern_strings[PATTERN_TRIANGLE])) {
356             devc->sample_generator = PATTERN_TRIANGLE;
357         } else if (!strcmp(stropt, pattern_strings[PATTERN_SAWTOOTH])) {
358             devc->sample_generator = PATTERN_SAWTOOTH;
359         } else if (!strcmp(stropt, pattern_strings[PATTERN_RANDOM])) {
360             devc->sample_generator = PATTERN_RANDOM;
361                 } else {
362             ret = SR_ERR;
363                 }
364         sr_dbg("%s: setting pattern to %d",
365                         __func__, devc->sample_generator);
366         } else {
367         ret = SR_ERR_NA;
368         }
369
370         return ret;
371 }
372
373 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
374 {
375         GVariant *gvar;
376         GVariantBuilder gvb;
377
378         (void)sdi;
379
380         switch (key) {
381     case SR_CONF_DEVICE_OPTIONS:
382 //              *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
383 //                              hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
384                 *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"),
385                 hwcaps, ARRAY_SIZE(hwcaps)*sizeof(int32_t), TRUE, NULL, NULL);
386                 break;
387     case SR_CONF_DEVICE_CONFIGS:
388 //              *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
389 //                              hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
390         *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"),
391                 hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL);
392         break;
393     case SR_CONF_SAMPLERATE:
394                 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
395 //              gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
396 //                              ARRAY_SIZE(samplerates), sizeof(uint64_t));
397                 gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"),
398                                 samplerates, ARRAY_SIZE(samplerates)*sizeof(uint64_t), TRUE, NULL, NULL);
399         g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
400                 *data = g_variant_builder_end(&gvb);
401                 break;
402     case SR_CONF_DEVICE_MODE:
403         *data = g_variant_new_strv(mode_strings, ARRAY_SIZE(mode_strings));
404         break;
405     case SR_CONF_PATTERN_MODE:
406                 *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
407                 break;
408         default:
409         return SR_ERR_NA;
410         }
411
412     return SR_OK;
413 }
414
415 static void samples_generator(uint16_t *buf, uint64_t size,
416                               struct dev_context *devc)
417 {
418     static uint16_t p = 0;
419         uint64_t i;
420     uint16_t demo_data;
421
422         switch (devc->sample_generator) {
423     case PATTERN_SINE: /* Sine */
424         for (i = 0; i < size; i++) {
425             if (i%CONST_LEN == 0) {
426                 demo_data = 0x8000 * sin(2 * PI * p / 0xffff) + 0x8000;
427                 p += CONST_LEN;
428             }
429             *(buf + i) = demo_data;
430         }
431                 break;
432     case PATTERN_SQUARE:
433         for (i = 0; i < size; i++) {
434             if (i%CONST_LEN == 0) {
435                 demo_data = p > 0x7fff ? 0xf000 : 0x1000;
436                 p += CONST_LEN;
437             }
438             *(buf + i) = demo_data;
439         }
440         break;
441     case PATTERN_TRIANGLE:
442         for (i = 0; i < size; i++) {
443             if (i%CONST_LEN == 0) {
444                 demo_data = p > 0x7fff ? 0xffff * (2.0f * (0x10000 - p) / 0x10000) :
445                                          0xffff * (2.0f * p / 0x10000);
446                 p += CONST_LEN;
447             }
448             *(buf + i) = demo_data;
449         }
450         break;
451     case PATTERN_SAWTOOTH:
452         for (i = 0; i < size; i++) {
453             if (i%CONST_LEN == 0) {
454                 demo_data = p;
455                 p += CONST_LEN;
456             }
457             *(buf + i) = demo_data;
458         }
459         break;
460         case PATTERN_RANDOM: /* Random */
461         for (i = 0; i < size; i++) {
462             if (i%CONST_LEN == 0)
463                 demo_data = (uint16_t)(rand() * (0x10000 * 1.0f / RAND_MAX));
464             *(buf + i) = demo_data;
465         }
466                 break;
467         default:
468         sr_err("Unknown pattern: %d.", devc->sample_generator);
469                 break;
470         }
471 }
472
473 /* Callback handling data */
474 static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
475 {
476     struct dev_context *devc = sdi->priv;
477     struct sr_datafeed_packet packet;
478     struct sr_datafeed_logic logic;
479     struct sr_datafeed_analog analog;
480     //uint16_t buf[BUFSIZE];
481     uint16_t *buf;
482         static uint64_t samples_to_send, expected_samplenum, sending_now;
483         int64_t time, elapsed;
484     static uint16_t last_sample = 0;
485     uint16_t cur_sample;
486     int i;
487
488         (void)fd;
489         (void)revents;
490
491     if (!(buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) {
492         sr_err("buf for receive_data malloc failed.");
493         return FALSE;
494     }
495
496         /* How many "virtual" samples should we have collected by now? */
497         time = g_get_monotonic_time();
498         elapsed = time - devc->starttime;
499     devc->starttime = time;
500         expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
501         /* Of those, how many do we still have to send? */
502     //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN;
503     samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN;
504
505     if (devc->limit_samples) {
506         if (sdi->mode == LOGIC)
507             samples_to_send = MIN(samples_to_send,
508                      devc->limit_samples - devc->samples_counter);
509         else if (sdi->mode == ANALOG)
510             samples_to_send = MIN(samples_to_send,
511                      devc->limit_samples);
512     }
513
514     while (samples_to_send > 0) {
515         sending_now = MIN(samples_to_send, BUFSIZE);
516                 samples_generator(buf, sending_now, devc);
517
518         if (devc->trigger_stage != 0) {
519             for (i = 0; i < sending_now; i++) {
520                 if (devc->trigger_edge == 0) {
521                     if ((*(buf + i) | devc->trigger_mask) ==
522                             (devc->trigger_value | devc->trigger_mask)) {
523                         devc->trigger_stage = 0;
524                         break;
525                     }
526                 } else {
527                     cur_sample = *(buf + i);
528                     if (((last_sample & devc->trigger_edge) ==
529                          (~devc->trigger_value & devc->trigger_edge)) &&
530                         ((cur_sample | devc->trigger_mask) ==
531                          (devc->trigger_value | devc->trigger_mask)) &&
532                         ((cur_sample & devc->trigger_edge) ==
533                          (devc->trigger_value & devc->trigger_edge))) {
534                         devc->trigger_stage = 0;
535                         break;
536                     }
537                     last_sample = cur_sample;
538                 }
539             }
540             if (devc->trigger_stage == 0) {
541                 struct ds_trigger_pos demo_trigger_pos;
542                 demo_trigger_pos.real_pos = i;
543                 packet.type = SR_DF_TRIGGER;
544                 packet.payload = &demo_trigger_pos;
545                 sr_session_send(sdi, &packet);
546             }
547         }
548
549         if (devc->trigger_stage == 0){
550             samples_to_send -= sending_now;
551             if (sdi->mode == LOGIC) {
552                 packet.type = SR_DF_LOGIC;
553                 packet.payload = &logic;
554                 logic.length = sending_now * (NUM_PROBES >> 3);
555                 logic.unitsize = (NUM_PROBES >> 3);
556                 logic.data = buf;
557             } else if (sdi->mode == ANALOG) {
558                 packet.type = SR_DF_ANALOG;
559                 packet.payload = &analog;
560                 analog.probes = sdi->probes;
561                 analog.num_samples = sending_now;
562                 analog.mq = SR_MQ_VOLTAGE;
563                 analog.unit = SR_UNIT_VOLT;
564                 analog.mqflags = SR_MQFLAG_AC;
565                 analog.data = buf;
566             }
567
568             sr_session_send(sdi, &packet);
569             if (sdi->mode == LOGIC)
570                 devc->samples_counter += sending_now;
571             else if (sdi->mode == ANALOG)
572                 devc->samples_counter = (devc->samples_counter + sending_now) % devc->limit_samples;
573         } else {
574             break;
575         }
576         }
577
578     if (sdi->mode == LOGIC &&
579         devc->limit_samples &&
580         devc->samples_counter >= devc->limit_samples) {
581         sr_info("Requested number of samples reached.");
582         hw_dev_acquisition_stop(sdi, NULL);
583         g_free(buf);
584         return TRUE;
585     }
586
587     g_free(buf);
588
589         return TRUE;
590 }
591
592 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
593                 void *cb_data)
594 {
595         struct dev_context *const devc = sdi->priv;
596
597     (void)cb_data;
598
599     if (sdi->status != SR_ST_ACTIVE)
600         return SR_ERR_DEV_CLOSED;
601
602     //devc->cb_data = cb_data;
603         devc->samples_counter = 0;
604     devc->stop = FALSE;
605
606     /*
607      * trigger setting
608      */
609     if (!trigger->trigger_en || sdi->mode == ANALOG) {
610         devc->trigger_stage = 0;
611     } else {
612         devc->trigger_mask = ds_trigger_get_mask0(TriggerStages);
613         devc->trigger_value = ds_trigger_get_value0(TriggerStages);
614         devc->trigger_edge = ds_trigger_get_edge0(TriggerStages);
615         if (devc->trigger_edge != 0)
616             devc->trigger_stage = 2;
617         else
618             devc->trigger_stage = 1;
619     }
620
621         /*
622          * Setting two channels connected by a pipe is a remnant from when the
623          * demo driver generated data in a thread, and collected and sent the
624          * data in the main program loop.
625          * They are kept here because it provides a convenient way of setting
626          * up a timeout-based polling mechanism.
627          */
628         if (pipe(devc->pipe_fds)) {
629                 /* TODO: Better error message. */
630                 sr_err("%s: pipe() failed", __func__);
631                 return SR_ERR;
632         }
633
634         devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
635
636         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
637
638         /* Set channel encoding to binary (default is UTF-8). */
639         g_io_channel_set_encoding(devc->channel, NULL, NULL);
640
641         /* Make channels to unbuffered. */
642         g_io_channel_set_buffered(devc->channel, FALSE);
643
644     sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
645             100, receive_data, sdi);
646
647         /* Send header packet to the session bus. */
648     //std_session_send_df_header(cb_data, LOG_PREFIX);
649     std_session_send_df_header(sdi, LOG_PREFIX);
650
651         /* We use this timestamp to decide how many more samples to send. */
652         devc->starttime = g_get_monotonic_time();
653
654         return SR_OK;
655 }
656
657 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
658 {
659         struct dev_context *const devc = sdi->priv;
660         struct sr_datafeed_packet packet;
661
662         (void)cb_data;
663
664         sr_dbg("Stopping aquisition.");
665
666     devc->stop = TRUE;
667     sr_session_source_remove_channel(devc->channel);
668         g_io_channel_shutdown(devc->channel, FALSE, NULL);
669         g_io_channel_unref(devc->channel);
670         devc->channel = NULL;
671
672         /* Send last packet. */
673     packet.type = SR_DF_END;
674     sr_session_send(sdi, &packet);
675
676         return SR_OK;
677 }
678
679 static int hw_dev_test(struct sr_dev_inst *sdi)
680 {
681     if (sdi)
682         return SR_OK;
683     else
684         return SR_ERR;
685 }
686
687 SR_PRIV struct sr_dev_driver demo_driver_info = {
688         .name = "demo",
689         .longname = "Demo driver and pattern generator",
690         .api_version = 1,
691         .init = hw_init,
692         .cleanup = hw_cleanup,
693         .scan = hw_scan,
694         .dev_list = hw_dev_list,
695         .dev_clear = clear_instances,
696         .config_get = config_get,
697         .config_set = config_set,
698         .config_list = config_list,
699         .dev_open = hw_dev_open,
700         .dev_close = hw_dev_close,
701     .dev_test = hw_dev_test,
702         .dev_acquisition_start = hw_dev_acquisition_start,
703         .dev_acquisition_stop = hw_dev_acquisition_stop,
704         .priv = NULL,
705 };