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