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