]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/demo/demo.c
Change sr_dev_inst_new() to take no parameters.
[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 scanopts[] = {
132 SR_CONF_NUM_LOGIC_CHANNELS,
133 SR_CONF_NUM_ANALOG_CHANNELS,
134};
135
136static const uint32_t devopts[] = {
137 SR_CONF_DEMO_DEV,
138 SR_CONF_LOGIC_ANALYZER,
139 SR_CONF_OSCILLOSCOPE,
140 SR_CONF_CONTINUOUS,
141 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
142 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
143};
144
145static const uint32_t devopts_global[] = {
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 - 1;
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 = sr_dev_inst_new();
294 sdi->status = SR_ST_ACTIVE;
295 sdi->model = "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 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name)))
315 return NULL;
316 sdi->channels = g_slist_append(sdi->channels, ch);
317 cg->channels = g_slist_append(cg->channels, ch);
318 }
319 sdi->channel_groups = g_slist_append(NULL, cg);
320
321 /* Analog channels, channel groups and pattern generators. */
322 pattern = 0;
323 /* An "Analog" channel group with all analog channels in it. */
324 acg = g_malloc0(sizeof(struct sr_channel_group));
325 acg->name = g_strdup("Analog");
326 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
327
328 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
329 for (i = 0; i < num_analog_channels; i++) {
330 snprintf(channel_name, 16, "A%d", i);
331 ch = sr_channel_new(i + num_logic_channels, SR_CHANNEL_ANALOG,
332 TRUE, channel_name);
333 sdi->channels = g_slist_append(sdi->channels, ch);
334 acg->channels = g_slist_append(acg->channels, ch);
335
336 /* Every analog channel gets its own channel group as well. */
337 cg = g_malloc0(sizeof(struct sr_channel_group));
338 cg->name = g_strdup(channel_name);
339 cg->channels = g_slist_append(NULL, ch);
340 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
341
342 /* Every channel gets a generator struct. */
343 ag = g_malloc(sizeof(struct analog_gen));
344 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
345 ag->packet.channels = cg->channels;
346 ag->packet.mq = 0;
347 ag->packet.mqflags = 0;
348 ag->packet.unit = SR_UNIT_VOLT;
349 ag->packet.data = ag->pattern_data;
350 ag->pattern = pattern;
351 g_hash_table_insert(devc->ch_ag, ch, ag);
352
353 if (++pattern == ARRAY_SIZE(analog_pattern_str))
354 pattern = 0;
355 }
356
357 sdi->priv = devc;
358 devices = g_slist_append(devices, sdi);
359 drvc->instances = g_slist_append(drvc->instances, sdi);
360
361 return devices;
362}
363
364static GSList *dev_list(void)
365{
366 return ((struct drv_context *)(di->priv))->instances;
367}
368
369static int dev_open(struct sr_dev_inst *sdi)
370{
371 sdi->status = SR_ST_ACTIVE;
372
373 return SR_OK;
374}
375
376static int dev_close(struct sr_dev_inst *sdi)
377{
378 sdi->status = SR_ST_INACTIVE;
379
380 return SR_OK;
381}
382
383static void clear_helper(void *priv)
384{
385 struct dev_context *devc;
386 GHashTableIter iter;
387 void *value;
388
389 devc = priv;
390
391 /* Analog generators. */
392 g_hash_table_iter_init(&iter, devc->ch_ag);
393 while (g_hash_table_iter_next(&iter, NULL, &value))
394 g_free(value);
395 g_hash_table_unref(devc->ch_ag);
396 g_free(devc);
397}
398
399static int cleanup(void)
400{
401 return std_dev_clear(di, clear_helper);
402}
403
404static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
405 const struct sr_channel_group *cg)
406{
407 struct dev_context *devc;
408 struct sr_channel *ch;
409 struct analog_gen *ag;
410 int pattern;
411
412 if (!sdi)
413 return SR_ERR_ARG;
414
415 devc = sdi->priv;
416 switch (key) {
417 case SR_CONF_SAMPLERATE:
418 *data = g_variant_new_uint64(devc->cur_samplerate);
419 break;
420 case SR_CONF_LIMIT_SAMPLES:
421 *data = g_variant_new_uint64(devc->limit_samples);
422 break;
423 case SR_CONF_LIMIT_MSEC:
424 *data = g_variant_new_uint64(devc->limit_msec);
425 break;
426 case SR_CONF_PATTERN_MODE:
427 if (!cg)
428 return SR_ERR_CHANNEL_GROUP;
429 /* Any channel in the group will do. */
430 ch = cg->channels->data;
431 if (ch->type == SR_CHANNEL_LOGIC) {
432 pattern = devc->logic_pattern;
433 *data = g_variant_new_string(logic_pattern_str[pattern]);
434 } else if (ch->type == SR_CHANNEL_ANALOG) {
435 ag = g_hash_table_lookup(devc->ch_ag, ch);
436 pattern = ag->pattern;
437 *data = g_variant_new_string(analog_pattern_str[pattern]);
438 } else
439 return SR_ERR_BUG;
440 break;
441 case SR_CONF_AMPLITUDE:
442 if (!cg)
443 return SR_ERR_CHANNEL_GROUP;
444 /* Any channel in the group will do. */
445 ch = cg->channels->data;
446 if (ch->type != SR_CHANNEL_ANALOG)
447 return SR_ERR_ARG;
448 ag = g_hash_table_lookup(devc->ch_ag, ch);
449 *data = g_variant_new_double(ag->amplitude);
450 break;
451 default:
452 return SR_ERR_NA;
453 }
454
455 return SR_OK;
456}
457
458static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
459 const struct sr_channel_group *cg)
460{
461 struct dev_context *devc;
462 struct analog_gen *ag;
463 struct sr_channel *ch;
464 GSList *l;
465 int logic_pattern, analog_pattern, ret;
466 unsigned int i;
467 const char *stropt;
468
469 devc = sdi->priv;
470
471 if (sdi->status != SR_ST_ACTIVE)
472 return SR_ERR_DEV_CLOSED;
473
474 ret = SR_OK;
475 switch (key) {
476 case SR_CONF_SAMPLERATE:
477 devc->cur_samplerate = g_variant_get_uint64(data);
478 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
479 break;
480 case SR_CONF_LIMIT_SAMPLES:
481 devc->limit_msec = 0;
482 devc->limit_samples = g_variant_get_uint64(data);
483 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
484 break;
485 case SR_CONF_LIMIT_MSEC:
486 devc->limit_msec = g_variant_get_uint64(data);
487 devc->limit_samples = 0;
488 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
489 break;
490 case SR_CONF_PATTERN_MODE:
491 if (!cg)
492 return SR_ERR_CHANNEL_GROUP;
493 stropt = g_variant_get_string(data, NULL);
494 logic_pattern = analog_pattern = -1;
495 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
496 if (!strcmp(stropt, logic_pattern_str[i])) {
497 logic_pattern = i;
498 break;
499 }
500 }
501 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
502 if (!strcmp(stropt, analog_pattern_str[i])) {
503 analog_pattern = i;
504 break;
505 }
506 }
507 if (logic_pattern == -1 && analog_pattern == -1)
508 return SR_ERR_ARG;
509 for (l = cg->channels; l; l = l->next) {
510 ch = l->data;
511 if (ch->type == SR_CHANNEL_LOGIC) {
512 if (logic_pattern == -1)
513 return SR_ERR_ARG;
514 sr_dbg("Setting logic pattern to %s",
515 logic_pattern_str[logic_pattern]);
516 devc->logic_pattern = logic_pattern;
517 /* Might as well do this now, these are static. */
518 if (logic_pattern == PATTERN_ALL_LOW)
519 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
520 else if (logic_pattern == PATTERN_ALL_HIGH)
521 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
522 } else if (ch->type == SR_CHANNEL_ANALOG) {
523 if (analog_pattern == -1)
524 return SR_ERR_ARG;
525 sr_dbg("Setting analog pattern for channel %s to %s",
526 ch->name, analog_pattern_str[analog_pattern]);
527 ag = g_hash_table_lookup(devc->ch_ag, ch);
528 ag->pattern = analog_pattern;
529 } else
530 return SR_ERR_BUG;
531 }
532 break;
533 case SR_CONF_AMPLITUDE:
534 if (!cg)
535 return SR_ERR_CHANNEL_GROUP;
536 for (l = cg->channels; l; l = l->next) {
537 ch = l->data;
538 if (ch->type != SR_CHANNEL_ANALOG)
539 return SR_ERR_ARG;
540 ag = g_hash_table_lookup(devc->ch_ag, ch);
541 ag->amplitude = g_variant_get_double(data);
542 }
543 break;
544 default:
545 ret = SR_ERR_NA;
546 }
547
548 return ret;
549}
550
551static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
552 const struct sr_channel_group *cg)
553{
554 struct sr_channel *ch;
555 GVariant *gvar;
556 GVariantBuilder gvb;
557
558 (void)sdi;
559
560 if (key == SR_CONF_SCAN_OPTIONS) {
561 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
562 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
563 return SR_OK;
564 }
565
566 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
567 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
568 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
569 return SR_OK;
570 }
571
572 if (!sdi)
573 return SR_ERR_ARG;
574
575 if (!cg) {
576 switch (key) {
577 case SR_CONF_DEVICE_OPTIONS:
578 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
579 devopts_global, ARRAY_SIZE(devopts_global), sizeof(uint32_t));
580 break;
581 case SR_CONF_SAMPLERATE:
582 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
583 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
584 ARRAY_SIZE(samplerates), sizeof(uint64_t));
585 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
586 *data = g_variant_builder_end(&gvb);
587 break;
588 default:
589 return SR_ERR_NA;
590 }
591 } else {
592 /* Any channel in the group will do. */
593 ch = cg->channels->data;
594 switch (key) {
595 case SR_CONF_DEVICE_OPTIONS:
596 if (ch->type == SR_CHANNEL_LOGIC)
597 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
598 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
599 sizeof(uint32_t));
600 else if (ch->type == SR_CHANNEL_ANALOG)
601 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
602 devopts_cg_analog, ARRAY_SIZE(devopts_cg_analog),
603 sizeof(uint32_t));
604 else
605 return SR_ERR_BUG;
606 break;
607 case SR_CONF_PATTERN_MODE:
608 if (ch->type == SR_CHANNEL_LOGIC)
609 *data = g_variant_new_strv(logic_pattern_str,
610 ARRAY_SIZE(logic_pattern_str));
611 else if (ch->type == SR_CHANNEL_ANALOG)
612 *data = g_variant_new_strv(analog_pattern_str,
613 ARRAY_SIZE(analog_pattern_str));
614 else
615 return SR_ERR_BUG;
616 break;
617 default:
618 return SR_ERR_NA;
619 }
620 }
621
622 return SR_OK;
623}
624
625static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
626{
627 struct dev_context *devc;
628 uint64_t i, j;
629 uint8_t pat;
630
631 devc = sdi->priv;
632
633 switch (devc->logic_pattern) {
634 case PATTERN_SIGROK:
635 memset(devc->logic_data, 0x00, size);
636 for (i = 0; i < size; i += devc->logic_unitsize) {
637 for (j = 0; j < devc->logic_unitsize; j++) {
638 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
639 devc->logic_data[i + j] = ~pat;
640 }
641 devc->step++;
642 }
643 break;
644 case PATTERN_RANDOM:
645 for (i = 0; i < size; i++)
646 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
647 break;
648 case PATTERN_INC:
649 for (i = 0; i < size; i++) {
650 for (j = 0; j < devc->logic_unitsize; j++) {
651 devc->logic_data[i + j] = devc->step;
652 }
653 devc->step++;
654 }
655 break;
656 case PATTERN_ALL_LOW:
657 case PATTERN_ALL_HIGH:
658 /* These were set when the pattern mode was selected. */
659 break;
660 default:
661 sr_err("Unknown pattern: %d.", devc->logic_pattern);
662 break;
663 }
664}
665
666/* Callback handling data */
667static int prepare_data(int fd, int revents, void *cb_data)
668{
669 struct sr_dev_inst *sdi;
670 struct dev_context *devc;
671 struct sr_datafeed_packet packet;
672 struct sr_datafeed_logic logic;
673 struct analog_gen *ag;
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
726 /* FIXME we should make sure we output a whole
727 * period of data before we send out again the
728 * beginning of our buffer. A ring buffer would
729 * help here as well */
730
731 sending_now = MIN(analog_todo, ag->num_samples);
732 ag->packet.num_samples = sending_now;
733 sr_session_send(sdi, &packet);
734
735 /* Whichever channel group gets there first. */
736 analog_sent = MAX(analog_sent, sending_now);
737 }
738 analog_todo -= analog_sent;
739 devc->analog_counter += analog_sent;
740 }
741 }
742
743 if (!devc->continuous
744 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
745 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
746 sr_dbg("Requested number of samples reached.");
747 dev_acquisition_stop(sdi, cb_data);
748 return TRUE;
749 }
750
751 return TRUE;
752}
753
754static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
755{
756 struct dev_context *devc;
757 GHashTableIter iter;
758 void *value;
759
760 (void)cb_data;
761
762 if (sdi->status != SR_ST_ACTIVE)
763 return SR_ERR_DEV_CLOSED;
764
765 devc = sdi->priv;
766 devc->continuous = !devc->limit_samples;
767 devc->logic_counter = devc->analog_counter = 0;
768
769 /*
770 * Setting two channels connected by a pipe is a remnant from when the
771 * demo driver generated data in a thread, and collected and sent the
772 * data in the main program loop.
773 * They are kept here because it provides a convenient way of setting
774 * up a timeout-based polling mechanism.
775 */
776 if (pipe(devc->pipe_fds)) {
777 sr_err("%s: pipe() failed", __func__);
778 return SR_ERR;
779 }
780
781 g_hash_table_iter_init(&iter, devc->ch_ag);
782 while (g_hash_table_iter_next(&iter, NULL, &value))
783 generate_analog_pattern(value, devc->cur_samplerate);
784
785 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
786 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
787
788 /* Set channel encoding to binary (default is UTF-8). */
789 g_io_channel_set_encoding(devc->channel, NULL, NULL);
790
791 /* Make channels unbuffered. */
792 g_io_channel_set_buffered(devc->channel, FALSE);
793
794 sr_session_source_add_channel(sdi->session, devc->channel,
795 G_IO_IN | G_IO_ERR, 40, prepare_data, (void *)sdi);
796
797 /* Send header packet to the session bus. */
798 std_session_send_df_header(sdi, LOG_PREFIX);
799
800 /* We use this timestamp to decide how many more samples to send. */
801 devc->starttime = g_get_monotonic_time();
802
803 return SR_OK;
804}
805
806static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
807{
808 struct dev_context *devc;
809 struct sr_datafeed_packet packet;
810
811 (void)cb_data;
812
813 devc = sdi->priv;
814 sr_dbg("Stopping acquisition.");
815
816 sr_session_source_remove_channel(sdi->session, devc->channel);
817 g_io_channel_shutdown(devc->channel, FALSE, NULL);
818 g_io_channel_unref(devc->channel);
819 devc->channel = NULL;
820
821 /* Send last packet. */
822 packet.type = SR_DF_END;
823 sr_session_send(sdi, &packet);
824
825 return SR_OK;
826}
827
828SR_PRIV struct sr_dev_driver demo_driver_info = {
829 .name = "demo",
830 .longname = "Demo driver and pattern generator",
831 .api_version = 1,
832 .init = init,
833 .cleanup = cleanup,
834 .scan = scan,
835 .dev_list = dev_list,
836 .dev_clear = NULL,
837 .config_get = config_get,
838 .config_set = config_set,
839 .config_list = config_list,
840 .dev_open = dev_open,
841 .dev_close = dev_close,
842 .dev_acquisition_start = dev_acquisition_start,
843 .dev_acquisition_stop = dev_acquisition_stop,
844 .priv = NULL,
845};