]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/demo/demo.c
rigol-ds: add a few more DS2000 models to the supported list
[libsigrok.git] / hardware / demo / demo.c
... / ...
CommitLineData
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 */
45enum {
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
77static const char *logic_pattern_str[] = {
78 "sigrok",
79 "random",
80 "incremental",
81 "all-low",
82 "all-high",
83};
84
85static const char *analog_pattern_str[] = {
86 "square",
87};
88
89struct 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. */
97struct 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
116static const int32_t hwopts[] = {
117 SR_CONF_NUM_LOGIC_PROBES,
118 SR_CONF_NUM_ANALOG_PROBES,
119};
120
121static 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
130static const uint64_t samplerates[] = {
131 SR_HZ(1),
132 SR_GHZ(1),
133 SR_HZ(1),
134};
135
136static 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
147SR_PRIV struct sr_dev_driver demo_driver_info;
148static struct sr_dev_driver *di = &demo_driver_info;
149
150static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
151
152
153static int dev_clear(void)
154{
155 return std_dev_clear(di, NULL);
156}
157
158static int init(struct sr_context *sr_ctx)
159{
160 return std_init(sr_ctx, di, LOG_PREFIX);
161}
162
163static 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
190static 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
291static GSList *dev_list(void)
292{
293 return ((struct drv_context *)(di->priv))->instances;
294}
295
296static int dev_open(struct sr_dev_inst *sdi)
297{
298 sdi->status = SR_ST_ACTIVE;
299
300 return SR_OK;
301}
302
303static int dev_close(struct sr_dev_inst *sdi)
304{
305 sdi->status = SR_ST_INACTIVE;
306
307 return SR_OK;
308}
309
310static int cleanup(void)
311{
312 return dev_clear();
313}
314
315static 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
349static 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
430static 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
465static 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 */
507static 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
583static 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
628static 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
650SR_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};