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