]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/demo/demo.c
sysclk-lwla: Load bitstream files in RBF format.
[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#define LOG_PREFIX "demo"
36
37#define DEFAULT_NUM_LOGIC_PROBES 8
38#define DEFAULT_NUM_ANALOG_PROBES 4
39
40/* The size in bytes of chunks to send through the session bus. */
41#define LOGIC_BUFSIZE 4096
42/* Size of the analog pattern space per channel. */
43#define ANALOG_BUFSIZE 4096
44
45#define ANALOG_AMPLITUDE 25
46#define ANALOG_SAMPLES_PER_PERIOD 20
47
48/* Logic patterns we can generate. */
49enum {
50 /**
51 * Spells "sigrok" across 8 probes using '0's (with '1's as
52 * "background") when displayed using the 'bits' output format.
53 * The pattern is repeasted every 8 probes, shifted to the right
54 * in time by one bit.
55 */
56 PATTERN_SIGROK,
57
58 /** Pseudo-random values on all probes. */
59 PATTERN_RANDOM,
60
61 /**
62 * Incrementing number across 8 probes. The pattern is repeasted
63 * every 8 probes, shifted to the right in time by one bit.
64 */
65 PATTERN_INC,
66
67 /** All probes have a low logic state. */
68 PATTERN_ALL_LOW,
69
70 /** All probes have a high logic state. */
71 PATTERN_ALL_HIGH,
72};
73
74/* Analog patterns we can generate. */
75enum {
76 /**
77 * Square wave.
78 */
79 PATTERN_SQUARE,
80 PATTERN_SINE,
81 PATTERN_TRIANGLE,
82 PATTERN_SAWTOOTH,
83};
84
85static const char *logic_pattern_str[] = {
86 "sigrok",
87 "random",
88 "incremental",
89 "all-low",
90 "all-high",
91};
92
93static const char *analog_pattern_str[] = {
94 "square",
95 "sine",
96 "triangle",
97 "sawtooth",
98};
99
100struct analog_gen {
101 int pattern;
102 float pattern_data[ANALOG_BUFSIZE];
103 unsigned int num_samples;
104 struct sr_datafeed_analog packet;
105};
106
107/* Private, per-device-instance driver context. */
108struct dev_context {
109 int pipe_fds[2];
110 GIOChannel *channel;
111 uint64_t cur_samplerate;
112 uint64_t limit_samples;
113 uint64_t limit_msec;
114 uint64_t logic_counter;
115 uint64_t analog_counter;
116 int64_t starttime;
117 uint64_t step;
118 /* Logic */
119 int32_t num_logic_probes;
120 unsigned int logic_unitsize;
121 /* There is only ever one logic probe group, so its pattern goes here. */
122 uint8_t logic_pattern;
123 unsigned char logic_data[LOGIC_BUFSIZE];
124 /* Analog */
125 int32_t num_analog_probes;
126 GSList *analog_probe_groups;
127};
128
129static const int32_t scanopts[] = {
130 SR_CONF_NUM_LOGIC_PROBES,
131 SR_CONF_NUM_ANALOG_PROBES,
132};
133
134static const int devopts[] = {
135 SR_CONF_LOGIC_ANALYZER,
136 SR_CONF_DEMO_DEV,
137 SR_CONF_SAMPLERATE,
138 SR_CONF_LIMIT_SAMPLES,
139 SR_CONF_LIMIT_MSEC,
140};
141
142static const int devopts_pg[] = {
143 SR_CONF_PATTERN_MODE,
144};
145
146static const uint64_t samplerates[] = {
147 SR_HZ(1),
148 SR_GHZ(1),
149 SR_HZ(1),
150};
151
152static uint8_t pattern_sigrok[] = {
153 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
154 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
155 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
156 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
157 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
158 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161};
162
163SR_PRIV struct sr_dev_driver demo_driver_info;
164static struct sr_dev_driver *di = &demo_driver_info;
165
166static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
167
168
169static int dev_clear(void)
170{
171 return std_dev_clear(di, NULL);
172}
173
174static int init(struct sr_context *sr_ctx)
175{
176 return std_init(sr_ctx, di, LOG_PREFIX);
177}
178
179static void generate_analog_pattern(const struct sr_probe_group *probe_group, uint64_t sample_rate)
180{
181 struct analog_gen *ag;
182 double t, frequency;
183 float value;
184 unsigned int num_samples, i;
185 int last_end;
186
187 ag = probe_group->priv;
188 num_samples = ANALOG_BUFSIZE / sizeof(float);
189
190 sr_dbg("Generating %s pattern for probe group %s",
191 analog_pattern_str[ag->pattern],
192 probe_group->name);
193
194 switch (ag->pattern) {
195 case PATTERN_SQUARE:
196 value = ANALOG_AMPLITUDE;
197 last_end = 0;
198 for (i = 0; i < num_samples; i++) {
199 if (i % 5 == 0)
200 value = -value;
201 if (i % 10 == 0)
202 last_end = i - 1;
203 ag->pattern_data[i] = value;
204 }
205 ag->num_samples = last_end;
206 break;
207
208 case PATTERN_SINE:
209 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
210
211 /* Make sure the number of samples we put out is an integer
212 * multiple of our period size */
213 /* FIXME we actually need only one period. A ringbuffer would be
214 * usefull here.*/
215 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
216 num_samples--;
217
218 for (i = 0; i < num_samples; i++) {
219 t = (double) i / (double) sample_rate;
220 ag->pattern_data[i] = ANALOG_AMPLITUDE *
221 sin(2 * M_PI * frequency * t);
222 }
223
224 ag->num_samples = num_samples;
225 break;
226
227 case PATTERN_TRIANGLE:
228 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
229
230 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
231 num_samples--;
232
233 for (i = 0; i < num_samples; i++) {
234 t = (double) i / (double) sample_rate;
235 ag->pattern_data[i] = (2 * ANALOG_AMPLITUDE / M_PI) *
236 asin(sin(2 * M_PI * frequency * t));
237 }
238
239 ag->num_samples = num_samples;
240 break;
241
242 case PATTERN_SAWTOOTH:
243 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
244
245 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
246 num_samples--;
247
248 for (i = 0; i < num_samples; i++) {
249 t = (double) i / (double) sample_rate;
250 ag->pattern_data[i] = 2 * ANALOG_AMPLITUDE *
251 ((t * frequency) - floor(0.5f + t * frequency));
252 }
253
254 ag->num_samples = num_samples;
255 break;
256 }
257}
258
259static GSList *scan(GSList *options)
260{
261 struct drv_context *drvc;
262 struct dev_context *devc;
263 struct sr_dev_inst *sdi;
264 struct sr_probe *probe;
265 struct sr_probe_group *pg;
266 struct sr_config *src;
267 struct analog_gen *ag;
268 GSList *devices, *l;
269 int num_logic_probes, num_analog_probes, pattern, i;
270 char probe_name[16];
271
272 drvc = di->priv;
273
274 num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
275 num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
276 for (l = options; l; l = l->next) {
277 src = l->data;
278 switch (src->key) {
279 case SR_CONF_NUM_LOGIC_PROBES:
280 num_logic_probes = g_variant_get_int32(src->data);
281 break;
282 case SR_CONF_NUM_ANALOG_PROBES:
283 num_analog_probes = g_variant_get_int32(src->data);
284 break;
285 }
286 }
287
288 devices = NULL;
289 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
290 if (!sdi) {
291 sr_err("Device instance creation failed.");
292 return NULL;
293 }
294 sdi->driver = di;
295
296 if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
297 sr_err("Device context malloc failed.");
298 return NULL;
299 }
300 devc->cur_samplerate = SR_KHZ(200);
301 devc->limit_samples = 0;
302 devc->limit_msec = 0;
303 devc->step = 0;
304 devc->num_logic_probes = num_logic_probes;
305 devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
306 devc->logic_pattern = PATTERN_SIGROK;
307 devc->num_analog_probes = num_analog_probes;
308 devc->analog_probe_groups = NULL;
309
310 /* Logic probes, all in one probe group. */
311 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
312 return NULL;
313 pg->name = g_strdup("Logic");
314 pg->probes = NULL;
315 pg->priv = NULL;
316 for (i = 0; i < num_logic_probes; i++) {
317 sprintf(probe_name, "D%d", i);
318 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
319 return NULL;
320 sdi->probes = g_slist_append(sdi->probes, probe);
321 pg->probes = g_slist_append(pg->probes, probe);
322 }
323 sdi->probe_groups = g_slist_append(NULL, pg);
324
325 /* Analog probes, probe groups and pattern generators. */
326
327 pattern = 0;
328 for (i = 0; i < num_analog_probes; i++) {
329 sprintf(probe_name, "A%d", i);
330 if (!(probe = sr_probe_new(i + num_logic_probes,
331 SR_PROBE_ANALOG, TRUE, probe_name)))
332 return NULL;
333 sdi->probes = g_slist_append(sdi->probes, probe);
334
335 /* Every analog probe gets its own probe group. */
336 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
337 return NULL;
338 pg->name = g_strdup(probe_name);
339 pg->probes = g_slist_append(NULL, probe);
340
341 /* Every probe group gets a generator struct. */
342 if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
343 return NULL;
344 ag->packet.probes = pg->probes;
345 ag->packet.mq = 0;
346 ag->packet.mqflags = 0;
347 ag->packet.unit = SR_UNIT_VOLT;
348 ag->packet.data = ag->pattern_data;
349 ag->pattern = pattern;
350 pg->priv = ag;
351
352 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
353 devc->analog_probe_groups = g_slist_append(devc->analog_probe_groups, pg);
354
355 if (++pattern == ARRAY_SIZE(analog_pattern_str))
356 pattern = 0;
357 }
358
359 sdi->priv = devc;
360 devices = g_slist_append(devices, sdi);
361 drvc->instances = g_slist_append(drvc->instances, sdi);
362
363 return devices;
364}
365
366static GSList *dev_list(void)
367{
368 return ((struct drv_context *)(di->priv))->instances;
369}
370
371static int dev_open(struct sr_dev_inst *sdi)
372{
373 sdi->status = SR_ST_ACTIVE;
374
375 return SR_OK;
376}
377
378static int dev_close(struct sr_dev_inst *sdi)
379{
380 sdi->status = SR_ST_INACTIVE;
381
382 return SR_OK;
383}
384
385static int cleanup(void)
386{
387 return dev_clear();
388}
389
390static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
391 const struct sr_probe_group *probe_group)
392{
393 struct dev_context *devc;
394 struct sr_probe *probe;
395 struct analog_gen *ag;
396 int pattern;
397
398 if (!sdi)
399 return SR_ERR_ARG;
400
401 devc = sdi->priv;
402 switch (id) {
403 case SR_CONF_SAMPLERATE:
404 *data = g_variant_new_uint64(devc->cur_samplerate);
405 break;
406 case SR_CONF_LIMIT_SAMPLES:
407 *data = g_variant_new_uint64(devc->limit_samples);
408 break;
409 case SR_CONF_LIMIT_MSEC:
410 *data = g_variant_new_uint64(devc->limit_msec);
411 break;
412 case SR_CONF_PATTERN_MODE:
413 if (!probe_group)
414 return SR_ERR_PROBE_GROUP;
415 probe = probe_group->probes->data;
416 if (probe->type == SR_PROBE_LOGIC) {
417 pattern = devc->logic_pattern;
418 *data = g_variant_new_string(logic_pattern_str[pattern]);
419 } else if (probe->type == SR_PROBE_ANALOG) {
420 ag = probe_group->priv;
421 pattern = ag->pattern;
422 *data = g_variant_new_string(analog_pattern_str[pattern]);
423 } else
424 return SR_ERR_BUG;
425 break;
426 case SR_CONF_NUM_LOGIC_PROBES:
427 *data = g_variant_new_int32(devc->num_logic_probes);
428 break;
429 case SR_CONF_NUM_ANALOG_PROBES:
430 *data = g_variant_new_int32(devc->num_analog_probes);
431 break;
432 default:
433 return SR_ERR_NA;
434 }
435
436 return SR_OK;
437}
438
439static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
440 const struct sr_probe_group *probe_group)
441{
442 struct dev_context *devc;
443 struct analog_gen *ag;
444 struct sr_probe *probe;
445 int pattern, ret;
446 unsigned int i;
447 const char *stropt;
448
449 devc = sdi->priv;
450
451 if (sdi->status != SR_ST_ACTIVE)
452 return SR_ERR_DEV_CLOSED;
453
454 ret = SR_OK;
455 switch (id) {
456 case SR_CONF_SAMPLERATE:
457 devc->cur_samplerate = g_variant_get_uint64(data);
458 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
459 break;
460 case SR_CONF_LIMIT_SAMPLES:
461 devc->limit_msec = 0;
462 devc->limit_samples = g_variant_get_uint64(data);
463 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
464 break;
465 case SR_CONF_LIMIT_MSEC:
466 devc->limit_msec = g_variant_get_uint64(data);
467 devc->limit_samples = 0;
468 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
469 break;
470 case SR_CONF_PATTERN_MODE:
471 if (!probe_group)
472 return SR_ERR_PROBE_GROUP;
473 stropt = g_variant_get_string(data, NULL);
474 probe = probe_group->probes->data;
475 pattern = -1;
476 if (probe->type == SR_PROBE_LOGIC) {
477 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
478 if (!strcmp(stropt, logic_pattern_str[i])) {
479 pattern = i;
480 break;
481 }
482 }
483 if (pattern == -1)
484 return SR_ERR_ARG;
485 devc->logic_pattern = pattern;
486
487 /* Might as well do this now, these are static. */
488 if (pattern == PATTERN_ALL_LOW)
489 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
490 else if (pattern == PATTERN_ALL_HIGH)
491 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
492 sr_dbg("Setting logic pattern to %s",
493 logic_pattern_str[pattern]);
494 } else if (probe->type == SR_PROBE_ANALOG) {
495 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
496 if (!strcmp(stropt, analog_pattern_str[i])) {
497 pattern = i;
498 break;
499 }
500 }
501 if (pattern == -1)
502 return SR_ERR_ARG;
503 sr_dbg("Setting analog pattern for probe group %s to %s",
504 probe_group->name,
505 analog_pattern_str[pattern]);
506 ag = probe_group->priv;
507 ag->pattern = pattern;
508 } else
509 return SR_ERR_BUG;
510 break;
511 default:
512 ret = SR_ERR_NA;
513 }
514
515 return ret;
516}
517
518static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
519 const struct sr_probe_group *probe_group)
520{
521 struct sr_probe *probe;
522 GVariant *gvar;
523 GVariantBuilder gvb;
524
525 (void)sdi;
526
527 if (key == SR_CONF_SCAN_OPTIONS) {
528 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
529 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
530 return SR_OK;
531 }
532
533 if (!sdi)
534 return SR_ERR_ARG;
535
536 if (!probe_group) {
537 switch (key) {
538 case SR_CONF_DEVICE_OPTIONS:
539 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
540 devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
541 break;
542 case SR_CONF_SAMPLERATE:
543 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
544 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
545 ARRAY_SIZE(samplerates), sizeof(uint64_t));
546 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
547 *data = g_variant_builder_end(&gvb);
548 break;
549 default:
550 return SR_ERR_NA;
551 }
552 } else {
553 probe = probe_group->probes->data;
554 switch (key) {
555 case SR_CONF_DEVICE_OPTIONS:
556 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
557 devopts_pg, ARRAY_SIZE(devopts_pg), sizeof(int32_t));
558 break;
559 case SR_CONF_PATTERN_MODE:
560 if (probe->type == SR_PROBE_LOGIC)
561 *data = g_variant_new_strv(logic_pattern_str,
562 ARRAY_SIZE(logic_pattern_str));
563 else if (probe->type == SR_PROBE_ANALOG)
564 *data = g_variant_new_strv(analog_pattern_str,
565 ARRAY_SIZE(analog_pattern_str));
566 else
567 return SR_ERR_BUG;
568 break;
569 default:
570 return SR_ERR_NA;
571 }
572 }
573
574 return SR_OK;
575}
576
577static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
578{
579 struct dev_context *devc;
580 uint64_t i, j;
581 uint8_t pat;
582
583 devc = sdi->priv;
584
585 switch (devc->logic_pattern) {
586 case PATTERN_SIGROK:
587 memset(devc->logic_data, 0x00, size);
588 for (i = 0; i < size; i += devc->logic_unitsize) {
589 for (j = 0; j < devc->logic_unitsize; j++) {
590 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
591 devc->logic_data[i + j] = ~pat;
592 }
593 devc->step++;
594 }
595 break;
596 case PATTERN_RANDOM:
597 for (i = 0; i < size; i++)
598 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
599 break;
600 case PATTERN_INC:
601 for (i = 0; i < size; i++) {
602 for (j = 0; j < devc->logic_unitsize; j++) {
603 devc->logic_data[i + j] = devc->step;
604 }
605 devc->step++;
606 }
607 break;
608 case PATTERN_ALL_LOW:
609 case PATTERN_ALL_HIGH:
610 /* These were set when the pattern mode was selected. */
611 break;
612 default:
613 sr_err("Unknown pattern: %d.", devc->logic_pattern);
614 break;
615 }
616}
617
618/* Callback handling data */
619static int prepare_data(int fd, int revents, void *cb_data)
620{
621 struct sr_dev_inst *sdi;
622 struct dev_context *devc;
623 struct sr_datafeed_packet packet;
624 struct sr_datafeed_logic logic;
625 struct sr_probe_group *pg;
626 struct analog_gen *ag;
627 GSList *l;
628 uint64_t logic_todo, analog_todo, expected_samplenum, analog_samples, sending_now;
629 int64_t time, elapsed;
630
631 (void)fd;
632 (void)revents;
633
634 sdi = cb_data;
635 devc = sdi->priv;
636
637 /* How many "virtual" samples should we have collected by now? */
638 time = g_get_monotonic_time();
639 elapsed = time - devc->starttime;
640 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
641
642 /* Of those, how many do we still have to send? */
643 logic_todo = expected_samplenum - devc->logic_counter;
644 analog_todo = expected_samplenum - devc->analog_counter;
645
646 if (devc->limit_samples) {
647 logic_todo = MIN(logic_todo, devc->limit_samples - devc->logic_counter);
648 analog_todo = MIN(analog_todo, devc->limit_samples - devc->analog_counter);
649 }
650
651 while (logic_todo || analog_todo) {
652 /* Logic */
653 if (devc->num_logic_probes > 0 && logic_todo > 0) {
654 sending_now = MIN(logic_todo,
655 LOGIC_BUFSIZE / devc->logic_unitsize);
656 logic_generator(sdi, sending_now * devc->logic_unitsize);
657 packet.type = SR_DF_LOGIC;
658 packet.payload = &logic;
659 logic.length = sending_now * devc->logic_unitsize;
660 logic.unitsize = devc->logic_unitsize;
661 logic.data = devc->logic_data;
662 sr_session_send(sdi, &packet);
663 logic_todo -= sending_now;
664 devc->logic_counter += sending_now;
665 }
666
667 /* Analog, one probe at a time */
668 if (devc->num_analog_probes > 0 && analog_todo > 0) {
669 sending_now = 0;
670 for (l = devc->analog_probe_groups; l; l = l->next) {
671 pg = l->data;
672 ag = pg->priv;
673 packet.type = SR_DF_ANALOG;
674 packet.payload = &ag->packet;
675
676 /* FIXME we should make sure we output a whole
677 * period of data before we send out again the
678 * beginning of our buffer. A ring buffer would
679 * help here as well */
680
681 analog_samples = MIN(analog_todo, ag->num_samples);
682 /* Whichever probe group gets there first. */
683 sending_now = MAX(sending_now, analog_samples);
684 ag->packet.num_samples = analog_samples;
685 sr_session_send(sdi, &packet);
686 }
687 analog_todo -= sending_now;
688 devc->analog_counter += sending_now;
689 }
690 }
691
692 if (devc->limit_samples &&
693 devc->logic_counter >= devc->limit_samples &&
694 devc->analog_counter >= devc->limit_samples) {
695 sr_dbg("Requested number of samples reached.");
696 dev_acquisition_stop(sdi, cb_data);
697 return TRUE;
698 }
699
700 return TRUE;
701}
702
703static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
704{
705 GSList *l;
706 struct dev_context *devc;
707
708 if (sdi->status != SR_ST_ACTIVE)
709 return SR_ERR_DEV_CLOSED;
710
711 /* TODO: don't start without a sample limit set */
712 devc = sdi->priv;
713 devc->logic_counter = devc->analog_counter = 0;
714
715 /*
716 * Setting two channels connected by a pipe is a remnant from when the
717 * demo driver generated data in a thread, and collected and sent the
718 * data in the main program loop.
719 * They are kept here because it provides a convenient way of setting
720 * up a timeout-based polling mechanism.
721 */
722 if (pipe(devc->pipe_fds)) {
723 sr_err("%s: pipe() failed", __func__);
724 return SR_ERR;
725 }
726
727 for (l = devc->analog_probe_groups; l; l = l->next) {
728 generate_analog_pattern(l->data, devc->cur_samplerate);
729 }
730
731 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
732
733 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
734
735 /* Set channel encoding to binary (default is UTF-8). */
736 g_io_channel_set_encoding(devc->channel, NULL, NULL);
737
738 /* Make channels to unbuffered. */
739 g_io_channel_set_buffered(devc->channel, FALSE);
740
741 sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
742 40, prepare_data, (void *)sdi);
743
744 /* Send header packet to the session bus. */
745 std_session_send_df_header(cb_data, LOG_PREFIX);
746
747 /* We use this timestamp to decide how many more samples to send. */
748 devc->starttime = g_get_monotonic_time();
749
750 return SR_OK;
751}
752
753static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
754{
755 struct dev_context *devc;
756 struct sr_datafeed_packet packet;
757
758 (void)cb_data;
759
760 devc = sdi->priv;
761 sr_dbg("Stopping aquisition.");
762
763 sr_session_source_remove_channel(devc->channel);
764 g_io_channel_shutdown(devc->channel, FALSE, NULL);
765 g_io_channel_unref(devc->channel);
766 devc->channel = NULL;
767
768 /* Send last packet. */
769 packet.type = SR_DF_END;
770 sr_session_send(sdi, &packet);
771
772 return SR_OK;
773}
774
775SR_PRIV struct sr_dev_driver demo_driver_info = {
776 .name = "demo",
777 .longname = "Demo driver and pattern generator",
778 .api_version = 1,
779 .init = init,
780 .cleanup = cleanup,
781 .scan = scan,
782 .dev_list = dev_list,
783 .dev_clear = dev_clear,
784 .config_get = config_get,
785 .config_set = config_set,
786 .config_list = config_list,
787 .dev_open = dev_open,
788 .dev_close = dev_close,
789 .dev_acquisition_start = dev_acquisition_start,
790 .dev_acquisition_stop = dev_acquisition_stop,
791 .priv = NULL,
792};