]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/demo/demo.c
Removal of sdi->index, step 3: sr_dev_inst_new() calls for input mods
[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 int devopts[] = {
137 SR_CONF_LOGIC_ANALYZER,
138 SR_CONF_CONTINUOUS,
139 SR_CONF_DEMO_DEV,
140 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
141 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
142 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
143 SR_CONF_NUM_LOGIC_CHANNELS | SR_CONF_GET,
144 SR_CONF_NUM_ANALOG_CHANNELS | SR_CONF_GET,
145};
146
147static const int devopts_cg_logic[] = {
148 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
149};
150
151static const int devopts_cg_analog[] = {
152 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
153 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
154};
155
156static const uint64_t samplerates[] = {
157 SR_HZ(1),
158 SR_GHZ(1),
159 SR_HZ(1),
160};
161
162static uint8_t pattern_sigrok[] = {
163 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
164 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
165 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
166 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
167 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
168 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171};
172
173SR_PRIV struct sr_dev_driver demo_driver_info;
174static struct sr_dev_driver *di = &demo_driver_info;
175
176static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
177
178
179static int init(struct sr_context *sr_ctx)
180{
181 return std_init(sr_ctx, di, LOG_PREFIX);
182}
183
184static void generate_analog_pattern(struct analog_gen *ag, uint64_t sample_rate)
185{
186 double t, frequency;
187 float value;
188 unsigned int num_samples, i;
189 int last_end;
190
191 sr_dbg("Generating %s pattern.", analog_pattern_str[ag->pattern]);
192
193 num_samples = ANALOG_BUFSIZE / sizeof(float);
194
195 switch (ag->pattern) {
196 case PATTERN_SQUARE:
197 value = ag->amplitude;
198 last_end = 0;
199 for (i = 0; i < num_samples; i++) {
200 if (i % 5 == 0)
201 value = -value;
202 if (i % 10 == 0)
203 last_end = i - 1;
204 ag->pattern_data[i] = value;
205 }
206 ag->num_samples = last_end;
207 break;
208
209 case PATTERN_SINE:
210 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
211
212 /* Make sure the number of samples we put out is an integer
213 * multiple of our period size */
214 /* FIXME we actually need only one period. A ringbuffer would be
215 * usefull here.*/
216 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
217 num_samples--;
218
219 for (i = 0; i < num_samples; i++) {
220 t = (double) i / (double) sample_rate;
221 ag->pattern_data[i] = ag->amplitude *
222 sin(2 * M_PI * frequency * t);
223 }
224
225 ag->num_samples = num_samples;
226 break;
227
228 case PATTERN_TRIANGLE:
229 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
230
231 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
232 num_samples--;
233
234 for (i = 0; i < num_samples; i++) {
235 t = (double) i / (double) sample_rate;
236 ag->pattern_data[i] = (2 * ag->amplitude / M_PI) *
237 asin(sin(2 * M_PI * frequency * t));
238 }
239
240 ag->num_samples = num_samples;
241 break;
242
243 case PATTERN_SAWTOOTH:
244 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
245
246 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
247 num_samples--;
248
249 for (i = 0; i < num_samples; i++) {
250 t = (double) i / (double) sample_rate;
251 ag->pattern_data[i] = 2 * ag->amplitude *
252 ((t * frequency) - floor(0.5f + t * frequency));
253 }
254
255 ag->num_samples = num_samples;
256 break;
257 }
258}
259
260static GSList *scan(GSList *options)
261{
262 struct drv_context *drvc;
263 struct dev_context *devc;
264 struct sr_dev_inst *sdi;
265 struct sr_channel *ch;
266 struct sr_channel_group *cg, *acg;
267 struct sr_config *src;
268 struct analog_gen *ag;
269 GSList *devices, *l;
270 int num_logic_channels, num_analog_channels, pattern, i;
271 char channel_name[16];
272
273 drvc = di->priv;
274
275 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
276 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
277 for (l = options; l; l = l->next) {
278 src = l->data;
279 switch (src->key) {
280 case SR_CONF_NUM_LOGIC_CHANNELS:
281 num_logic_channels = g_variant_get_int32(src->data);
282 break;
283 case SR_CONF_NUM_ANALOG_CHANNELS:
284 num_analog_channels = g_variant_get_int32(src->data);
285 break;
286 }
287 }
288
289 devices = NULL;
290 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
291 if (!sdi) {
292 sr_err("Device instance creation failed.");
293 return NULL;
294 }
295 sdi->driver = di;
296
297 devc = g_malloc(sizeof(struct dev_context));
298 devc->cur_samplerate = SR_KHZ(200);
299 devc->limit_samples = 0;
300 devc->limit_msec = 0;
301 devc->step = 0;
302 devc->continuous = FALSE;
303 devc->num_logic_channels = num_logic_channels;
304 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
305 devc->logic_pattern = PATTERN_SIGROK;
306 devc->num_analog_channels = num_analog_channels;
307
308 /* Logic channels, all in one channel group. */
309 cg = g_malloc0(sizeof(struct sr_channel_group));
310 cg->name = g_strdup("Logic");
311 for (i = 0; i < num_logic_channels; i++) {
312 sprintf(channel_name, "D%d", i);
313 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name)))
314 return NULL;
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_NUM_LOGIC_CHANNELS:
441 *data = g_variant_new_int32(devc->num_logic_channels);
442 break;
443 case SR_CONF_NUM_ANALOG_CHANNELS:
444 *data = g_variant_new_int32(devc->num_analog_channels);
445 break;
446 case SR_CONF_AMPLITUDE:
447 if (!cg)
448 return SR_ERR_CHANNEL_GROUP;
449 /* Any channel in the group will do. */
450 ch = cg->channels->data;
451 if (ch->type != SR_CHANNEL_ANALOG)
452 return SR_ERR_ARG;
453 ag = g_hash_table_lookup(devc->ch_ag, ch);
454 *data = g_variant_new_double(ag->amplitude);
455 break;
456 default:
457 return SR_ERR_NA;
458 }
459
460 return SR_OK;
461}
462
463static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
464 const struct sr_channel_group *cg)
465{
466 struct dev_context *devc;
467 struct analog_gen *ag;
468 struct sr_channel *ch;
469 GSList *l;
470 int logic_pattern, analog_pattern, ret;
471 unsigned int i;
472 const char *stropt;
473
474 devc = sdi->priv;
475
476 if (sdi->status != SR_ST_ACTIVE)
477 return SR_ERR_DEV_CLOSED;
478
479 ret = SR_OK;
480 switch (key) {
481 case SR_CONF_SAMPLERATE:
482 devc->cur_samplerate = g_variant_get_uint64(data);
483 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
484 break;
485 case SR_CONF_LIMIT_SAMPLES:
486 devc->limit_msec = 0;
487 devc->limit_samples = g_variant_get_uint64(data);
488 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
489 break;
490 case SR_CONF_LIMIT_MSEC:
491 devc->limit_msec = g_variant_get_uint64(data);
492 devc->limit_samples = 0;
493 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
494 break;
495 case SR_CONF_PATTERN_MODE:
496 if (!cg)
497 return SR_ERR_CHANNEL_GROUP;
498 stropt = g_variant_get_string(data, NULL);
499 ch = cg->channels->data;
500 logic_pattern = analog_pattern = -1;
501 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
502 if (!strcmp(stropt, logic_pattern_str[i])) {
503 logic_pattern = i;
504 break;
505 }
506 }
507 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
508 if (!strcmp(stropt, analog_pattern_str[i])) {
509 analog_pattern = i;
510 break;
511 }
512 }
513 if (logic_pattern == -1 && analog_pattern == -1)
514 return SR_ERR_ARG;
515 for (l = cg->channels; l; l = l->next) {
516 ch = l->data;
517 if (ch->type == SR_CHANNEL_LOGIC) {
518 if (logic_pattern == -1)
519 return SR_ERR_ARG;
520 sr_dbg("Setting logic pattern to %s",
521 logic_pattern_str[logic_pattern]);
522 devc->logic_pattern = logic_pattern;
523 /* Might as well do this now, these are static. */
524 if (logic_pattern == PATTERN_ALL_LOW)
525 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
526 else if (logic_pattern == PATTERN_ALL_HIGH)
527 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
528 } else if (ch->type == SR_CHANNEL_ANALOG) {
529 if (analog_pattern == -1)
530 return SR_ERR_ARG;
531 sr_dbg("Setting analog pattern for channel %s to %s",
532 ch->name, analog_pattern_str[analog_pattern]);
533 ag = g_hash_table_lookup(devc->ch_ag, ch);
534 ag->pattern = analog_pattern;
535 } else
536 return SR_ERR_BUG;
537 }
538 break;
539 case SR_CONF_AMPLITUDE:
540 if (!cg)
541 return SR_ERR_CHANNEL_GROUP;
542 for (l = cg->channels; l; l = l->next) {
543 ch = l->data;
544 if (ch->type != SR_CHANNEL_ANALOG)
545 return SR_ERR_ARG;
546 ag = g_hash_table_lookup(devc->ch_ag, ch);
547 ag->amplitude = g_variant_get_double(data);
548 }
549 break;
550 default:
551 ret = SR_ERR_NA;
552 }
553
554 return ret;
555}
556
557static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
558 const struct sr_channel_group *cg)
559{
560 struct sr_channel *ch;
561 GVariant *gvar;
562 GVariantBuilder gvb;
563
564 (void)sdi;
565
566 if (key == SR_CONF_SCAN_OPTIONS) {
567 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
568 scanopts, ARRAY_SIZE(scanopts), 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, ARRAY_SIZE(devopts), 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};