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