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