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