]> sigrok.org Git - libsigrok.git/blame - hardware/demo/demo.c
Fix 'aquisition' typo in a few places.
[libsigrok.git] / hardware / demo / demo.c
CommitLineData
6239c175 1/*
50985c20 2 * This file is part of the libsigrok project.
6239c175
UH
3 *
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
fc96e6f8 5 * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
c216d623 6 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
6239c175
UH
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>
85b5af06 24#include <unistd.h>
6239c175 25#include <string.h>
4374219b 26#include <math.h>
d35aaf02
UH
27#ifdef _WIN32
28#include <io.h>
29#include <fcntl.h>
30#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
31#endif
45c59c8b
BV
32#include "libsigrok.h"
33#include "libsigrok-internal.h"
6239c175 34
3544f848 35#define LOG_PREFIX "demo"
92bcedf6 36
c07f60e7
BV
37#define DEFAULT_NUM_LOGIC_PROBES 8
38#define DEFAULT_NUM_ANALOG_PROBES 4
c03ed397 39
8b2d41ed 40/* The size in bytes of chunks to send through the session bus. */
61c39f54 41#define LOGIC_BUFSIZE 4096
8b2d41ed
BV
42/* Size of the analog pattern space per channel. */
43#define ANALOG_BUFSIZE 4096
2474d87e 44
4374219b
DJ
45#define ANALOG_AMPLITUDE 25
46#define ANALOG_SAMPLES_PER_PERIOD 20
47
2388ae86 48/* Logic patterns we can generate. */
e15f48c2 49enum {
0d31276b 50 /**
61c39f54
BV
51 * Spells "sigrok" across 8 probes using '0's (with '1's as
52 * "background") when displayed using the 'bits' output format.
c07f60e7
BV
53 * The pattern is repeasted every 8 probes, shifted to the right
54 * in time by one bit.
0d31276b 55 */
c8f4624d 56 PATTERN_SIGROK,
0d31276b 57
c07f60e7 58 /** Pseudo-random values on all probes. */
c8f4624d 59 PATTERN_RANDOM,
0d31276b
UH
60
61 /**
c07f60e7
BV
62 * Incrementing number across 8 probes. The pattern is repeasted
63 * every 8 probes, shifted to the right in time by one bit.
0d31276b 64 */
c8f4624d 65 PATTERN_INC,
c03ed397 66
61c39f54 67 /** All probes have a low logic state. */
c03ed397
UH
68 PATTERN_ALL_LOW,
69
61c39f54 70 /** All probes have a high logic state. */
c03ed397 71 PATTERN_ALL_HIGH,
2388ae86 72};
8b2d41ed 73
2388ae86
BV
74/* Analog patterns we can generate. */
75enum {
8b2d41ed
BV
76 /**
77 * Square wave.
78 */
79 PATTERN_SQUARE,
4374219b 80 PATTERN_SINE,
091c9621 81 PATTERN_TRIANGLE,
9f54e0e8 82 PATTERN_SAWTOOTH,
e15f48c2 83};
85b5af06 84
8b2d41ed 85static const char *logic_pattern_str[] = {
61c39f54
BV
86 "sigrok",
87 "random",
88 "incremental",
89 "all-low",
90 "all-high",
91};
92
8b2d41ed
BV
93static const char *analog_pattern_str[] = {
94 "square",
4374219b 95 "sine",
091c9621 96 "triangle",
9f54e0e8 97 "sawtooth",
8b2d41ed
BV
98};
99
100struct analog_gen {
101 int pattern;
102 float pattern_data[ANALOG_BUFSIZE];
103 unsigned int num_samples;
104 struct sr_datafeed_analog packet;
105};
106
b4750a3a
BV
107/* Private, per-device-instance driver context. */
108struct dev_context {
e15f48c2 109 int pipe_fds[2];
e0532047 110 GIOChannel *channel;
a7684294
JH
111 uint64_t cur_samplerate;
112 uint64_t limit_samples;
113 uint64_t limit_msec;
7f4975b4
BV
114 uint64_t logic_counter;
115 uint64_t analog_counter;
3b203673 116 int64_t starttime;
61c39f54 117 uint64_t step;
8b2d41ed 118 /* Logic */
c07f60e7
BV
119 int32_t num_logic_probes;
120 unsigned int logic_unitsize;
2388ae86 121 /* There is only ever one logic probe group, so its pattern goes here. */
c07f60e7
BV
122 uint8_t logic_pattern;
123 unsigned char logic_data[LOGIC_BUFSIZE];
8b2d41ed 124 /* Analog */
c07f60e7 125 int32_t num_analog_probes;
8b2d41ed 126 GSList *analog_probe_groups;
c07f60e7
BV
127};
128
7a1da331 129static const int32_t scanopts[] = {
c07f60e7
BV
130 SR_CONF_NUM_LOGIC_PROBES,
131 SR_CONF_NUM_ANALOG_PROBES,
e15f48c2 132};
85b5af06 133
7a1da331 134static const int devopts[] = {
1953564a
BV
135 SR_CONF_LOGIC_ANALYZER,
136 SR_CONF_DEMO_DEV,
137 SR_CONF_SAMPLERATE,
1953564a
BV
138 SR_CONF_LIMIT_SAMPLES,
139 SR_CONF_LIMIT_MSEC,
6239c175
UH
140};
141
7a1da331
BV
142static const int devopts_pg[] = {
143 SR_CONF_PATTERN_MODE,
144};
145
d00088ca
BV
146static const uint64_t samplerates[] = {
147 SR_HZ(1),
148 SR_GHZ(1),
149 SR_HZ(1),
4bfbf9fc
BV
150};
151
c8f4624d 152static uint8_t pattern_sigrok[] = {
917e0e71
BV
153 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
154 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
155 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
156 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
157 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
158 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161};
162
dcf03d6d 163SR_PRIV struct sr_dev_driver demo_driver_info;
a873c594 164static struct sr_dev_driver *di = &demo_driver_info;
6239c175 165
6078d2c9 166static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 167
c07f60e7 168
6078d2c9 169static int init(struct sr_context *sr_ctx)
61136ea6 170{
f6beaac5 171 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
172}
173
4374219b 174static void generate_analog_pattern(const struct sr_probe_group *probe_group, uint64_t sample_rate)
8b2d41ed
BV
175{
176 struct analog_gen *ag;
4374219b 177 double t, frequency;
8b2d41ed
BV
178 float value;
179 unsigned int num_samples, i;
180 int last_end;
181
182 ag = probe_group->priv;
4374219b
DJ
183 num_samples = ANALOG_BUFSIZE / sizeof(float);
184
185 sr_dbg("Generating %s pattern for probe group %s",
186 analog_pattern_str[ag->pattern],
187 probe_group->name);
8b2d41ed 188
4374219b 189 switch (ag->pattern) {
8b2d41ed 190 case PATTERN_SQUARE:
2438b737 191 value = ANALOG_AMPLITUDE;
8b2d41ed
BV
192 last_end = 0;
193 for (i = 0; i < num_samples; i++) {
194 if (i % 5 == 0)
195 value = -value;
196 if (i % 10 == 0)
197 last_end = i - 1;
198 ag->pattern_data[i] = value;
199 }
200 ag->num_samples = last_end;
201 break;
4374219b
DJ
202
203 case PATTERN_SINE:
9d156555 204 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
4374219b
DJ
205
206 /* Make sure the number of samples we put out is an integer
207 * multiple of our period size */
208 /* FIXME we actually need only one period. A ringbuffer would be
209 * usefull here.*/
210 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
211 num_samples--;
212
213 for (i = 0; i < num_samples; i++) {
214 t = (double) i / (double) sample_rate;
215 ag->pattern_data[i] = ANALOG_AMPLITUDE *
216 sin(2 * M_PI * frequency * t);
217 }
218
091c9621
DJ
219 ag->num_samples = num_samples;
220 break;
221
222 case PATTERN_TRIANGLE:
9d156555 223 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
091c9621
DJ
224
225 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
226 num_samples--;
227
228 for (i = 0; i < num_samples; i++) {
229 t = (double) i / (double) sample_rate;
230 ag->pattern_data[i] = (2 * ANALOG_AMPLITUDE / M_PI) *
231 asin(sin(2 * M_PI * frequency * t));
232 }
233
9f54e0e8
DJ
234 ag->num_samples = num_samples;
235 break;
236
237 case PATTERN_SAWTOOTH:
9d156555 238 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
9f54e0e8
DJ
239
240 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
241 num_samples--;
242
243 for (i = 0; i < num_samples; i++) {
244 t = (double) i / (double) sample_rate;
245 ag->pattern_data[i] = 2 * ANALOG_AMPLITUDE *
246 ((t * frequency) - floor(0.5f + t * frequency));
247 }
248
4374219b
DJ
249 ag->num_samples = num_samples;
250 break;
8b2d41ed
BV
251 }
252}
253
6078d2c9 254static GSList *scan(GSList *options)
6239c175 255{
b4750a3a 256 struct drv_context *drvc;
33ef7573 257 struct dev_context *devc;
c07f60e7
BV
258 struct sr_dev_inst *sdi;
259 struct sr_probe *probe;
8b2d41ed 260 struct sr_probe_group *pg;
c07f60e7 261 struct sr_config *src;
8b2d41ed 262 struct analog_gen *ag;
c07f60e7 263 GSList *devices, *l;
2b36d6c6 264 int num_logic_probes, num_analog_probes, pattern, i;
61c39f54 265 char probe_name[16];
067d0716 266
a873c594 267 drvc = di->priv;
4b97c74e 268
c07f60e7
BV
269 num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
270 num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
271 for (l = options; l; l = l->next) {
272 src = l->data;
273 switch (src->key) {
274 case SR_CONF_NUM_LOGIC_PROBES:
275 num_logic_probes = g_variant_get_int32(src->data);
276 break;
277 case SR_CONF_NUM_ANALOG_PROBES:
278 num_analog_probes = g_variant_get_int32(src->data);
279 break;
280 }
281 }
85b5af06 282
c07f60e7 283 devices = NULL;
61c39f54 284 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
c03ed397 285 if (!sdi) {
e45ad6e2
UH
286 sr_err("Device instance creation failed.");
287 return NULL;
c03ed397 288 }
a873c594 289 sdi->driver = di;
e15f48c2 290
8b2d41ed
BV
291 if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
292 sr_err("Device context malloc failed.");
293 return NULL;
294 }
295 devc->cur_samplerate = SR_KHZ(200);
296 devc->limit_samples = 0;
297 devc->limit_msec = 0;
298 devc->step = 0;
299 devc->num_logic_probes = num_logic_probes;
300 devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
301 devc->logic_pattern = PATTERN_SIGROK;
302 devc->num_analog_probes = num_analog_probes;
303 devc->analog_probe_groups = NULL;
304
305 /* Logic probes, all in one probe group. */
306 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
307 return NULL;
308 pg->name = g_strdup("Logic");
309 pg->probes = NULL;
310 pg->priv = NULL;
c07f60e7 311 for (i = 0; i < num_logic_probes; i++) {
61c39f54
BV
312 sprintf(probe_name, "D%d", i);
313 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
87ca93c5
BV
314 return NULL;
315 sdi->probes = g_slist_append(sdi->probes, probe);
8b2d41ed 316 pg->probes = g_slist_append(pg->probes, probe);
87ca93c5 317 }
8b2d41ed 318 sdi->probe_groups = g_slist_append(NULL, pg);
87ca93c5 319
8b2d41ed 320 /* Analog probes, probe groups and pattern generators. */
2b36d6c6
BV
321
322 pattern = 0;
c07f60e7
BV
323 for (i = 0; i < num_analog_probes; i++) {
324 sprintf(probe_name, "A%d", i);
03aa381e
BV
325 if (!(probe = sr_probe_new(i + num_logic_probes,
326 SR_PROBE_ANALOG, TRUE, probe_name)))
c07f60e7
BV
327 return NULL;
328 sdi->probes = g_slist_append(sdi->probes, probe);
c07f60e7 329
8b2d41ed
BV
330 /* Every analog probe gets its own probe group. */
331 if (!(pg = g_try_malloc(sizeof(struct sr_probe_group))))
332 return NULL;
333 pg->name = g_strdup(probe_name);
334 pg->probes = g_slist_append(NULL, probe);
85b5af06 335
8b2d41ed
BV
336 /* Every probe group gets a generator struct. */
337 if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
338 return NULL;
339 ag->packet.probes = pg->probes;
340 ag->packet.mq = 0;
341 ag->packet.mqflags = 0;
342 ag->packet.unit = SR_UNIT_VOLT;
343 ag->packet.data = ag->pattern_data;
2b36d6c6 344 ag->pattern = pattern;
8b2d41ed 345 pg->priv = ag;
8b2d41ed
BV
346
347 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
348 devc->analog_probe_groups = g_slist_append(devc->analog_probe_groups, pg);
2b36d6c6
BV
349
350 if (++pattern == ARRAY_SIZE(analog_pattern_str))
351 pattern = 0;
33ef7573 352 }
33ef7573
JH
353
354 sdi->priv = devc;
8b2d41ed
BV
355 devices = g_slist_append(devices, sdi);
356 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 357
067d0716 358 return devices;
6239c175
UH
359}
360
6078d2c9 361static GSList *dev_list(void)
811deee4 362{
0e94d524 363 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
364}
365
6078d2c9 366static int dev_open(struct sr_dev_inst *sdi)
6239c175 367{
e73ffd42 368 sdi->status = SR_ST_ACTIVE;
697785d1 369
e46b8fb1 370 return SR_OK;
6239c175
UH
371}
372
6078d2c9 373static int dev_close(struct sr_dev_inst *sdi)
6239c175 374{
decfe89d 375 sdi->status = SR_ST_INACTIVE;
697785d1
UH
376
377 return SR_OK;
6239c175
UH
378}
379
6078d2c9 380static int cleanup(void)
6239c175 381{
a6630742 382 return std_dev_clear(di, NULL);
6239c175
UH
383}
384
8f996b89
ML
385static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
386 const struct sr_probe_group *probe_group)
6239c175 387{
c07f60e7 388 struct dev_context *devc;
2388ae86
BV
389 struct sr_probe *probe;
390 struct analog_gen *ag;
391 int pattern;
6f57fd96 392
2388ae86
BV
393 if (!sdi)
394 return SR_ERR_ARG;
8f996b89 395
c07f60e7 396 devc = sdi->priv;
035a1078 397 switch (id) {
123e1313 398 case SR_CONF_SAMPLERATE:
a7684294 399 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 400 break;
2474d87e 401 case SR_CONF_LIMIT_SAMPLES:
a7684294 402 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
403 break;
404 case SR_CONF_LIMIT_MSEC:
a7684294 405 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e
BV
406 break;
407 case SR_CONF_PATTERN_MODE:
2388ae86
BV
408 if (!probe_group)
409 return SR_ERR_PROBE_GROUP;
410 probe = probe_group->probes->data;
411 if (probe->type == SR_PROBE_LOGIC) {
412 pattern = devc->logic_pattern;
413 *data = g_variant_new_string(logic_pattern_str[pattern]);
414 } else if (probe->type == SR_PROBE_ANALOG) {
415 ag = probe_group->priv;
416 pattern = ag->pattern;
417 *data = g_variant_new_string(analog_pattern_str[pattern]);
418 } else
419 return SR_ERR_BUG;
c07f60e7
BV
420 break;
421 case SR_CONF_NUM_LOGIC_PROBES:
422 *data = g_variant_new_int32(devc->num_logic_probes);
423 break;
424 case SR_CONF_NUM_ANALOG_PROBES:
425 *data = g_variant_new_int32(devc->num_analog_probes);
2474d87e 426 break;
7dfcf010 427 default:
bd6fbf62 428 return SR_ERR_NA;
6239c175
UH
429 }
430
dfb0fa1a 431 return SR_OK;
6239c175
UH
432}
433
8f996b89
ML
434static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
435 const struct sr_probe_group *probe_group)
6239c175 436{
8b2d41ed 437 struct dev_context *devc;
4374219b 438 struct analog_gen *ag;
2388ae86
BV
439 struct sr_probe *probe;
440 int pattern, ret;
61c39f54 441 unsigned int i;
1b79df2f 442 const char *stropt;
6239c175 443
8b2d41ed 444 devc = sdi->priv;
6239c175 445
e73ffd42
BV
446 if (sdi->status != SR_ST_ACTIVE)
447 return SR_ERR_DEV_CLOSED;
448
2388ae86
BV
449 ret = SR_OK;
450 switch (id) {
451 case SR_CONF_SAMPLERATE:
a7684294 452 devc->cur_samplerate = g_variant_get_uint64(data);
61c39f54 453 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
2388ae86
BV
454 break;
455 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
456 devc->limit_msec = 0;
457 devc->limit_samples = g_variant_get_uint64(data);
8b2d41ed 458 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
2388ae86
BV
459 break;
460 case SR_CONF_LIMIT_MSEC:
a7684294
JH
461 devc->limit_msec = g_variant_get_uint64(data);
462 devc->limit_samples = 0;
8b2d41ed 463 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
2388ae86
BV
464 break;
465 case SR_CONF_PATTERN_MODE:
466 if (!probe_group)
467 return SR_ERR_PROBE_GROUP;
d00088ca 468 stropt = g_variant_get_string(data, NULL);
2388ae86
BV
469 probe = probe_group->probes->data;
470 pattern = -1;
471 if (probe->type == SR_PROBE_LOGIC) {
472 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
473 if (!strcmp(stropt, logic_pattern_str[i])) {
474 pattern = i;
8b2d41ed
BV
475 break;
476 }
477 }
2388ae86
BV
478 if (pattern == -1)
479 return SR_ERR_ARG;
480 devc->logic_pattern = pattern;
481
482 /* Might as well do this now, these are static. */
483 if (pattern == PATTERN_ALL_LOW)
8b2d41ed 484 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
2388ae86 485 else if (pattern == PATTERN_ALL_HIGH)
8b2d41ed 486 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
2388ae86
BV
487 sr_dbg("Setting logic pattern to %s",
488 logic_pattern_str[pattern]);
489 } else if (probe->type == SR_PROBE_ANALOG) {
490 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
491 if (!strcmp(stropt, analog_pattern_str[i])) {
492 pattern = i;
493 break;
8b2d41ed 494 }
8b2d41ed 495 }
2388ae86
BV
496 if (pattern == -1)
497 return SR_ERR_ARG;
4374219b
DJ
498 sr_dbg("Setting analog pattern for probe group %s to %s",
499 probe_group->name,
2388ae86 500 analog_pattern_str[pattern]);
4374219b
DJ
501 ag = probe_group->priv;
502 ag->pattern = pattern;
2388ae86
BV
503 } else
504 return SR_ERR_BUG;
505 break;
506 default:
bd6fbf62 507 ret = SR_ERR_NA;
6239c175
UH
508 }
509
510 return ret;
511}
512
8f996b89
ML
513static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
514 const struct sr_probe_group *probe_group)
a1c743fc 515{
7a1da331 516 struct sr_probe *probe;
d00088ca
BV
517 GVariant *gvar;
518 GVariantBuilder gvb;
a1c743fc
BV
519
520 (void)sdi;
521
7a1da331 522 if (key == SR_CONF_SCAN_OPTIONS) {
c07f60e7 523 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
7a1da331
BV
524 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
525 return SR_OK;
526 }
527
528 if (!sdi)
529 return SR_ERR_ARG;
530
531 if (!probe_group) {
532 switch (key) {
533 case SR_CONF_DEVICE_OPTIONS:
534 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
535 devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
536 break;
537 case SR_CONF_SAMPLERATE:
538 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
539 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
540 ARRAY_SIZE(samplerates), sizeof(uint64_t));
541 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
542 *data = g_variant_builder_end(&gvb);
543 break;
544 default:
545 return SR_ERR_NA;
546 }
547 } else {
548 probe = probe_group->probes->data;
549 switch (key) {
550 case SR_CONF_DEVICE_OPTIONS:
551 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
552 devopts_pg, ARRAY_SIZE(devopts_pg), sizeof(int32_t));
553 break;
554 case SR_CONF_PATTERN_MODE:
555 if (probe->type == SR_PROBE_LOGIC)
556 *data = g_variant_new_strv(logic_pattern_str,
557 ARRAY_SIZE(logic_pattern_str));
2388ae86 558 else if (probe->type == SR_PROBE_ANALOG)
7a1da331
BV
559 *data = g_variant_new_strv(analog_pattern_str,
560 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
561 else
562 return SR_ERR_BUG;
7a1da331
BV
563 break;
564 default:
565 return SR_ERR_NA;
566 }
a1c743fc
BV
567 }
568
569 return SR_OK;
570}
571
c07f60e7 572static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 573{
61c39f54 574 struct dev_context *devc;
c07f60e7
BV
575 uint64_t i, j;
576 uint8_t pat;
85b5af06 577
61c39f54 578 devc = sdi->priv;
85b5af06 579
c07f60e7 580 switch (devc->logic_pattern) {
61c39f54 581 case PATTERN_SIGROK:
c07f60e7
BV
582 memset(devc->logic_data, 0x00, size);
583 for (i = 0; i < size; i += devc->logic_unitsize) {
584 for (j = 0; j < devc->logic_unitsize; j++) {
585 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
586 devc->logic_data[i + j] = ~pat;
587 }
588 devc->step++;
917e0e71
BV
589 }
590 break;
61c39f54 591 case PATTERN_RANDOM:
5096c6a6 592 for (i = 0; i < size; i++)
61c39f54 593 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 594 break;
61c39f54 595 case PATTERN_INC:
c07f60e7
BV
596 for (i = 0; i < size; i++) {
597 for (j = 0; j < devc->logic_unitsize; j++) {
598 devc->logic_data[i + j] = devc->step;
599 }
600 devc->step++;
601 }
c03ed397 602 break;
61c39f54
BV
603 case PATTERN_ALL_LOW:
604 case PATTERN_ALL_HIGH:
605 /* These were set when the pattern mode was selected. */
c03ed397
UH
606 break;
607 default:
c07f60e7 608 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 609 break;
85b5af06
UH
610 }
611}
612
85b5af06 613/* Callback handling data */
61c39f54 614static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 615{
61c39f54
BV
616 struct sr_dev_inst *sdi;
617 struct dev_context *devc;
b9c735a2 618 struct sr_datafeed_packet packet;
9c939c51 619 struct sr_datafeed_logic logic;
8b2d41ed
BV
620 struct sr_probe_group *pg;
621 struct analog_gen *ag;
622 GSList *l;
7f4975b4 623 uint64_t logic_todo, analog_todo, expected_samplenum, analog_samples, sending_now;
3b203673 624 int64_t time, elapsed;
1924f59f 625
cb93f8a9
UH
626 (void)fd;
627 (void)revents;
1924f59f 628
61c39f54
BV
629 sdi = cb_data;
630 devc = sdi->priv;
631
3b203673
AG
632 /* How many "virtual" samples should we have collected by now? */
633 time = g_get_monotonic_time();
634 elapsed = time - devc->starttime;
a7684294 635 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
7f4975b4 636
3b203673 637 /* Of those, how many do we still have to send? */
fe90fbb7
BV
638 logic_todo = MIN(expected_samplenum, devc->limit_samples) - devc->logic_counter;
639 analog_todo = MIN(expected_samplenum, devc->limit_samples) - devc->analog_counter;
85b5af06 640
7f4975b4 641 while (logic_todo || analog_todo) {
c07f60e7 642 /* Logic */
7f4975b4
BV
643 if (devc->num_logic_probes > 0 && logic_todo > 0) {
644 sending_now = MIN(logic_todo,
8b2d41ed
BV
645 LOGIC_BUFSIZE / devc->logic_unitsize);
646 logic_generator(sdi, sending_now * devc->logic_unitsize);
647 packet.type = SR_DF_LOGIC;
648 packet.payload = &logic;
649 logic.length = sending_now * devc->logic_unitsize;
650 logic.unitsize = devc->logic_unitsize;
651 logic.data = devc->logic_data;
652 sr_session_send(sdi, &packet);
7f4975b4
BV
653 logic_todo -= sending_now;
654 devc->logic_counter += sending_now;
8b2d41ed
BV
655 }
656
657 /* Analog, one probe at a time */
7f4975b4 658 if (devc->num_analog_probes > 0 && analog_todo > 0) {
8b2d41ed
BV
659 sending_now = 0;
660 for (l = devc->analog_probe_groups; l; l = l->next) {
661 pg = l->data;
662 ag = pg->priv;
663 packet.type = SR_DF_ANALOG;
664 packet.payload = &ag->packet;
4374219b
DJ
665
666 /* FIXME we should make sure we output a whole
667 * period of data before we send out again the
668 * beginning of our buffer. A ring buffer would
669 * help here as well */
670
7f4975b4 671 analog_samples = MIN(analog_todo, ag->num_samples);
8b2d41ed
BV
672 /* Whichever probe group gets there first. */
673 sending_now = MAX(sending_now, analog_samples);
674 ag->packet.num_samples = analog_samples;
675 sr_session_send(sdi, &packet);
676 }
7f4975b4
BV
677 analog_todo -= sending_now;
678 devc->analog_counter += sending_now;
8b2d41ed 679 }
3b203673
AG
680 }
681
fe90fbb7 682 if (devc->logic_counter >= devc->limit_samples &&
7f4975b4
BV
683 devc->analog_counter >= devc->limit_samples) {
684 sr_dbg("Requested number of samples reached.");
61c39f54 685 dev_acquisition_stop(sdi, cb_data);
c216d623 686 return TRUE;
85b5af06 687 }
1924f59f 688
85b5af06
UH
689 return TRUE;
690}
691
6078d2c9 692static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 693{
4374219b 694 GSList *l;
61c39f54 695 struct dev_context *devc;
85b5af06 696
e73ffd42
BV
697 if (sdi->status != SR_ST_ACTIVE)
698 return SR_ERR_DEV_CLOSED;
699
61c39f54 700 devc = sdi->priv;
fe90fbb7
BV
701 if (devc->limit_samples == 0)
702 return SR_ERR;
7f4975b4 703 devc->logic_counter = devc->analog_counter = 0;
85b5af06 704
3b203673
AG
705 /*
706 * Setting two channels connected by a pipe is a remnant from when the
707 * demo driver generated data in a thread, and collected and sent the
708 * data in the main program loop.
709 * They are kept here because it provides a convenient way of setting
710 * up a timeout-based polling mechanism.
711 */
b4750a3a 712 if (pipe(devc->pipe_fds)) {
92bcedf6 713 sr_err("%s: pipe() failed", __func__);
e46b8fb1 714 return SR_ERR;
c03ed397 715 }
85b5af06 716
4374219b
DJ
717 for (l = devc->analog_probe_groups; l; l = l->next) {
718 generate_analog_pattern(l->data, devc->cur_samplerate);
719 }
720
e0532047 721 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
d35aaf02 722
e0532047 723 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 724
d35aaf02 725 /* Set channel encoding to binary (default is UTF-8). */
e0532047 726 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02
UH
727
728 /* Make channels to unbuffered. */
e0532047 729 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 730
e0532047 731 sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
61c39f54 732 40, prepare_data, (void *)sdi);
85b5af06 733
4afdfd46 734 /* Send header packet to the session bus. */
29a27196 735 std_session_send_df_header(cb_data, LOG_PREFIX);
f366e86c 736
3b203673
AG
737 /* We use this timestamp to decide how many more samples to send. */
738 devc->starttime = g_get_monotonic_time();
739
e46b8fb1 740 return SR_OK;
6239c175
UH
741}
742
6078d2c9 743static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 744{
8b2d41ed 745 struct dev_context *devc;
c216d623 746 struct sr_datafeed_packet packet;
7fd3e859 747
33ef7573 748 (void)cb_data;
7fd3e859 749
8b2d41ed 750 devc = sdi->priv;
a84f6ad3 751 sr_dbg("Stopping acquisition.");
49145a63 752
e0532047
JH
753 sr_session_source_remove_channel(devc->channel);
754 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
755 g_io_channel_unref(devc->channel);
756 devc->channel = NULL;
c216d623
AG
757
758 /* Send last packet. */
759 packet.type = SR_DF_END;
c07f60e7 760 sr_session_send(sdi, &packet);
7fd3e859 761
3010f21c 762 return SR_OK;
6239c175
UH
763}
764
c09f0b57 765SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
766 .name = "demo",
767 .longname = "Demo driver and pattern generator",
768 .api_version = 1,
6078d2c9
UH
769 .init = init,
770 .cleanup = cleanup,
771 .scan = scan,
772 .dev_list = dev_list,
a6630742 773 .dev_clear = NULL,
035a1078
BV
774 .config_get = config_get,
775 .config_set = config_set,
a1c743fc 776 .config_list = config_list,
6078d2c9
UH
777 .dev_open = dev_open,
778 .dev_close = dev_close,
779 .dev_acquisition_start = dev_acquisition_start,
780 .dev_acquisition_stop = dev_acquisition_stop,
b4750a3a 781 .priv = NULL,
6239c175 782};