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