]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
0c4c211e9f085d2f1aadc4bf124d4709759a89a1
[libsigrok.git] / hardware / demo / demo.c
1 /*
2  * This file is part of the sigrok 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 /* Message logging helpers with driver-specific prefix string. */
35 #define DRIVER_LOG_DOMAIN "demo: "
36 #define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args)
37 #define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args)
38 #define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args)
39 #define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args)
40 #define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args)
41 #define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
42
43 /* TODO: Number of probes should be configurable. */
44 #define NUM_PROBES             8
45
46 #define DEMONAME               "Demo device"
47
48 /* The size of chunks to send through the session bus. */
49 /* TODO: Should be configurable. */
50 #define BUFSIZE                4096
51
52 /* Supported patterns which we can generate */
53 enum {
54         /**
55          * Pattern which spells "sigrok" using '0's (with '1's as "background")
56          * when displayed using the 'bits' output format.
57          */
58         PATTERN_SIGROK,
59
60         /** Pattern which consists of (pseudo-)random values on all probes. */
61         PATTERN_RANDOM,
62
63         /**
64          * Pattern which consists of incrementing numbers.
65          * TODO: Better description.
66          */
67         PATTERN_INC,
68
69         /** Pattern where all probes have a low logic state. */
70         PATTERN_ALL_LOW,
71
72         /** Pattern where all probes have a high logic state. */
73         PATTERN_ALL_HIGH,
74 };
75
76 /* Private, per-device-instance driver context. */
77 struct dev_context {
78         int pipe_fds[2];
79         GIOChannel *channels[2];
80         uint8_t sample_generator;
81         uint64_t samples_counter;
82         void *session_dev_id;
83         int64_t starttime;
84 };
85
86 static const int hwcaps[] = {
87         SR_HWCAP_LOGIC_ANALYZER,
88         SR_HWCAP_DEMO_DEV,
89         SR_HWCAP_SAMPLERATE,
90         SR_HWCAP_PATTERN_MODE,
91         SR_HWCAP_LIMIT_SAMPLES,
92         SR_HWCAP_LIMIT_MSEC,
93         SR_HWCAP_CONTINUOUS,
94 };
95
96 static const struct sr_samplerates samplerates = {
97         SR_HZ(1),
98         SR_GHZ(1),
99         SR_HZ(1),
100         NULL,
101 };
102
103 static const char *pattern_strings[] = {
104         "sigrok",
105         "random",
106         "incremental",
107         "all-low",
108         "all-high",
109         NULL,
110 };
111
112 /* We name the probes 0-7 on our demo driver. */
113 static const char *probe_names[NUM_PROBES + 1] = {
114         "0",
115         "1",
116         "2",
117         "3",
118         "4",
119         "5",
120         "6",
121         "7",
122         NULL,
123 };
124
125 static uint8_t pattern_sigrok[] = {
126         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
127         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
128         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
129         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
130         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
131         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 };
135
136 /* Private, per-device-instance driver context. */
137 /* TODO: struct context as with the other drivers. */
138
139 /* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
140 SR_PRIV struct sr_dev_driver demo_driver_info;
141 static struct sr_dev_driver *ddi = &demo_driver_info;
142 static uint64_t cur_samplerate = SR_KHZ(200);
143 static uint64_t limit_samples = 0;
144 static uint64_t limit_msec = 0;
145 static int default_pattern = PATTERN_SIGROK;
146
147 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
148
149 static int clear_instances(void)
150 {
151         /* Nothing needed so far. */
152
153         return SR_OK;
154 }
155
156 static int hw_init(void)
157 {
158         struct drv_context *drvc;
159
160         if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
161                 sr_err("Driver context malloc failed.");
162                 return SR_ERR_MALLOC;
163         }
164         ddi->priv = drvc;
165
166         return SR_OK;
167 }
168
169 static GSList *hw_scan(GSList *options)
170 {
171         struct sr_dev_inst *sdi;
172         struct sr_probe *probe;
173         struct drv_context *drvc;
174         GSList *devices;
175         int i;
176
177         (void)options;
178
179         drvc = ddi->priv;
180         devices = NULL;
181
182         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
183         if (!sdi) {
184                 sr_err("%s: sr_dev_inst_new failed", __func__);
185                 return 0;
186         }
187         sdi->driver = ddi;
188
189         for (i = 0; probe_names[i]; i++) {
190                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
191                                 probe_names[i])))
192                         return NULL;
193                 sdi->probes = g_slist_append(sdi->probes, probe);
194         }
195
196         devices = g_slist_append(devices, sdi);
197         drvc->instances = g_slist_append(drvc->instances, sdi);
198
199         return devices;
200 }
201
202 static GSList *hw_dev_list(void)
203 {
204         struct drv_context *drvc;
205
206         drvc = ddi->priv;
207
208         return drvc->instances;
209 }
210
211 static int hw_dev_open(struct sr_dev_inst *sdi)
212 {
213         (void)sdi;
214
215         /* Nothing needed so far. */
216
217         return SR_OK;
218 }
219
220 static int hw_dev_close(struct sr_dev_inst *sdi)
221 {
222         (void)sdi;
223
224         /* Nothing needed so far. */
225
226         return SR_OK;
227 }
228
229 static int hw_cleanup(void)
230 {
231         /* Nothing needed so far. */
232         return SR_OK;
233 }
234
235 static int hw_info_get(int info_id, const void **data,
236        const struct sr_dev_inst *sdi)
237 {
238         (void)sdi;
239
240         switch (info_id) {
241         case SR_DI_HWCAPS:
242                 *data = hwcaps;
243                 break;
244         case SR_DI_NUM_PROBES:
245                 *data = GINT_TO_POINTER(NUM_PROBES);
246                 break;
247         case SR_DI_PROBE_NAMES:
248                 *data = probe_names;
249                 break;
250         case SR_DI_SAMPLERATES:
251                 *data = &samplerates;
252                 break;
253         case SR_DI_CUR_SAMPLERATE:
254                 *data = &cur_samplerate;
255                 break;
256         case SR_DI_PATTERNS:
257                 *data = &pattern_strings;
258                 break;
259         default:
260                 return SR_ERR_ARG;
261         }
262
263         return SR_OK;
264 }
265
266 static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
267                 const void *value)
268 {
269         int ret;
270         const char *stropt;
271
272         (void)sdi;
273
274         if (hwcap == SR_HWCAP_SAMPLERATE) {
275                 cur_samplerate = *(const uint64_t *)value;
276                 sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
277                        cur_samplerate);
278                 ret = SR_OK;
279         } else if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
280                 limit_msec = 0;
281                 limit_samples = *(const uint64_t *)value;
282                 sr_dbg("%s: setting limit_samples to %" PRIu64, __func__,
283                        limit_samples);
284                 ret = SR_OK;
285         } else if (hwcap == SR_HWCAP_LIMIT_MSEC) {
286                 limit_msec = *(const uint64_t *)value;
287                 limit_samples = 0;
288                 sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
289                        limit_msec);
290                 ret = SR_OK;
291         } else if (hwcap == SR_HWCAP_PATTERN_MODE) {
292                 stropt = value;
293                 ret = SR_OK;
294                 if (!strcmp(stropt, "sigrok")) {
295                         default_pattern = PATTERN_SIGROK;
296                 } else if (!strcmp(stropt, "random")) {
297                         default_pattern = PATTERN_RANDOM;
298                 } else if (!strcmp(stropt, "incremental")) {
299                         default_pattern = PATTERN_INC;
300                 } else if (!strcmp(stropt, "all-low")) {
301                         default_pattern = PATTERN_ALL_LOW;
302                 } else if (!strcmp(stropt, "all-high")) {
303                         default_pattern = PATTERN_ALL_HIGH;
304                 } else {
305                         ret = SR_ERR;
306                 }
307                 sr_dbg("%s: setting pattern to %d", __func__, default_pattern);
308         } else {
309                 ret = SR_ERR;
310         }
311
312         return ret;
313 }
314
315 static void samples_generator(uint8_t *buf, uint64_t size,
316                               struct dev_context *devc)
317 {
318         static uint64_t p = 0;
319         uint64_t i;
320
321         /* TODO: Needed? */
322         memset(buf, 0, size);
323
324         switch (devc->sample_generator) {
325         case PATTERN_SIGROK: /* sigrok pattern */
326                 for (i = 0; i < size; i++) {
327                         *(buf + i) = ~(pattern_sigrok[p] >> 1);
328                         if (++p == 64)
329                                 p = 0;
330                 }
331                 break;
332         case PATTERN_RANDOM: /* Random */
333                 for (i = 0; i < size; i++)
334                         *(buf + i) = (uint8_t)(rand() & 0xff);
335                 break;
336         case PATTERN_INC: /* Simple increment */
337                 for (i = 0; i < size; i++)
338                         *(buf + i) = i;
339                 break;
340         case PATTERN_ALL_LOW: /* All probes are low */
341                 memset(buf, 0x00, size);
342                 break;
343         case PATTERN_ALL_HIGH: /* All probes are high */
344                 memset(buf, 0xff, size);
345                 break;
346         default:
347                 sr_err("Unknown pattern: %d.", devc->sample_generator);
348                 break;
349         }
350 }
351
352 /* Callback handling data */
353 static int receive_data(int fd, int revents, void *cb_data)
354 {
355         struct dev_context *devc = cb_data;
356         struct sr_datafeed_packet packet;
357         struct sr_datafeed_logic logic;
358         uint8_t buf[BUFSIZE];
359         static uint64_t samples_to_send, expected_samplenum, sending_now;
360         int64_t time, elapsed;
361
362         (void)fd;
363         (void)revents;
364
365         /* How many "virtual" samples should we have collected by now? */
366         time = g_get_monotonic_time();
367         elapsed = time - devc->starttime;
368         expected_samplenum = elapsed * cur_samplerate / 1000000;
369         /* Of those, how many do we still have to send? */
370         samples_to_send = expected_samplenum - devc->samples_counter;
371
372         if (limit_samples) {
373                 samples_to_send = MIN(samples_to_send,
374                                  limit_samples - devc->samples_counter);
375         }
376
377         while (samples_to_send > 0) {
378                 sending_now = MIN(samples_to_send, sizeof(buf));
379                 samples_to_send -= sending_now;
380                 samples_generator(buf, sending_now, devc);
381
382                 packet.type = SR_DF_LOGIC;
383                 packet.payload = &logic;
384                 logic.length = sending_now;
385                 logic.unitsize = 1;
386                 logic.data = buf;
387                 sr_session_send(devc->session_dev_id, &packet);
388                 devc->samples_counter += sending_now;
389         }
390
391
392         if (devc->samples_counter >= limit_samples) {
393                 sr_spew("We sent a total of %" PRIu64 " samples.",
394                         devc->samples_counter);
395                 /* Make sure we don't receive more packets. */
396                 hw_dev_acquisition_stop(NULL, cb_data);
397                 return TRUE;
398         }
399
400         return TRUE;
401 }
402
403 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
404                 void *cb_data)
405 {
406         struct sr_datafeed_packet *packet;
407         struct sr_datafeed_header *header;
408         struct sr_datafeed_meta_logic meta;
409         struct dev_context *devc;
410
411         (void)sdi;
412
413         sr_dbg("Starting acquisition.");
414
415         /* TODO: 'devc' is never g_free()'d? */
416         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
417                 sr_err("%s: devc malloc failed", __func__);
418                 return SR_ERR_MALLOC;
419         }
420
421         devc->sample_generator = default_pattern;
422         devc->session_dev_id = cb_data;
423         devc->samples_counter = 0;
424
425         /*
426          * Setting two channels connected by a pipe is a remnant from when the
427          * demo driver generated data in a thread, and collected and sent the
428          * data in the main program loop.
429          * They are kept here because it provides a convenient way of setting
430          * up a timeout-based polling mechanism.
431          */
432         if (pipe(devc->pipe_fds)) {
433                 /* TODO: Better error message. */
434                 sr_err("%s: pipe() failed", __func__);
435                 return SR_ERR;
436         }
437
438         devc->channels[0] = g_io_channel_unix_new(devc->pipe_fds[0]);
439         devc->channels[1] = g_io_channel_unix_new(devc->pipe_fds[1]);
440
441         g_io_channel_set_flags(devc->channels[0], G_IO_FLAG_NONBLOCK, NULL);
442
443         /* Set channel encoding to binary (default is UTF-8). */
444         g_io_channel_set_encoding(devc->channels[0], NULL, NULL);
445         g_io_channel_set_encoding(devc->channels[1], NULL, NULL);
446
447         /* Make channels to unbuffered. */
448         g_io_channel_set_buffered(devc->channels[0], FALSE);
449         g_io_channel_set_buffered(devc->channels[1], FALSE);
450
451         sr_session_source_add_channel(devc->channels[0], G_IO_IN | G_IO_ERR,
452                     40, receive_data, devc);
453
454         if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
455                 sr_err("%s: packet malloc failed", __func__);
456                 return SR_ERR_MALLOC;
457         }
458
459         if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
460                 sr_err("%s: header malloc failed", __func__);
461                 return SR_ERR_MALLOC;
462         }
463
464         packet->type = SR_DF_HEADER;
465         packet->payload = header;
466         header->feed_version = 1;
467         gettimeofday(&header->starttime, NULL);
468         sr_session_send(devc->session_dev_id, packet);
469
470         /* Send metadata about the SR_DF_LOGIC packets to come. */
471         packet->type = SR_DF_META_LOGIC;
472         packet->payload = &meta;
473         meta.samplerate = cur_samplerate;
474         meta.num_probes = NUM_PROBES;
475         sr_session_send(devc->session_dev_id, packet);
476
477         /* We use this timestamp to decide how many more samples to send. */
478         devc->starttime = g_get_monotonic_time();
479
480         g_free(header);
481         g_free(packet);
482
483         return SR_OK;
484 }
485
486 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
487 {
488         struct dev_context *devc;
489         struct sr_datafeed_packet packet;
490
491         (void)sdi;
492
493         devc = cb_data;
494
495         sr_dbg("Stopping aquisition.");
496
497         sr_session_source_remove_channel(devc->channels[0]);
498         g_io_channel_shutdown(devc->channels[0], FALSE, NULL);
499
500         /* Send last packet. */
501         packet.type = SR_DF_END;
502         sr_session_send(devc->session_dev_id, &packet);
503
504         return SR_OK;
505 }
506
507 SR_PRIV struct sr_dev_driver demo_driver_info = {
508         .name = "demo",
509         .longname = "Demo driver and pattern generator",
510         .api_version = 1,
511         .init = hw_init,
512         .cleanup = hw_cleanup,
513         .scan = hw_scan,
514         .dev_list = hw_dev_list,
515         .dev_clear = clear_instances,
516         .dev_open = hw_dev_open,
517         .dev_close = hw_dev_close,
518         .info_get = hw_info_get,
519         .dev_config_set = hw_dev_config_set,
520         .dev_acquisition_start = hw_dev_acquisition_start,
521         .dev_acquisition_stop = hw_dev_acquisition_stop,
522         .priv = NULL,
523 };