]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
demo: Analog probe support.
[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 #ifdef _WIN32
27 #include <io.h>
28 #include <fcntl.h>
29 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
30 #endif
31 #include "libsigrok.h"
32 #include "libsigrok-internal.h"
33
34 #define LOG_PREFIX "demo"
35
36 #define DEFAULT_NUM_LOGIC_PROBES     8
37 #define DEFAULT_NUM_ANALOG_PROBES    4
38
39 /* The size in bytes of chunks to send through the session bus. */
40 #define LOGIC_BUFSIZE        4096
41 /* Size of the analog pattern space per channel. */
42 #define ANALOG_BUFSIZE       4096
43
44 /* Patterns we can generate */
45 enum {
46         /* Logic */
47         /**
48          * Spells "sigrok" across 8 probes using '0's (with '1's as
49          * "background") when displayed using the 'bits' output format.
50          * The pattern is repeasted every 8 probes, shifted to the right
51          * in time by one bit.
52          */
53         PATTERN_SIGROK,
54
55         /** Pseudo-random values on all probes. */
56         PATTERN_RANDOM,
57
58         /**
59          * Incrementing number across 8 probes. The pattern is repeasted
60          * every 8 probes, shifted to the right in time by one bit.
61          */
62         PATTERN_INC,
63
64         /** All probes have a low logic state. */
65         PATTERN_ALL_LOW,
66
67         /** All probes have a high logic state. */
68         PATTERN_ALL_HIGH,
69
70         /* Analog */
71         /**
72          * Square wave.
73          */
74         PATTERN_SQUARE,
75 };
76
77 static const char *logic_pattern_str[] = {
78         "sigrok",
79         "random",
80         "incremental",
81         "all-low",
82         "all-high",
83 };
84
85 static const char *analog_pattern_str[] = {
86         "square",
87 };
88
89 struct analog_gen {
90         int pattern;
91         float pattern_data[ANALOG_BUFSIZE];
92         unsigned int num_samples;
93         struct sr_datafeed_analog packet;
94 };
95
96 /* Private, per-device-instance driver context. */
97 struct dev_context {
98         int pipe_fds[2];
99         GIOChannel *channel;
100         uint64_t cur_samplerate;
101         uint64_t limit_samples;
102         uint64_t limit_msec;
103         uint64_t samples_counter;
104         int64_t starttime;
105         uint64_t step;
106         /* Logic */
107         int32_t num_logic_probes;
108         unsigned int logic_unitsize;
109         uint8_t logic_pattern;
110         unsigned char logic_data[LOGIC_BUFSIZE];
111         /* Analog */
112         int32_t num_analog_probes;
113         GSList *analog_probe_groups;
114 };
115
116 static const int32_t hwopts[] = {
117         SR_CONF_NUM_LOGIC_PROBES,
118         SR_CONF_NUM_ANALOG_PROBES,
119 };
120
121 static const int hwcaps[] = {
122         SR_CONF_LOGIC_ANALYZER,
123         SR_CONF_DEMO_DEV,
124         SR_CONF_SAMPLERATE,
125         SR_CONF_PATTERN_MODE,
126         SR_CONF_LIMIT_SAMPLES,
127         SR_CONF_LIMIT_MSEC,
128 };
129
130 static const uint64_t samplerates[] = {
131         SR_HZ(1),
132         SR_GHZ(1),
133         SR_HZ(1),
134 };
135
136 static uint8_t pattern_sigrok[] = {
137         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
138         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
139         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
140         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
141         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
142         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 };
146
147 SR_PRIV struct sr_dev_driver demo_driver_info;
148 static struct sr_dev_driver *di = &demo_driver_info;
149
150 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
151
152
153 static int dev_clear(void)
154 {
155         return std_dev_clear(di, NULL);
156 }
157
158 static int init(struct sr_context *sr_ctx)
159 {
160         return std_init(sr_ctx, di, LOG_PREFIX);
161 }
162
163 static void set_analog_pattern(const struct sr_probe_group *probe_group, int pattern)
164 {
165         struct analog_gen *ag;
166         float value;
167         unsigned int num_samples, i;
168         int last_end;
169
170         ag = probe_group->priv;
171         ag->pattern = pattern;
172
173         switch (pattern) {
174         case PATTERN_SQUARE:
175                 num_samples = ANALOG_BUFSIZE / sizeof(float);
176                 value = 5.0;
177                 last_end = 0;
178                 for (i = 0; i < num_samples; i++) {
179                         if (i % 5 == 0)
180                                 value = -value;
181                         if (i % 10 == 0)
182                                 last_end = i - 1;
183                         ag->pattern_data[i] = value;
184                 }
185                 ag->num_samples = last_end;
186                 break;
187         }
188 }
189
190 static GSList *scan(GSList *options)
191 {
192         struct drv_context *drvc;
193         struct dev_context *devc;
194         struct sr_dev_inst *sdi;
195         struct sr_probe *probe;
196         struct sr_probe_group *pg;
197         struct sr_config *src;
198         struct analog_gen *ag;
199         GSList *devices, *l;
200         int num_logic_probes, num_analog_probes, i;
201         char probe_name[16];
202
203         drvc = di->priv;
204
205         num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
206         num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
207         for (l = options; l; l = l->next) {
208                 src = l->data;
209                 switch (src->key) {
210                 case SR_CONF_NUM_LOGIC_PROBES:
211                         num_logic_probes = g_variant_get_int32(src->data);
212                         break;
213                 case SR_CONF_NUM_ANALOG_PROBES:
214                         num_analog_probes = g_variant_get_int32(src->data);
215                         break;
216                 }
217         }
218
219         devices = NULL;
220         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
221         if (!sdi) {
222                 sr_err("Device instance creation failed.");
223                 return NULL;
224         }
225         sdi->driver = di;
226
227         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
228                 sr_err("Device context malloc failed.");
229                 return NULL;
230         }
231         devc->cur_samplerate = SR_KHZ(200);
232         devc->limit_samples = 0;
233         devc->limit_msec = 0;
234         devc->step = 0;
235         devc->num_logic_probes = num_logic_probes;
236         devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
237         devc->logic_pattern = PATTERN_SIGROK;
238         devc->num_analog_probes = num_analog_probes;
239         devc->analog_probe_groups = NULL;
240
241         /* Logic probes, all in one probe group. */
242         if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
243                 return NULL;
244         pg->name = g_strdup("Logic");
245         pg->probes = NULL;
246         pg->priv = NULL;
247         for (i = 0; i < num_logic_probes; i++) {
248                 sprintf(probe_name, "D%d", i);
249                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
250                         return NULL;
251                 sdi->probes = g_slist_append(sdi->probes, probe);
252                 pg->probes = g_slist_append(pg->probes, probe);
253         }
254         sdi->probe_groups = g_slist_append(NULL, pg);
255
256         /* Analog probes, probe groups and pattern generators. */
257         for (i = 0; i < num_analog_probes; i++) {
258                 sprintf(probe_name, "A%d", i);
259                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_name)))
260                         return NULL;
261                 sdi->probes = g_slist_append(sdi->probes, probe);
262
263                 /* Every analog probe gets its own probe group. */
264                 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
265                         return NULL;
266                 pg->name = g_strdup(probe_name);
267                 pg->probes = g_slist_append(NULL, probe);
268
269                 /* Every probe group gets a generator struct. */
270                 if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
271                         return NULL;
272                 ag->packet.probes = pg->probes;
273                 ag->packet.mq = 0;
274                 ag->packet.mqflags = 0;
275                 ag->packet.unit = SR_UNIT_VOLT;
276                 ag->packet.data = ag->pattern_data;
277                 pg->priv = ag;
278                 set_analog_pattern(pg, PATTERN_SQUARE);
279
280                 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
281                 devc->analog_probe_groups = g_slist_append(devc->analog_probe_groups, pg);
282         }
283
284         sdi->priv = devc;
285         devices = g_slist_append(devices, sdi);
286         drvc->instances = g_slist_append(drvc->instances, sdi);
287
288         return devices;
289 }
290
291 static GSList *dev_list(void)
292 {
293         return ((struct drv_context *)(di->priv))->instances;
294 }
295
296 static int dev_open(struct sr_dev_inst *sdi)
297 {
298         sdi->status = SR_ST_ACTIVE;
299
300         return SR_OK;
301 }
302
303 static int dev_close(struct sr_dev_inst *sdi)
304 {
305         sdi->status = SR_ST_INACTIVE;
306
307         return SR_OK;
308 }
309
310 static int cleanup(void)
311 {
312         return dev_clear();
313 }
314
315 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
316                 const struct sr_probe_group *probe_group)
317 {
318         struct dev_context *devc;
319
320         (void)probe_group;
321
322         devc = sdi->priv;
323         switch (id) {
324         case SR_CONF_SAMPLERATE:
325                 *data = g_variant_new_uint64(devc->cur_samplerate);
326                 break;
327         case SR_CONF_LIMIT_SAMPLES:
328                 *data = g_variant_new_uint64(devc->limit_samples);
329                 break;
330         case SR_CONF_LIMIT_MSEC:
331                 *data = g_variant_new_uint64(devc->limit_msec);
332                 break;
333         case SR_CONF_PATTERN_MODE:
334                 *data = g_variant_new_string(logic_pattern_str[devc->logic_pattern]);
335                 break;
336         case SR_CONF_NUM_LOGIC_PROBES:
337                 *data = g_variant_new_int32(devc->num_logic_probes);
338                 break;
339         case SR_CONF_NUM_ANALOG_PROBES:
340                 *data = g_variant_new_int32(devc->num_analog_probes);
341                 break;
342         default:
343                 return SR_ERR_NA;
344         }
345
346         return SR_OK;
347 }
348
349 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
350                 const struct sr_probe_group *probe_group)
351 {
352         struct dev_context *devc;
353         struct sr_probe_group *pg;
354         GSList *l;
355         int logic_pattern, analog_pattern, ret;
356         unsigned int i;
357         const char *stropt;
358
359         devc = sdi->priv;
360
361         if (sdi->status != SR_ST_ACTIVE)
362                 return SR_ERR_DEV_CLOSED;
363
364         ret = SR_ERR;
365         if (id == SR_CONF_SAMPLERATE) {
366                 devc->cur_samplerate = g_variant_get_uint64(data);
367                 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
368                 ret = SR_OK;
369         } else if (id == SR_CONF_LIMIT_SAMPLES) {
370                 devc->limit_msec = 0;
371                 devc->limit_samples = g_variant_get_uint64(data);
372                 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
373                 ret = SR_OK;
374         } else if (id == SR_CONF_LIMIT_MSEC) {
375                 /* TODO: convert to limit_samples */
376                 devc->limit_msec = g_variant_get_uint64(data);
377                 devc->limit_samples = 0;
378                 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
379                 ret = SR_OK;
380         } else if (id == SR_CONF_PATTERN_MODE) {
381                 stropt = g_variant_get_string(data, NULL);
382                 logic_pattern = analog_pattern = -1;
383                 /* Is it a logic pattern? */
384                 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
385                         if (!strcmp(stropt, logic_pattern_str[i])) {
386                                 logic_pattern = i;
387                                 break;
388                         }
389                 }
390                 if (logic_pattern == -1) {
391                         /* Is it an analog pattern? */
392                         for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
393                                 if (!strcmp(stropt, analog_pattern_str[i])) {
394                                         analog_pattern = i;
395                                         break;
396                                 }
397                         }
398                 }
399                 if (logic_pattern > -1) {
400                         devc->logic_pattern = logic_pattern;
401                         /* Might as well do this now. */
402                         if (logic_pattern == PATTERN_ALL_LOW)
403                                 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
404                         else if (logic_pattern == PATTERN_ALL_HIGH)
405                                 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
406                         ret = SR_OK;
407                         sr_dbg("Setting logic pattern to %s", logic_pattern_str[logic_pattern]);
408                 } else if (analog_pattern > -1) {
409                         sr_dbg("Setting analog pattern to %s", analog_pattern_str[analog_pattern]);
410                         if (probe_group)
411                                 set_analog_pattern(probe_group, analog_pattern);
412                         else {
413                                 /* No probe group specified, apply pattern to all of them. */
414                                 for (l = sdi->probe_groups; l; l = l->next) {
415                                         pg = l->data;
416                                         set_analog_pattern(pg, analog_pattern);
417                                 }
418                                 ret = SR_OK;
419                         }
420                 } else {
421                         ret = SR_ERR;
422                 }
423         } else {
424                 ret = SR_ERR_NA;
425         }
426
427         return ret;
428 }
429
430 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
431                 const struct sr_probe_group *probe_group)
432 {
433         GVariant *gvar;
434         GVariantBuilder gvb;
435
436         (void)sdi;
437         (void)probe_group;
438
439         switch (key) {
440         case SR_CONF_SCAN_OPTIONS:
441                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
442                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
443                 break;
444         case SR_CONF_DEVICE_OPTIONS:
445                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
446                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
447                 break;
448         case SR_CONF_SAMPLERATE:
449                 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
450                 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
451                                 ARRAY_SIZE(samplerates), sizeof(uint64_t));
452                 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
453                 *data = g_variant_builder_end(&gvb);
454                 break;
455         case SR_CONF_PATTERN_MODE:
456                 *data = g_variant_new_strv(logic_pattern_str, ARRAY_SIZE(logic_pattern_str));
457                 break;
458         default:
459                 return SR_ERR_NA;
460         }
461
462         return SR_OK;
463 }
464
465 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
466 {
467         struct dev_context *devc;
468         uint64_t i, j;
469         uint8_t pat;
470
471         devc = sdi->priv;
472
473         switch (devc->logic_pattern) {
474         case PATTERN_SIGROK:
475                 memset(devc->logic_data, 0x00, size);
476                 for (i = 0; i < size; i += devc->logic_unitsize) {
477                         for (j = 0; j < devc->logic_unitsize; j++) {
478                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
479                                 devc->logic_data[i + j] = ~pat;
480                         }
481                         devc->step++;
482                 }
483                 break;
484         case PATTERN_RANDOM:
485                 for (i = 0; i < size; i++)
486                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
487                 break;
488         case PATTERN_INC:
489                 for (i = 0; i < size; i++) {
490                         for (j = 0; j < devc->logic_unitsize; j++) {
491                                 devc->logic_data[i + j] = devc->step;
492                         }
493                         devc->step++;
494                 }
495                 break;
496         case PATTERN_ALL_LOW:
497         case PATTERN_ALL_HIGH:
498                 /* These were set when the pattern mode was selected. */
499                 break;
500         default:
501                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
502                 break;
503         }
504 }
505
506 /* Callback handling data */
507 static int prepare_data(int fd, int revents, void *cb_data)
508 {
509         struct sr_dev_inst *sdi;
510         struct dev_context *devc;
511         struct sr_datafeed_packet packet;
512         struct sr_datafeed_logic logic;
513         struct sr_probe_group *pg;
514         struct analog_gen *ag;
515         GSList *l;
516         uint64_t samples_to_send, expected_samplenum, analog_samples, sending_now;
517         int64_t time, elapsed;
518
519         (void)fd;
520         (void)revents;
521
522         sdi = cb_data;
523         devc = sdi->priv;
524
525         /* How many "virtual" samples should we have collected by now? */
526         time = g_get_monotonic_time();
527         elapsed = time - devc->starttime;
528         expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
529         /* Of those, how many do we still have to send? */
530         samples_to_send = expected_samplenum - devc->samples_counter;
531
532         if (devc->limit_samples) {
533                 samples_to_send = MIN(samples_to_send,
534                                 devc->limit_samples - devc->samples_counter);
535         }
536
537         while (samples_to_send > 0) {
538                 sending_now = 0;
539
540                 /* Logic */
541                 if (devc->num_logic_probes > 0) {
542                         sending_now = MIN(samples_to_send,
543                                         LOGIC_BUFSIZE / devc->logic_unitsize);
544                         logic_generator(sdi, sending_now * devc->logic_unitsize);
545                         packet.type = SR_DF_LOGIC;
546                         packet.payload = &logic;
547                         logic.length = sending_now * devc->logic_unitsize;
548                         logic.unitsize = devc->logic_unitsize;
549                         logic.data = devc->logic_data;
550                         sr_session_send(sdi, &packet);
551                 }
552
553                 /* Analog, one probe at a time */
554                 if (devc->num_analog_probes > 0) {
555                         sending_now = 0;
556                         for (l = devc->analog_probe_groups; l; l = l->next) {
557                                 pg = l->data;
558                                 ag = pg->priv;
559                                 packet.type = SR_DF_ANALOG;
560                                 packet.payload = &ag->packet;
561                                 analog_samples = MIN(samples_to_send, ag->num_samples);
562                                 /* Whichever probe group gets there first. */
563                                 sending_now = MAX(sending_now, analog_samples);
564                                 ag->packet.num_samples = analog_samples;
565                                 sr_session_send(sdi, &packet);
566                         }
567                 }
568
569                 samples_to_send -= sending_now;
570                 devc->samples_counter += sending_now;
571         }
572
573         if (devc->limit_samples &&
574                 devc->samples_counter >= devc->limit_samples) {
575                 sr_info("Requested number of samples reached.");
576                 dev_acquisition_stop(sdi, cb_data);
577                 return TRUE;
578         }
579
580         return TRUE;
581 }
582
583 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
584 {
585         struct dev_context *devc;
586
587         if (sdi->status != SR_ST_ACTIVE)
588                 return SR_ERR_DEV_CLOSED;
589
590         /* TODO: don't start without a sample limit set */
591         devc = sdi->priv;
592         devc->samples_counter = 0;
593
594         /*
595          * Setting two channels connected by a pipe is a remnant from when the
596          * demo driver generated data in a thread, and collected and sent the
597          * data in the main program loop.
598          * They are kept here because it provides a convenient way of setting
599          * up a timeout-based polling mechanism.
600          */
601         if (pipe(devc->pipe_fds)) {
602                 sr_err("%s: pipe() failed", __func__);
603                 return SR_ERR;
604         }
605
606         devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
607
608         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
609
610         /* Set channel encoding to binary (default is UTF-8). */
611         g_io_channel_set_encoding(devc->channel, NULL, NULL);
612
613         /* Make channels to unbuffered. */
614         g_io_channel_set_buffered(devc->channel, FALSE);
615
616         sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
617                         40, prepare_data, (void *)sdi);
618
619         /* Send header packet to the session bus. */
620         std_session_send_df_header(cb_data, LOG_PREFIX);
621
622         /* We use this timestamp to decide how many more samples to send. */
623         devc->starttime = g_get_monotonic_time();
624
625         return SR_OK;
626 }
627
628 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
629 {
630         struct dev_context *devc;
631         struct sr_datafeed_packet packet;
632
633         (void)cb_data;
634
635         devc = sdi->priv;
636         sr_dbg("Stopping aquisition.");
637
638         sr_session_source_remove_channel(devc->channel);
639         g_io_channel_shutdown(devc->channel, FALSE, NULL);
640         g_io_channel_unref(devc->channel);
641         devc->channel = NULL;
642
643         /* Send last packet. */
644         packet.type = SR_DF_END;
645         sr_session_send(sdi, &packet);
646
647         return SR_OK;
648 }
649
650 SR_PRIV struct sr_dev_driver demo_driver_info = {
651         .name = "demo",
652         .longname = "Demo driver and pattern generator",
653         .api_version = 1,
654         .init = init,
655         .cleanup = cleanup,
656         .scan = scan,
657         .dev_list = dev_list,
658         .dev_clear = dev_clear,
659         .config_get = config_get,
660         .config_set = config_set,
661         .config_list = config_list,
662         .dev_open = dev_open,
663         .dev_close = dev_close,
664         .dev_acquisition_start = dev_acquisition_start,
665         .dev_acquisition_stop = dev_acquisition_stop,
666         .priv = NULL,
667 };