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