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