]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/demo/demo.c
Code drop from DreamSourceLabs first source release.
[libsigrok.git] / hardware / demo / demo.c
... / ...
CommitLineData
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 */
60enum {
61 PATTERN_SINE = 0,
62 PATTERN_SQUARE = 1,
63 PATTERN_TRIANGLE = 2,
64 PATTERN_SAWTOOTH = 3,
65 PATTERN_RANDOM = 4,
66};
67static const char *pattern_strings[] = {
68 "Sine",
69 "Square",
70 "Triangle",
71 "Sawtooth",
72 "Random",
73};
74
75/* Private, per-device-instance driver context. */
76struct 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
95static 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
105static const int hwoptions[] = {
106 SR_CONF_PATTERN_MODE,
107};
108
109static 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. */
129static 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(). */
141SR_PRIV struct sr_dev_driver demo_driver_info;
142static struct sr_dev_driver *di = &demo_driver_info;
143
144extern struct ds_trigger *trigger;
145
146static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
147
148static int clear_instances(void)
149{
150 /* Nothing needed so far. */
151
152 return SR_OK;
153}
154
155static int hw_init(struct sr_context *sr_ctx)
156{
157 return std_hw_init(sr_ctx, di, LOG_PREFIX);
158}
159
160static 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
217static GSList *hw_dev_list(void)
218{
219 return ((struct drv_context *)(di->priv))->instances;
220}
221
222static 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
231static 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
240static 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
266static 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
293static 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
373static 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
415static 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 */
474static 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
592static 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
657static 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
679static 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
687SR_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};