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