]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
demo: User-configurable number of probes.
[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 of chunks to send through the session bus. */
40 #define LOGIC_BUFSIZE        4096
41
42 /* Patterns we can generate */
43 enum {
44         /**
45          * Spells "sigrok" across 8 probes using '0's (with '1's as
46          * "background") when displayed using the 'bits' output format.
47          * The pattern is repeasted every 8 probes, shifted to the right
48          * in time by one bit.
49          */
50         PATTERN_SIGROK,
51
52         /** Pseudo-random values on all probes. */
53         PATTERN_RANDOM,
54
55         /**
56          * Incrementing number across 8 probes. The pattern is repeasted
57          * every 8 probes, shifted to the right in time by one bit.
58          */
59         PATTERN_INC,
60
61         /** All probes have a low logic state. */
62         PATTERN_ALL_LOW,
63
64         /** All probes have a high logic state. */
65         PATTERN_ALL_HIGH,
66 };
67
68 static const char *pattern_strings[] = {
69         "sigrok",
70         "random",
71         "incremental",
72         "all-low",
73         "all-high",
74 };
75
76 /* Private, per-device-instance driver context. */
77 struct dev_context {
78         int pipe_fds[2];
79         GIOChannel *channel;
80         uint64_t cur_samplerate;
81         uint64_t limit_samples;
82         uint64_t limit_msec;
83         uint64_t samples_counter;
84         int64_t starttime;
85         uint64_t step;
86         int32_t num_logic_probes;
87         unsigned int logic_unitsize;
88         uint8_t logic_pattern;
89         unsigned char logic_data[LOGIC_BUFSIZE];
90         int32_t num_analog_probes;
91 };
92
93 static const int32_t hwopts[] = {
94         SR_CONF_NUM_LOGIC_PROBES,
95         SR_CONF_NUM_ANALOG_PROBES,
96 };
97
98 static const int hwcaps[] = {
99         SR_CONF_LOGIC_ANALYZER,
100         SR_CONF_DEMO_DEV,
101         SR_CONF_SAMPLERATE,
102         SR_CONF_PATTERN_MODE,
103         SR_CONF_LIMIT_SAMPLES,
104         SR_CONF_LIMIT_MSEC,
105         SR_CONF_CONTINUOUS,
106 };
107
108 static const uint64_t samplerates[] = {
109         SR_HZ(1),
110         SR_GHZ(1),
111         SR_HZ(1),
112 };
113
114 static uint8_t pattern_sigrok[] = {
115         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
116         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
117         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
118         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
119         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
120         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
121         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 };
124
125 SR_PRIV struct sr_dev_driver demo_driver_info;
126 static struct sr_dev_driver *di = &demo_driver_info;
127
128 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
129
130
131 static int dev_clear(void)
132 {
133         return std_dev_clear(di, NULL);
134 }
135
136 static int init(struct sr_context *sr_ctx)
137 {
138         return std_init(sr_ctx, di, LOG_PREFIX);
139 }
140
141 static GSList *scan(GSList *options)
142 {
143         struct drv_context *drvc;
144         struct dev_context *devc;
145         struct sr_dev_inst *sdi;
146         struct sr_probe *probe;
147         struct sr_config *src;
148         GSList *devices, *l;
149         int num_logic_probes, num_analog_probes, i;
150         char probe_name[16];
151
152         drvc = di->priv;
153
154         num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
155         num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
156         for (l = options; l; l = l->next) {
157                 src = l->data;
158                 switch (src->key) {
159                 case SR_CONF_NUM_LOGIC_PROBES:
160                         num_logic_probes = g_variant_get_int32(src->data);
161                         break;
162                 case SR_CONF_NUM_ANALOG_PROBES:
163                         num_analog_probes = g_variant_get_int32(src->data);
164                         break;
165                 }
166         }
167
168         devices = NULL;
169         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
170         if (!sdi) {
171                 sr_err("Device instance creation failed.");
172                 return NULL;
173         }
174         sdi->driver = di;
175
176         for (i = 0; i < num_logic_probes; i++) {
177                 sprintf(probe_name, "D%d", i);
178                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
179                         return NULL;
180                 sdi->probes = g_slist_append(sdi->probes, probe);
181         }
182
183         for (i = 0; i < num_analog_probes; i++) {
184                 sprintf(probe_name, "A%d", i);
185                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_name)))
186                         return NULL;
187                 sdi->probes = g_slist_append(sdi->probes, probe);
188         }
189
190         devices = g_slist_append(devices, sdi);
191         drvc->instances = g_slist_append(drvc->instances, sdi);
192
193         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
194                 sr_err("Device context malloc failed.");
195                 return NULL;
196         }
197         devc->cur_samplerate = SR_KHZ(200);
198         devc->limit_samples = 0;
199         devc->limit_msec = 0;
200         devc->step = 0;
201         devc->num_logic_probes = num_logic_probes;
202         devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
203         devc->logic_pattern = PATTERN_SIGROK;
204         devc->num_analog_probes = num_analog_probes;
205
206         sdi->priv = devc;
207
208         return devices;
209 }
210
211 static GSList *dev_list(void)
212 {
213         return ((struct drv_context *)(di->priv))->instances;
214 }
215
216 static int dev_open(struct sr_dev_inst *sdi)
217 {
218         sdi->status = SR_ST_ACTIVE;
219
220         return SR_OK;
221 }
222
223 static int dev_close(struct sr_dev_inst *sdi)
224 {
225         sdi->status = SR_ST_INACTIVE;
226
227         return SR_OK;
228 }
229
230 static int cleanup(void)
231 {
232         return dev_clear();
233 }
234
235 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
236                 const struct sr_probe_group *probe_group)
237 {
238         struct dev_context *devc;
239
240         (void)probe_group;
241
242         devc = sdi->priv;
243         switch (id) {
244         case SR_CONF_SAMPLERATE:
245                 *data = g_variant_new_uint64(devc->cur_samplerate);
246                 break;
247         case SR_CONF_LIMIT_SAMPLES:
248                 *data = g_variant_new_uint64(devc->limit_samples);
249                 break;
250         case SR_CONF_LIMIT_MSEC:
251                 *data = g_variant_new_uint64(devc->limit_msec);
252                 break;
253         case SR_CONF_PATTERN_MODE:
254                 *data = g_variant_new_string(pattern_strings[devc->logic_pattern]);
255                 break;
256         case SR_CONF_NUM_LOGIC_PROBES:
257                 *data = g_variant_new_int32(devc->num_logic_probes);
258                 break;
259         case SR_CONF_NUM_ANALOG_PROBES:
260                 *data = g_variant_new_int32(devc->num_analog_probes);
261                 break;
262         default:
263                 return SR_ERR_NA;
264         }
265
266         return SR_OK;
267 }
268
269 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
270                 const struct sr_probe_group *probe_group)
271 {
272         unsigned int i;
273         int ret;
274         const char *stropt;
275
276         (void)probe_group;
277         struct dev_context *const devc = sdi->priv;
278
279         if (sdi->status != SR_ST_ACTIVE)
280                 return SR_ERR_DEV_CLOSED;
281
282         if (id == SR_CONF_SAMPLERATE) {
283                 devc->cur_samplerate = g_variant_get_uint64(data);
284                 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
285                 ret = SR_OK;
286         } else if (id == SR_CONF_LIMIT_SAMPLES) {
287                 devc->limit_msec = 0;
288                 devc->limit_samples = g_variant_get_uint64(data);
289                 sr_dbg("Setting limit_samples to %" PRIu64, devc->limit_samples);
290                 ret = SR_OK;
291         } else if (id == SR_CONF_LIMIT_MSEC) {
292                 devc->limit_msec = g_variant_get_uint64(data);
293                 devc->limit_samples = 0;
294                 sr_dbg("Setting limit_msec to %" PRIu64, devc->limit_msec);
295                 ret = SR_OK;
296         } else if (id == SR_CONF_PATTERN_MODE) {
297                 stropt = g_variant_get_string(data, NULL);
298                 ret = SR_ERR;
299                 for (i = 0; i < ARRAY_SIZE(pattern_strings); i++) {
300                         if (!strcmp(stropt, pattern_strings[i])) {
301                                 devc->logic_pattern = i;
302                                 ret = SR_OK;
303                                 break;
304                         }
305                 }
306                 /* Might as well do this now. */
307                 if (i == PATTERN_ALL_LOW)
308                         memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
309                 else if (i == PATTERN_ALL_HIGH)
310                         memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
311                 sr_dbg("Setting pattern to %s", pattern_strings[i]);
312         } else {
313                 ret = SR_ERR_NA;
314         }
315
316         return ret;
317 }
318
319 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
320                 const struct sr_probe_group *probe_group)
321 {
322         GVariant *gvar;
323         GVariantBuilder gvb;
324
325         (void)sdi;
326         (void)probe_group;
327
328         switch (key) {
329         case SR_CONF_SCAN_OPTIONS:
330                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
331                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
332                 break;
333         case SR_CONF_DEVICE_OPTIONS:
334                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
335                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
336                 break;
337         case SR_CONF_SAMPLERATE:
338                 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
339                 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
340                                 ARRAY_SIZE(samplerates), sizeof(uint64_t));
341                 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
342                 *data = g_variant_builder_end(&gvb);
343                 break;
344         case SR_CONF_PATTERN_MODE:
345                 *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
346                 break;
347         default:
348                 return SR_ERR_NA;
349         }
350
351         return SR_OK;
352 }
353
354 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
355 {
356         struct dev_context *devc;
357         uint64_t i, j;
358         uint8_t pat;
359
360         devc = sdi->priv;
361
362         switch (devc->logic_pattern) {
363         case PATTERN_SIGROK:
364                 memset(devc->logic_data, 0x00, size);
365                 for (i = 0; i < size; i += devc->logic_unitsize) {
366                         for (j = 0; j < devc->logic_unitsize; j++) {
367                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
368                                 devc->logic_data[i + j] = ~pat;
369                         }
370                         devc->step++;
371                 }
372                 break;
373         case PATTERN_RANDOM:
374                 for (i = 0; i < size; i++)
375                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
376                 break;
377         case PATTERN_INC:
378                 for (i = 0; i < size; i++) {
379                         for (j = 0; j < devc->logic_unitsize; j++) {
380                                 devc->logic_data[i + j] = devc->step;
381                         }
382                         devc->step++;
383                 }
384                 break;
385         case PATTERN_ALL_LOW:
386         case PATTERN_ALL_HIGH:
387                 /* These were set when the pattern mode was selected. */
388                 break;
389         default:
390                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
391                 break;
392         }
393 }
394
395 /* Callback handling data */
396 static int prepare_data(int fd, int revents, void *cb_data)
397 {
398         struct sr_dev_inst *sdi;
399         struct dev_context *devc;
400         struct sr_datafeed_packet packet;
401         struct sr_datafeed_logic logic;
402         uint64_t samples_to_send, expected_samplenum, sending_now;
403         int64_t time, elapsed;
404
405         (void)fd;
406         (void)revents;
407
408         sdi = cb_data;
409         devc = sdi->priv;
410
411         /* How many "virtual" samples should we have collected by now? */
412         time = g_get_monotonic_time();
413         elapsed = time - devc->starttime;
414         expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
415         /* Of those, how many do we still have to send? */
416         samples_to_send = expected_samplenum - devc->samples_counter;
417
418         if (devc->limit_samples) {
419                 samples_to_send = MIN(samples_to_send,
420                                 devc->limit_samples - devc->samples_counter);
421         }
422
423         while (samples_to_send > 0) {
424                 sending_now = MIN(samples_to_send, LOGIC_BUFSIZE / devc->logic_unitsize);
425                 samples_to_send -= sending_now;
426
427                 /* Logic */
428                 logic_generator(sdi, sending_now * devc->logic_unitsize);
429                 packet.type = SR_DF_LOGIC;
430                 packet.payload = &logic;
431                 logic.length = sending_now * devc->logic_unitsize;
432                 logic.unitsize = devc->logic_unitsize;
433                 logic.data = devc->logic_data;
434                 sr_session_send(sdi, &packet);
435                 devc->samples_counter += sending_now;
436         }
437
438         if (devc->limit_samples &&
439                 devc->samples_counter >= devc->limit_samples) {
440                 sr_info("Requested number of samples reached.");
441                 dev_acquisition_stop(sdi, cb_data);
442                 return TRUE;
443         }
444
445         return TRUE;
446 }
447
448 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
449 {
450         struct dev_context *devc;
451
452         if (sdi->status != SR_ST_ACTIVE)
453                 return SR_ERR_DEV_CLOSED;
454
455         devc = sdi->priv;
456         devc->samples_counter = 0;
457
458         /*
459          * Setting two channels connected by a pipe is a remnant from when the
460          * demo driver generated data in a thread, and collected and sent the
461          * data in the main program loop.
462          * They are kept here because it provides a convenient way of setting
463          * up a timeout-based polling mechanism.
464          */
465         if (pipe(devc->pipe_fds)) {
466                 sr_err("%s: pipe() failed", __func__);
467                 return SR_ERR;
468         }
469
470         devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
471
472         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
473
474         /* Set channel encoding to binary (default is UTF-8). */
475         g_io_channel_set_encoding(devc->channel, NULL, NULL);
476
477         /* Make channels to unbuffered. */
478         g_io_channel_set_buffered(devc->channel, FALSE);
479
480         sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
481                         40, prepare_data, (void *)sdi);
482
483         /* Send header packet to the session bus. */
484         std_session_send_df_header(cb_data, LOG_PREFIX);
485
486         /* We use this timestamp to decide how many more samples to send. */
487         devc->starttime = g_get_monotonic_time();
488
489         return SR_OK;
490 }
491
492 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
493 {
494         struct dev_context *const devc = sdi->priv;
495         struct sr_datafeed_packet packet;
496
497         (void)cb_data;
498
499         sr_dbg("Stopping aquisition.");
500
501         sr_session_source_remove_channel(devc->channel);
502         g_io_channel_shutdown(devc->channel, FALSE, NULL);
503         g_io_channel_unref(devc->channel);
504         devc->channel = NULL;
505
506         /* Send last packet. */
507         packet.type = SR_DF_END;
508         sr_session_send(sdi, &packet);
509
510         return SR_OK;
511 }
512
513 SR_PRIV struct sr_dev_driver demo_driver_info = {
514         .name = "demo",
515         .longname = "Demo driver and pattern generator",
516         .api_version = 1,
517         .init = init,
518         .cleanup = cleanup,
519         .scan = scan,
520         .dev_list = dev_list,
521         .dev_clear = dev_clear,
522         .config_get = config_get,
523         .config_set = config_set,
524         .config_list = config_list,
525         .dev_open = dev_open,
526         .dev_close = dev_close,
527         .dev_acquisition_start = dev_acquisition_start,
528         .dev_acquisition_stop = dev_acquisition_stop,
529         .priv = NULL,
530 };