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