]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
Deprecate SR_DI_CUR_SAMPLERATE.
[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_CONF_LOGIC_ANALYZER,
88         SR_CONF_DEMO_DEV,
89         SR_CONF_SAMPLERATE,
90         SR_CONF_PATTERN_MODE,
91         SR_CONF_LIMIT_SAMPLES,
92         SR_CONF_LIMIT_MSEC,
93         SR_CONF_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", "1", "2", "3", "4", "5", "6", "7",
115         NULL,
116 };
117
118 static uint8_t pattern_sigrok[] = {
119         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
120         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
121         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
122         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
123         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
124         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
125         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 };
128
129 /* Private, per-device-instance driver context. */
130 /* TODO: struct context as with the other drivers. */
131
132 /* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
133 SR_PRIV struct sr_dev_driver demo_driver_info;
134 static struct sr_dev_driver *di = &demo_driver_info;
135 static uint64_t cur_samplerate = SR_KHZ(200);
136 static uint64_t limit_samples = 0;
137 static uint64_t limit_msec = 0;
138 static int default_pattern = PATTERN_SIGROK;
139
140 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
141
142 static int clear_instances(void)
143 {
144         /* Nothing needed so far. */
145
146         return SR_OK;
147 }
148
149 static int hw_init(struct sr_context *sr_ctx)
150 {
151         struct drv_context *drvc;
152
153         if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
154                 sr_err("Driver context malloc failed.");
155                 return SR_ERR_MALLOC;
156         }
157         drvc->sr_ctx = sr_ctx;
158         di->priv = drvc;
159
160         return SR_OK;
161 }
162
163 static GSList *hw_scan(GSList *options)
164 {
165         struct sr_dev_inst *sdi;
166         struct sr_probe *probe;
167         struct drv_context *drvc;
168         GSList *devices;
169         int i;
170
171         (void)options;
172
173         drvc = di->priv;
174         devices = NULL;
175
176         sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
177         if (!sdi) {
178                 sr_err("%s: sr_dev_inst_new failed", __func__);
179                 return 0;
180         }
181         sdi->driver = di;
182
183         for (i = 0; probe_names[i]; i++) {
184                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
185                                 probe_names[i])))
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         return devices;
194 }
195
196 static GSList *hw_dev_list(void)
197 {
198         struct drv_context *drvc;
199
200         drvc = di->priv;
201
202         return drvc->instances;
203 }
204
205 static int hw_dev_open(struct sr_dev_inst *sdi)
206 {
207         (void)sdi;
208
209         /* Nothing needed so far. */
210
211         return SR_OK;
212 }
213
214 static int hw_dev_close(struct sr_dev_inst *sdi)
215 {
216         (void)sdi;
217
218         /* Nothing needed so far. */
219
220         return SR_OK;
221 }
222
223 static int hw_cleanup(void)
224 {
225         /* Nothing needed so far. */
226         return SR_OK;
227 }
228
229 static int config_get(int id, const void **data, const struct sr_dev_inst *sdi)
230 {
231         (void)sdi;
232
233         switch (id) {
234         case SR_DI_HWCAPS:
235                 *data = hwcaps;
236                 break;
237         case SR_CONF_SAMPLERATE:
238                 *data = &cur_samplerate;
239                 break;
240         case SR_DI_PATTERNS:
241                 *data = &pattern_strings;
242                 break;
243         default:
244                 return SR_ERR_ARG;
245         }
246
247         return SR_OK;
248 }
249
250 static int config_set(int id, const void *value, const struct sr_dev_inst *sdi)
251 {
252         int ret;
253         const char *stropt;
254
255         (void)sdi;
256
257         if (id == SR_CONF_SAMPLERATE) {
258                 cur_samplerate = *(const uint64_t *)value;
259                 sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
260                        cur_samplerate);
261                 ret = SR_OK;
262         } else if (id == SR_CONF_LIMIT_SAMPLES) {
263                 limit_msec = 0;
264                 limit_samples = *(const uint64_t *)value;
265                 sr_dbg("%s: setting limit_samples to %" PRIu64, __func__,
266                        limit_samples);
267                 ret = SR_OK;
268         } else if (id == SR_CONF_LIMIT_MSEC) {
269                 limit_msec = *(const uint64_t *)value;
270                 limit_samples = 0;
271                 sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
272                        limit_msec);
273                 ret = SR_OK;
274         } else if (id == SR_CONF_PATTERN_MODE) {
275                 stropt = value;
276                 ret = SR_OK;
277                 if (!strcmp(stropt, "sigrok")) {
278                         default_pattern = PATTERN_SIGROK;
279                 } else if (!strcmp(stropt, "random")) {
280                         default_pattern = PATTERN_RANDOM;
281                 } else if (!strcmp(stropt, "incremental")) {
282                         default_pattern = PATTERN_INC;
283                 } else if (!strcmp(stropt, "all-low")) {
284                         default_pattern = PATTERN_ALL_LOW;
285                 } else if (!strcmp(stropt, "all-high")) {
286                         default_pattern = PATTERN_ALL_HIGH;
287                 } else {
288                         ret = SR_ERR;
289                 }
290                 sr_dbg("%s: setting pattern to %d", __func__, default_pattern);
291         } else {
292                 ret = SR_ERR;
293         }
294
295         return ret;
296 }
297
298 static int config_list(int key, const void **data, const struct sr_dev_inst *sdi)
299 {
300
301         (void)sdi;
302
303         switch (key) {
304         case SR_CONF_SAMPLERATE:
305                 *data = &samplerates;
306                 break;
307         default:
308                 return SR_ERR_ARG;
309         }
310
311         return SR_OK;
312 }
313
314 static void samples_generator(uint8_t *buf, uint64_t size,
315                               struct dev_context *devc)
316 {
317         static uint64_t p = 0;
318         uint64_t i;
319
320         /* TODO: Needed? */
321         memset(buf, 0, size);
322
323         switch (devc->sample_generator) {
324         case PATTERN_SIGROK: /* sigrok pattern */
325                 for (i = 0; i < size; i++) {
326                         *(buf + i) = ~(pattern_sigrok[p] >> 1);
327                         if (++p == 64)
328                                 p = 0;
329                 }
330                 break;
331         case PATTERN_RANDOM: /* Random */
332                 for (i = 0; i < size; i++)
333                         *(buf + i) = (uint8_t)(rand() & 0xff);
334                 break;
335         case PATTERN_INC: /* Simple increment */
336                 for (i = 0; i < size; i++)
337                         *(buf + i) = i;
338                 break;
339         case PATTERN_ALL_LOW: /* All probes are low */
340                 memset(buf, 0x00, size);
341                 break;
342         case PATTERN_ALL_HIGH: /* All probes are high */
343                 memset(buf, 0xff, size);
344                 break;
345         default:
346                 sr_err("Unknown pattern: %d.", devc->sample_generator);
347                 break;
348         }
349 }
350
351 /* Callback handling data */
352 static int receive_data(int fd, int revents, void *cb_data)
353 {
354         struct dev_context *devc = cb_data;
355         struct sr_datafeed_packet packet;
356         struct sr_datafeed_logic logic;
357         uint8_t buf[BUFSIZE];
358         static uint64_t samples_to_send, expected_samplenum, sending_now;
359         int64_t time, elapsed;
360
361         (void)fd;
362         (void)revents;
363
364         /* How many "virtual" samples should we have collected by now? */
365         time = g_get_monotonic_time();
366         elapsed = time - devc->starttime;
367         expected_samplenum = elapsed * cur_samplerate / 1000000;
368         /* Of those, how many do we still have to send? */
369         samples_to_send = expected_samplenum - devc->samples_counter;
370
371         if (limit_samples) {
372                 samples_to_send = MIN(samples_to_send,
373                                  limit_samples - devc->samples_counter);
374         }
375
376         while (samples_to_send > 0) {
377                 sending_now = MIN(samples_to_send, sizeof(buf));
378                 samples_to_send -= sending_now;
379                 samples_generator(buf, sending_now, devc);
380
381                 packet.type = SR_DF_LOGIC;
382                 packet.payload = &logic;
383                 logic.length = sending_now;
384                 logic.unitsize = 1;
385                 logic.data = buf;
386                 sr_session_send(devc->session_dev_id, &packet);
387                 devc->samples_counter += sending_now;
388         }
389
390         if (limit_samples && devc->samples_counter >= limit_samples) {
391                 sr_info("Requested number of samples reached.");
392                 hw_dev_acquisition_stop(NULL, cb_data);
393                 return TRUE;
394         }
395
396         return TRUE;
397 }
398
399 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
400                 void *cb_data)
401 {
402         struct sr_datafeed_packet *packet;
403         struct sr_datafeed_header *header;
404         struct dev_context *devc;
405
406         (void)sdi;
407
408         sr_dbg("Starting acquisition.");
409
410         /* TODO: 'devc' is never g_free()'d? */
411         if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
412                 sr_err("%s: devc malloc failed", __func__);
413                 return SR_ERR_MALLOC;
414         }
415
416         devc->sample_generator = default_pattern;
417         devc->session_dev_id = cb_data;
418         devc->samples_counter = 0;
419
420         /*
421          * Setting two channels connected by a pipe is a remnant from when the
422          * demo driver generated data in a thread, and collected and sent the
423          * data in the main program loop.
424          * They are kept here because it provides a convenient way of setting
425          * up a timeout-based polling mechanism.
426          */
427         if (pipe(devc->pipe_fds)) {
428                 /* TODO: Better error message. */
429                 sr_err("%s: pipe() failed", __func__);
430                 return SR_ERR;
431         }
432
433         devc->channels[0] = g_io_channel_unix_new(devc->pipe_fds[0]);
434         devc->channels[1] = g_io_channel_unix_new(devc->pipe_fds[1]);
435
436         g_io_channel_set_flags(devc->channels[0], G_IO_FLAG_NONBLOCK, NULL);
437
438         /* Set channel encoding to binary (default is UTF-8). */
439         g_io_channel_set_encoding(devc->channels[0], NULL, NULL);
440         g_io_channel_set_encoding(devc->channels[1], NULL, NULL);
441
442         /* Make channels to unbuffered. */
443         g_io_channel_set_buffered(devc->channels[0], FALSE);
444         g_io_channel_set_buffered(devc->channels[1], FALSE);
445
446         sr_session_source_add_channel(devc->channels[0], G_IO_IN | G_IO_ERR,
447                     40, receive_data, devc);
448
449         if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
450                 sr_err("%s: packet malloc failed", __func__);
451                 return SR_ERR_MALLOC;
452         }
453
454         if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
455                 sr_err("%s: header malloc failed", __func__);
456                 return SR_ERR_MALLOC;
457         }
458
459         packet->type = SR_DF_HEADER;
460         packet->payload = header;
461         header->feed_version = 1;
462         gettimeofday(&header->starttime, NULL);
463         sr_session_send(devc->session_dev_id, packet);
464
465         /* We use this timestamp to decide how many more samples to send. */
466         devc->starttime = g_get_monotonic_time();
467
468         g_free(header);
469         g_free(packet);
470
471         return SR_OK;
472 }
473
474 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
475 {
476         struct dev_context *devc;
477         struct sr_datafeed_packet packet;
478
479         (void)sdi;
480
481         devc = cb_data;
482
483         sr_dbg("Stopping aquisition.");
484
485         sr_session_source_remove_channel(devc->channels[0]);
486         g_io_channel_shutdown(devc->channels[0], FALSE, NULL);
487
488         /* Send last packet. */
489         packet.type = SR_DF_END;
490         sr_session_send(devc->session_dev_id, &packet);
491
492         return SR_OK;
493 }
494
495 SR_PRIV struct sr_dev_driver demo_driver_info = {
496         .name = "demo",
497         .longname = "Demo driver and pattern generator",
498         .api_version = 1,
499         .init = hw_init,
500         .cleanup = hw_cleanup,
501         .scan = hw_scan,
502         .dev_list = hw_dev_list,
503         .dev_clear = clear_instances,
504         .config_get = config_get,
505         .config_set = config_set,
506         .config_list = config_list,
507         .dev_open = hw_dev_open,
508         .dev_close = hw_dev_close,
509         .dev_acquisition_start = hw_dev_acquisition_start,
510         .dev_acquisition_stop = hw_dev_acquisition_stop,
511         .priv = NULL,
512 };