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