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