]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
3d59ae5f7d71357401539a23c5d74ec283d4e8f0
[libsigrok.git] / 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  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <math.h>
27 #ifdef _WIN32
28 #include <io.h>
29 #include <fcntl.h>
30 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
31 #endif
32 #include "libsigrok.h"
33 #include "libsigrok-internal.h"
34
35 #define LOG_PREFIX "demo"
36
37 #define DEFAULT_NUM_LOGIC_PROBES     8
38 #define DEFAULT_NUM_ANALOG_PROBES    4
39
40 /* The size in bytes of chunks to send through the session bus. */
41 #define LOGIC_BUFSIZE        4096
42 /* Size of the analog pattern space per channel. */
43 #define ANALOG_BUFSIZE       4096
44
45 #define ANALOG_AMPLITUDE 25
46 #define ANALOG_SAMPLES_PER_PERIOD 20
47
48 /* Logic patterns we can generate. */
49 enum {
50         /**
51          * Spells "sigrok" across 8 probes using '0's (with '1's as
52          * "background") when displayed using the 'bits' output format.
53          * The pattern is repeasted every 8 probes, shifted to the right
54          * in time by one bit.
55          */
56         PATTERN_SIGROK,
57
58         /** Pseudo-random values on all probes. */
59         PATTERN_RANDOM,
60
61         /**
62          * Incrementing number across 8 probes. The pattern is repeasted
63          * every 8 probes, shifted to the right in time by one bit.
64          */
65         PATTERN_INC,
66
67         /** All probes have a low logic state. */
68         PATTERN_ALL_LOW,
69
70         /** All probes have a high logic state. */
71         PATTERN_ALL_HIGH,
72 };
73
74 /* Analog patterns we can generate. */
75 enum {
76         /**
77          * Square wave.
78          */
79         PATTERN_SQUARE,
80         PATTERN_SINE,
81         PATTERN_TRIANGLE,
82         PATTERN_SAWTOOTH,
83 };
84
85 static const char *logic_pattern_str[] = {
86         "sigrok",
87         "random",
88         "incremental",
89         "all-low",
90         "all-high",
91 };
92
93 static const char *analog_pattern_str[] = {
94         "square",
95         "sine",
96         "triangle",
97         "sawtooth",
98 };
99
100 struct analog_gen {
101         int pattern;
102         float pattern_data[ANALOG_BUFSIZE];
103         unsigned int num_samples;
104         struct sr_datafeed_analog packet;
105 };
106
107 /* Private, per-device-instance driver context. */
108 struct dev_context {
109         int pipe_fds[2];
110         GIOChannel *channel;
111         uint64_t cur_samplerate;
112         uint64_t limit_samples;
113         uint64_t limit_msec;
114         uint64_t logic_counter;
115         uint64_t analog_counter;
116         int64_t starttime;
117         uint64_t step;
118         /* Logic */
119         int32_t num_logic_probes;
120         unsigned int logic_unitsize;
121         /* There is only ever one logic probe group, so its pattern goes here. */
122         uint8_t logic_pattern;
123         unsigned char logic_data[LOGIC_BUFSIZE];
124         /* Analog */
125         int32_t num_analog_probes;
126         GSList *analog_probe_groups;
127 };
128
129 static const int32_t scanopts[] = {
130         SR_CONF_NUM_LOGIC_PROBES,
131         SR_CONF_NUM_ANALOG_PROBES,
132 };
133
134 static const int devopts[] = {
135         SR_CONF_LOGIC_ANALYZER,
136         SR_CONF_DEMO_DEV,
137         SR_CONF_SAMPLERATE,
138         SR_CONF_LIMIT_SAMPLES,
139         SR_CONF_LIMIT_MSEC,
140 };
141
142 static const int devopts_pg[] = {
143         SR_CONF_PATTERN_MODE,
144 };
145
146 static const uint64_t samplerates[] = {
147         SR_HZ(1),
148         SR_GHZ(1),
149         SR_HZ(1),
150 };
151
152 static uint8_t pattern_sigrok[] = {
153         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
154         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
155         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
156         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
157         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
158         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
159         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 };
162
163 SR_PRIV struct sr_dev_driver demo_driver_info;
164 static struct sr_dev_driver *di = &demo_driver_info;
165
166 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
167
168
169 static int dev_clear(void)
170 {
171         return std_dev_clear(di, NULL);
172 }
173
174 static int init(struct sr_context *sr_ctx)
175 {
176         return std_init(sr_ctx, di, LOG_PREFIX);
177 }
178
179 static void generate_analog_pattern(const struct sr_probe_group *probe_group, uint64_t sample_rate)
180 {
181         struct analog_gen *ag;
182         double t, frequency;
183         float value;
184         unsigned int num_samples, i;
185         int last_end;
186
187         ag = probe_group->priv;
188         num_samples = ANALOG_BUFSIZE / sizeof(float);
189
190         sr_dbg("Generating %s pattern for probe group %s",
191                analog_pattern_str[ag->pattern],
192                probe_group->name);
193
194         switch (ag->pattern) {
195         case PATTERN_SQUARE:
196                 value = ANALOG_AMPLITUDE;
197                 last_end = 0;
198                 for (i = 0; i < num_samples; i++) {
199                         if (i % 5 == 0)
200                                 value = -value;
201                         if (i % 10 == 0)
202                                 last_end = i - 1;
203                         ag->pattern_data[i] = value;
204                 }
205                 ag->num_samples = last_end;
206                 break;
207
208         case PATTERN_SINE:
209                 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
210
211                 /* Make sure the number of samples we put out is an integer
212                  * multiple of our period size */
213                 /* FIXME we actually need only one period. A ringbuffer would be
214                  * usefull here.*/
215                 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
216                         num_samples--;
217
218                 for (i = 0; i < num_samples; i++) {
219                         t = (double) i / (double) sample_rate;
220                         ag->pattern_data[i] = ANALOG_AMPLITUDE *
221                                                 sin(2 * M_PI * frequency * t);
222                 }
223
224                 ag->num_samples = num_samples;
225                 break;
226
227         case PATTERN_TRIANGLE:
228                 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
229
230                 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
231                         num_samples--;
232
233                 for (i = 0; i < num_samples; i++) {
234                         t = (double) i / (double) sample_rate;
235                         ag->pattern_data[i] = (2 * ANALOG_AMPLITUDE / M_PI) *
236                                                 asin(sin(2 * M_PI * frequency * t));
237                 }
238
239                 ag->num_samples = num_samples;
240                 break;
241
242         case PATTERN_SAWTOOTH:
243                 frequency = sample_rate / ANALOG_SAMPLES_PER_PERIOD;
244
245                 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
246                         num_samples--;
247
248                 for (i = 0; i < num_samples; i++) {
249                         t = (double) i / (double) sample_rate;
250                         ag->pattern_data[i] = 2 * ANALOG_AMPLITUDE *
251                                                 ((t * frequency) - floor(0.5f + t * frequency));
252                 }
253
254                 ag->num_samples = num_samples;
255                 break;
256         }
257 }
258
259 static GSList *scan(GSList *options)
260 {
261         struct drv_context *drvc;
262         struct dev_context *devc;
263         struct sr_dev_inst *sdi;
264         struct sr_probe *probe;
265         struct sr_probe_group *pg;
266         struct sr_config *src;
267         struct analog_gen *ag;
268         GSList *devices, *l;
269         int num_logic_probes, num_analog_probes, pattern, i;
270         char probe_name[16];
271
272         drvc = di->priv;
273
274         num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
275         num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
276         for (l = options; l; l = l->next) {
277                 src = l->data;
278                 switch (src->key) {
279                 case SR_CONF_NUM_LOGIC_PROBES:
280                         num_logic_probes = g_variant_get_int32(src->data);
281                         break;
282                 case SR_CONF_NUM_ANALOG_PROBES:
283                         num_analog_probes = g_variant_get_int32(src->data);
284                         break;
285                 }
286         }
287
288         devices = NULL;
289         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
290         if (!sdi) {
291                 sr_err("Device instance creation failed.");
292                 return NULL;
293         }
294         sdi->driver = di;
295
296         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
297                 sr_err("Device context malloc failed.");
298                 return NULL;
299         }
300         devc->cur_samplerate = SR_KHZ(200);
301         devc->limit_samples = 0;
302         devc->limit_msec = 0;
303         devc->step = 0;
304         devc->num_logic_probes = num_logic_probes;
305         devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
306         devc->logic_pattern = PATTERN_SIGROK;
307         devc->num_analog_probes = num_analog_probes;
308         devc->analog_probe_groups = NULL;
309
310         /* Logic probes, all in one probe group. */
311         if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
312                 return NULL;
313         pg->name = g_strdup("Logic");
314         pg->probes = NULL;
315         pg->priv = NULL;
316         for (i = 0; i < num_logic_probes; i++) {
317                 sprintf(probe_name, "D%d", i);
318                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
319                         return NULL;
320                 sdi->probes = g_slist_append(sdi->probes, probe);
321                 pg->probes = g_slist_append(pg->probes, probe);
322         }
323         sdi->probe_groups = g_slist_append(NULL, pg);
324
325         /* Analog probes, probe groups and pattern generators. */
326
327         pattern = 0;
328         for (i = 0; i < num_analog_probes; i++) {
329                 sprintf(probe_name, "A%d", i);
330                 if (!(probe = sr_probe_new(i + num_logic_probes,
331                                 SR_PROBE_ANALOG, TRUE, probe_name)))
332                         return NULL;
333                 sdi->probes = g_slist_append(sdi->probes, probe);
334
335                 /* Every analog probe gets its own probe group. */
336                 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
337                         return NULL;
338                 pg->name = g_strdup(probe_name);
339                 pg->probes = g_slist_append(NULL, probe);
340
341                 /* Every probe group gets a generator struct. */
342                 if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
343                         return NULL;
344                 ag->packet.probes = pg->probes;
345                 ag->packet.mq = 0;
346                 ag->packet.mqflags = 0;
347                 ag->packet.unit = SR_UNIT_VOLT;
348                 ag->packet.data = ag->pattern_data;
349                 ag->pattern = pattern;
350                 pg->priv = ag;
351
352                 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
353                 devc->analog_probe_groups = g_slist_append(devc->analog_probe_groups, pg);
354
355                 if (++pattern == ARRAY_SIZE(analog_pattern_str))
356                         pattern = 0;
357         }
358
359         sdi->priv = devc;
360         devices = g_slist_append(devices, sdi);
361         drvc->instances = g_slist_append(drvc->instances, sdi);
362
363         return devices;
364 }
365
366 static GSList *dev_list(void)
367 {
368         return ((struct drv_context *)(di->priv))->instances;
369 }
370
371 static int dev_open(struct sr_dev_inst *sdi)
372 {
373         sdi->status = SR_ST_ACTIVE;
374
375         return SR_OK;
376 }
377
378 static int dev_close(struct sr_dev_inst *sdi)
379 {
380         sdi->status = SR_ST_INACTIVE;
381
382         return SR_OK;
383 }
384
385 static int cleanup(void)
386 {
387         return dev_clear();
388 }
389
390 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
391                 const struct sr_probe_group *probe_group)
392 {
393         struct dev_context *devc;
394         struct sr_probe *probe;
395         struct analog_gen *ag;
396         int pattern;
397
398         if (!sdi)
399                 return SR_ERR_ARG;
400
401         devc = sdi->priv;
402         switch (id) {
403         case SR_CONF_SAMPLERATE:
404                 *data = g_variant_new_uint64(devc->cur_samplerate);
405                 break;
406         case SR_CONF_LIMIT_SAMPLES:
407                 *data = g_variant_new_uint64(devc->limit_samples);
408                 break;
409         case SR_CONF_LIMIT_MSEC:
410                 *data = g_variant_new_uint64(devc->limit_msec);
411                 break;
412         case SR_CONF_PATTERN_MODE:
413                 if (!probe_group)
414                         return SR_ERR_PROBE_GROUP;
415                 probe = probe_group->probes->data;
416                 if (probe->type == SR_PROBE_LOGIC) {
417                         pattern = devc->logic_pattern;
418                         *data = g_variant_new_string(logic_pattern_str[pattern]);
419                 } else if (probe->type == SR_PROBE_ANALOG) {
420                         ag = probe_group->priv;
421                         pattern = ag->pattern;
422                         *data = g_variant_new_string(analog_pattern_str[pattern]);
423                 } else
424                         return SR_ERR_BUG;
425                 break;
426         case SR_CONF_NUM_LOGIC_PROBES:
427                 *data = g_variant_new_int32(devc->num_logic_probes);
428                 break;
429         case SR_CONF_NUM_ANALOG_PROBES:
430                 *data = g_variant_new_int32(devc->num_analog_probes);
431                 break;
432         default:
433                 return SR_ERR_NA;
434         }
435
436         return SR_OK;
437 }
438
439 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
440                 const struct sr_probe_group *probe_group)
441 {
442         struct dev_context *devc;
443         struct analog_gen *ag;
444         struct sr_probe *probe;
445         int pattern, ret;
446         unsigned int i;
447         const char *stropt;
448
449         devc = sdi->priv;
450
451         if (sdi->status != SR_ST_ACTIVE)
452                 return SR_ERR_DEV_CLOSED;
453
454         ret = SR_OK;
455         switch (id) {
456         case SR_CONF_SAMPLERATE:
457                 devc->cur_samplerate = g_variant_get_uint64(data);
458                 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
459                 break;
460         case SR_CONF_LIMIT_SAMPLES:
461                 devc->limit_msec = 0;
462                 devc->limit_samples = g_variant_get_uint64(data);
463                 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
464                 break;
465         case SR_CONF_LIMIT_MSEC:
466                 devc->limit_msec = g_variant_get_uint64(data);
467                 devc->limit_samples = 0;
468                 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
469                 break;
470         case SR_CONF_PATTERN_MODE:
471                 if (!probe_group)
472                         return SR_ERR_PROBE_GROUP;
473                 stropt = g_variant_get_string(data, NULL);
474                 probe = probe_group->probes->data;
475                 pattern = -1;
476                 if (probe->type == SR_PROBE_LOGIC) {
477                         for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
478                                 if (!strcmp(stropt, logic_pattern_str[i])) {
479                                         pattern = i;
480                                         break;
481                                 }
482                         }
483                         if (pattern == -1)
484                                 return SR_ERR_ARG;
485                         devc->logic_pattern = pattern;
486
487                         /* Might as well do this now, these are static. */
488                         if (pattern == PATTERN_ALL_LOW)
489                                 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
490                         else if (pattern == PATTERN_ALL_HIGH)
491                                 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
492                         sr_dbg("Setting logic pattern to %s",
493                                         logic_pattern_str[pattern]);
494                 } else if (probe->type == SR_PROBE_ANALOG) {
495                         for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
496                                 if (!strcmp(stropt, analog_pattern_str[i])) {
497                                         pattern = i;
498                                         break;
499                                 }
500                         }
501                         if (pattern == -1)
502                                 return SR_ERR_ARG;
503                         sr_dbg("Setting analog pattern for probe group %s to %s",
504                                         probe_group->name,
505                                         analog_pattern_str[pattern]);
506                         ag = probe_group->priv;
507                         ag->pattern = pattern;
508                 } else
509                         return SR_ERR_BUG;
510                 break;
511         default:
512                 ret = SR_ERR_NA;
513         }
514
515         return ret;
516 }
517
518 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
519                 const struct sr_probe_group *probe_group)
520 {
521         struct sr_probe *probe;
522         GVariant *gvar;
523         GVariantBuilder gvb;
524
525         (void)sdi;
526
527         if (key == SR_CONF_SCAN_OPTIONS) {
528                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
529                                 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
530                 return SR_OK;
531         }
532
533         if (!sdi)
534                 return SR_ERR_ARG;
535
536         if (!probe_group) {
537                 switch (key) {
538                 case SR_CONF_DEVICE_OPTIONS:
539                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
540                                         devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
541                         break;
542                 case SR_CONF_SAMPLERATE:
543                         g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
544                         gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
545                                         ARRAY_SIZE(samplerates), sizeof(uint64_t));
546                         g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
547                         *data = g_variant_builder_end(&gvb);
548                         break;
549                 default:
550                         return SR_ERR_NA;
551                 }
552         } else {
553                 probe = probe_group->probes->data;
554                 switch (key) {
555                 case SR_CONF_DEVICE_OPTIONS:
556                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
557                                         devopts_pg, ARRAY_SIZE(devopts_pg), sizeof(int32_t));
558                         break;
559                 case SR_CONF_PATTERN_MODE:
560                         if (probe->type == SR_PROBE_LOGIC)
561                                 *data = g_variant_new_strv(logic_pattern_str,
562                                                 ARRAY_SIZE(logic_pattern_str));
563                         else if (probe->type == SR_PROBE_ANALOG)
564                                 *data = g_variant_new_strv(analog_pattern_str,
565                                                 ARRAY_SIZE(analog_pattern_str));
566                         else
567                                 return SR_ERR_BUG;
568                         break;
569                 default:
570                         return SR_ERR_NA;
571                 }
572         }
573
574         return SR_OK;
575 }
576
577 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
578 {
579         struct dev_context *devc;
580         uint64_t i, j;
581         uint8_t pat;
582
583         devc = sdi->priv;
584
585         switch (devc->logic_pattern) {
586         case PATTERN_SIGROK:
587                 memset(devc->logic_data, 0x00, size);
588                 for (i = 0; i < size; i += devc->logic_unitsize) {
589                         for (j = 0; j < devc->logic_unitsize; j++) {
590                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
591                                 devc->logic_data[i + j] = ~pat;
592                         }
593                         devc->step++;
594                 }
595                 break;
596         case PATTERN_RANDOM:
597                 for (i = 0; i < size; i++)
598                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
599                 break;
600         case PATTERN_INC:
601                 for (i = 0; i < size; i++) {
602                         for (j = 0; j < devc->logic_unitsize; j++) {
603                                 devc->logic_data[i + j] = devc->step;
604                         }
605                         devc->step++;
606                 }
607                 break;
608         case PATTERN_ALL_LOW:
609         case PATTERN_ALL_HIGH:
610                 /* These were set when the pattern mode was selected. */
611                 break;
612         default:
613                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
614                 break;
615         }
616 }
617
618 /* Callback handling data */
619 static int prepare_data(int fd, int revents, void *cb_data)
620 {
621         struct sr_dev_inst *sdi;
622         struct dev_context *devc;
623         struct sr_datafeed_packet packet;
624         struct sr_datafeed_logic logic;
625         struct sr_probe_group *pg;
626         struct analog_gen *ag;
627         GSList *l;
628         uint64_t logic_todo, analog_todo, expected_samplenum, analog_samples, sending_now;
629         int64_t time, elapsed;
630
631         (void)fd;
632         (void)revents;
633
634         sdi = cb_data;
635         devc = sdi->priv;
636
637         /* How many "virtual" samples should we have collected by now? */
638         time = g_get_monotonic_time();
639         elapsed = time - devc->starttime;
640         expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
641
642         /* Of those, how many do we still have to send? */
643         logic_todo = MIN(expected_samplenum, devc->limit_samples) - devc->logic_counter;
644         analog_todo = MIN(expected_samplenum, devc->limit_samples) - devc->analog_counter;
645
646         while (logic_todo || analog_todo) {
647                 /* Logic */
648                 if (devc->num_logic_probes > 0 && logic_todo > 0) {
649                         sending_now = MIN(logic_todo,
650                                         LOGIC_BUFSIZE / devc->logic_unitsize);
651                         logic_generator(sdi, sending_now * devc->logic_unitsize);
652                         packet.type = SR_DF_LOGIC;
653                         packet.payload = &logic;
654                         logic.length = sending_now * devc->logic_unitsize;
655                         logic.unitsize = devc->logic_unitsize;
656                         logic.data = devc->logic_data;
657                         sr_session_send(sdi, &packet);
658                         logic_todo -= sending_now;
659                         devc->logic_counter += sending_now;
660                 }
661
662                 /* Analog, one probe at a time */
663                 if (devc->num_analog_probes > 0 && analog_todo > 0) {
664                         sending_now = 0;
665                         for (l = devc->analog_probe_groups; l; l = l->next) {
666                                 pg = l->data;
667                                 ag = pg->priv;
668                                 packet.type = SR_DF_ANALOG;
669                                 packet.payload = &ag->packet;
670
671                                 /* FIXME we should make sure we output a whole
672                                  * period of data before we send out again the
673                                  * beginning of our buffer. A ring buffer would
674                                  * help here as well */
675
676                                 analog_samples = MIN(analog_todo, ag->num_samples);
677                                 /* Whichever probe group gets there first. */
678                                 sending_now = MAX(sending_now, analog_samples);
679                                 ag->packet.num_samples = analog_samples;
680                                 sr_session_send(sdi, &packet);
681                         }
682                         analog_todo -= sending_now;
683                         devc->analog_counter += sending_now;
684                 }
685         }
686
687         if (devc->logic_counter >= devc->limit_samples &&
688                         devc->analog_counter >= devc->limit_samples) {
689                 sr_dbg("Requested number of samples reached.");
690                 dev_acquisition_stop(sdi, cb_data);
691                 return TRUE;
692         }
693
694         return TRUE;
695 }
696
697 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
698 {
699         GSList *l;
700         struct dev_context *devc;
701
702         if (sdi->status != SR_ST_ACTIVE)
703                 return SR_ERR_DEV_CLOSED;
704
705         devc = sdi->priv;
706         if (devc->limit_samples == 0)
707                 return SR_ERR;
708         devc->logic_counter = devc->analog_counter = 0;
709
710         /*
711          * Setting two channels connected by a pipe is a remnant from when the
712          * demo driver generated data in a thread, and collected and sent the
713          * data in the main program loop.
714          * They are kept here because it provides a convenient way of setting
715          * up a timeout-based polling mechanism.
716          */
717         if (pipe(devc->pipe_fds)) {
718                 sr_err("%s: pipe() failed", __func__);
719                 return SR_ERR;
720         }
721
722         for (l = devc->analog_probe_groups; l; l = l->next) {
723                 generate_analog_pattern(l->data, devc->cur_samplerate);
724         }
725
726         devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
727
728         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
729
730         /* Set channel encoding to binary (default is UTF-8). */
731         g_io_channel_set_encoding(devc->channel, NULL, NULL);
732
733         /* Make channels to unbuffered. */
734         g_io_channel_set_buffered(devc->channel, FALSE);
735
736         sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
737                         40, prepare_data, (void *)sdi);
738
739         /* Send header packet to the session bus. */
740         std_session_send_df_header(cb_data, LOG_PREFIX);
741
742         /* We use this timestamp to decide how many more samples to send. */
743         devc->starttime = g_get_monotonic_time();
744
745         return SR_OK;
746 }
747
748 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
749 {
750         struct dev_context *devc;
751         struct sr_datafeed_packet packet;
752
753         (void)cb_data;
754
755         devc = sdi->priv;
756         sr_dbg("Stopping aquisition.");
757
758         sr_session_source_remove_channel(devc->channel);
759         g_io_channel_shutdown(devc->channel, FALSE, NULL);
760         g_io_channel_unref(devc->channel);
761         devc->channel = NULL;
762
763         /* Send last packet. */
764         packet.type = SR_DF_END;
765         sr_session_send(sdi, &packet);
766
767         return SR_OK;
768 }
769
770 SR_PRIV struct sr_dev_driver demo_driver_info = {
771         .name = "demo",
772         .longname = "Demo driver and pattern generator",
773         .api_version = 1,
774         .init = init,
775         .cleanup = cleanup,
776         .scan = scan,
777         .dev_list = dev_list,
778         .dev_clear = dev_clear,
779         .config_get = config_get,
780         .config_set = config_set,
781         .config_list = config_list,
782         .dev_open = dev_open,
783         .dev_close = dev_close,
784         .dev_acquisition_start = dev_acquisition_start,
785         .dev_acquisition_stop = dev_acquisition_stop,
786         .priv = NULL,
787 };