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