]> sigrok.org Git - libsigrok.git/blame - hardware/demo/demo.c
demo: Analog probe support.
[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
116static const int32_t hwopts[] = {
117 SR_CONF_NUM_LOGIC_PROBES,
118 SR_CONF_NUM_ANALOG_PROBES,
e15f48c2 119};
85b5af06 120
915f7cc8 121static const int hwcaps[] = {
1953564a
BV
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,
6239c175
UH
128};
129
d00088ca
BV
130static const uint64_t samplerates[] = {
131 SR_HZ(1),
132 SR_GHZ(1),
133 SR_HZ(1),
4bfbf9fc
BV
134};
135
c8f4624d 136static uint8_t pattern_sigrok[] = {
917e0e71
BV
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
dcf03d6d 147SR_PRIV struct sr_dev_driver demo_driver_info;
a873c594 148static struct sr_dev_driver *di = &demo_driver_info;
6239c175 149
6078d2c9 150static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 151
c07f60e7 152
3b412e3a 153static int dev_clear(void)
eebb6067 154{
1c2d542d 155 return std_dev_clear(di, NULL);
eebb6067
UH
156}
157
6078d2c9 158static int init(struct sr_context *sr_ctx)
61136ea6 159{
f6beaac5 160 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
161}
162
8b2d41ed
BV
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
6078d2c9 190static GSList *scan(GSList *options)
6239c175 191{
b4750a3a 192 struct drv_context *drvc;
33ef7573 193 struct dev_context *devc;
c07f60e7
BV
194 struct sr_dev_inst *sdi;
195 struct sr_probe *probe;
8b2d41ed 196 struct sr_probe_group *pg;
c07f60e7 197 struct sr_config *src;
8b2d41ed 198 struct analog_gen *ag;
c07f60e7
BV
199 GSList *devices, *l;
200 int num_logic_probes, num_analog_probes, i;
61c39f54 201 char probe_name[16];
067d0716 202
a873c594 203 drvc = di->priv;
4b97c74e 204
c07f60e7
BV
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 }
85b5af06 218
c07f60e7 219 devices = NULL;
61c39f54 220 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
c03ed397 221 if (!sdi) {
e45ad6e2
UH
222 sr_err("Device instance creation failed.");
223 return NULL;
c03ed397 224 }
a873c594 225 sdi->driver = di;
e15f48c2 226
8b2d41ed
BV
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;
c07f60e7 247 for (i = 0; i < num_logic_probes; i++) {
61c39f54
BV
248 sprintf(probe_name, "D%d", i);
249 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
87ca93c5
BV
250 return NULL;
251 sdi->probes = g_slist_append(sdi->probes, probe);
8b2d41ed 252 pg->probes = g_slist_append(pg->probes, probe);
87ca93c5 253 }
8b2d41ed 254 sdi->probe_groups = g_slist_append(NULL, pg);
87ca93c5 255
8b2d41ed 256 /* Analog probes, probe groups and pattern generators. */
c07f60e7
BV
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);
c07f60e7 262
8b2d41ed
BV
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);
85b5af06 268
8b2d41ed
BV
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);
33ef7573 282 }
33ef7573
JH
283
284 sdi->priv = devc;
8b2d41ed
BV
285 devices = g_slist_append(devices, sdi);
286 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 287
067d0716 288 return devices;
6239c175
UH
289}
290
6078d2c9 291static GSList *dev_list(void)
811deee4 292{
0e94d524 293 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
294}
295
6078d2c9 296static int dev_open(struct sr_dev_inst *sdi)
6239c175 297{
e73ffd42 298 sdi->status = SR_ST_ACTIVE;
697785d1 299
e46b8fb1 300 return SR_OK;
6239c175
UH
301}
302
6078d2c9 303static int dev_close(struct sr_dev_inst *sdi)
6239c175 304{
decfe89d 305 sdi->status = SR_ST_INACTIVE;
697785d1
UH
306
307 return SR_OK;
6239c175
UH
308}
309
6078d2c9 310static int cleanup(void)
6239c175 311{
1c2d542d 312 return dev_clear();
6239c175
UH
313}
314
8f996b89
ML
315static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
316 const struct sr_probe_group *probe_group)
6239c175 317{
c07f60e7 318 struct dev_context *devc;
6f57fd96 319
8f996b89
ML
320 (void)probe_group;
321
c07f60e7 322 devc = sdi->priv;
035a1078 323 switch (id) {
123e1313 324 case SR_CONF_SAMPLERATE:
a7684294 325 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 326 break;
2474d87e 327 case SR_CONF_LIMIT_SAMPLES:
a7684294 328 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
329 break;
330 case SR_CONF_LIMIT_MSEC:
a7684294 331 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e
BV
332 break;
333 case SR_CONF_PATTERN_MODE:
8b2d41ed 334 *data = g_variant_new_string(logic_pattern_str[devc->logic_pattern]);
c07f60e7
BV
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);
2474d87e 341 break;
7dfcf010 342 default:
bd6fbf62 343 return SR_ERR_NA;
6239c175
UH
344 }
345
dfb0fa1a 346 return SR_OK;
6239c175
UH
347}
348
8f996b89
ML
349static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
350 const struct sr_probe_group *probe_group)
6239c175 351{
8b2d41ed
BV
352 struct dev_context *devc;
353 struct sr_probe_group *pg;
354 GSList *l;
355 int logic_pattern, analog_pattern, ret;
61c39f54 356 unsigned int i;
1b79df2f 357 const char *stropt;
6239c175 358
8b2d41ed 359 devc = sdi->priv;
6239c175 360
e73ffd42
BV
361 if (sdi->status != SR_ST_ACTIVE)
362 return SR_ERR_DEV_CLOSED;
363
8b2d41ed 364 ret = SR_ERR;
035a1078 365 if (id == SR_CONF_SAMPLERATE) {
a7684294 366 devc->cur_samplerate = g_variant_get_uint64(data);
61c39f54 367 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
e46b8fb1 368 ret = SR_OK;
035a1078 369 } else if (id == SR_CONF_LIMIT_SAMPLES) {
a7684294
JH
370 devc->limit_msec = 0;
371 devc->limit_samples = g_variant_get_uint64(data);
8b2d41ed 372 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
e46b8fb1 373 ret = SR_OK;
035a1078 374 } else if (id == SR_CONF_LIMIT_MSEC) {
8b2d41ed 375 /* TODO: convert to limit_samples */
a7684294
JH
376 devc->limit_msec = g_variant_get_uint64(data);
377 devc->limit_samples = 0;
8b2d41ed 378 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
e46b8fb1 379 ret = SR_OK;
035a1078 380 } else if (id == SR_CONF_PATTERN_MODE) {
d00088ca 381 stropt = g_variant_get_string(data, NULL);
8b2d41ed
BV
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;
61c39f54
BV
387 break;
388 }
e15f48c2 389 }
8b2d41ed
BV
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 }
6239c175 423 } else {
bd6fbf62 424 ret = SR_ERR_NA;
6239c175
UH
425 }
426
427 return ret;
428}
429
8f996b89
ML
430static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
431 const struct sr_probe_group *probe_group)
a1c743fc 432{
d00088ca
BV
433 GVariant *gvar;
434 GVariantBuilder gvb;
a1c743fc
BV
435
436 (void)sdi;
8f996b89 437 (void)probe_group;
a1c743fc
BV
438
439 switch (key) {
c07f60e7
BV
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;
9a6517d1 444 case SR_CONF_DEVICE_OPTIONS:
d00088ca
BV
445 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
446 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 447 break;
a1c743fc 448 case SR_CONF_SAMPLERATE:
d00088ca
BV
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);
a1c743fc 454 break;
dd96ea98 455 case SR_CONF_PATTERN_MODE:
8b2d41ed 456 *data = g_variant_new_strv(logic_pattern_str, ARRAY_SIZE(logic_pattern_str));
dd96ea98 457 break;
a1c743fc 458 default:
bd6fbf62 459 return SR_ERR_NA;
a1c743fc
BV
460 }
461
462 return SR_OK;
463}
464
c07f60e7 465static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 466{
61c39f54 467 struct dev_context *devc;
c07f60e7
BV
468 uint64_t i, j;
469 uint8_t pat;
85b5af06 470
61c39f54 471 devc = sdi->priv;
85b5af06 472
c07f60e7 473 switch (devc->logic_pattern) {
61c39f54 474 case PATTERN_SIGROK:
c07f60e7
BV
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++;
917e0e71
BV
482 }
483 break;
61c39f54 484 case PATTERN_RANDOM:
5096c6a6 485 for (i = 0; i < size; i++)
61c39f54 486 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 487 break;
61c39f54 488 case PATTERN_INC:
c07f60e7
BV
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 }
c03ed397 495 break;
61c39f54
BV
496 case PATTERN_ALL_LOW:
497 case PATTERN_ALL_HIGH:
498 /* These were set when the pattern mode was selected. */
c03ed397
UH
499 break;
500 default:
c07f60e7 501 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 502 break;
85b5af06
UH
503 }
504}
505
85b5af06 506/* Callback handling data */
61c39f54 507static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 508{
61c39f54
BV
509 struct sr_dev_inst *sdi;
510 struct dev_context *devc;
b9c735a2 511 struct sr_datafeed_packet packet;
9c939c51 512 struct sr_datafeed_logic logic;
8b2d41ed
BV
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;
3b203673 517 int64_t time, elapsed;
1924f59f 518
cb93f8a9
UH
519 (void)fd;
520 (void)revents;
1924f59f 521
61c39f54
BV
522 sdi = cb_data;
523 devc = sdi->priv;
524
3b203673
AG
525 /* How many "virtual" samples should we have collected by now? */
526 time = g_get_monotonic_time();
527 elapsed = time - devc->starttime;
a7684294 528 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
3b203673
AG
529 /* Of those, how many do we still have to send? */
530 samples_to_send = expected_samplenum - devc->samples_counter;
531
a7684294 532 if (devc->limit_samples) {
3b203673 533 samples_to_send = MIN(samples_to_send,
c07f60e7 534 devc->limit_samples - devc->samples_counter);
3b203673 535 }
85b5af06 536
3b203673 537 while (samples_to_send > 0) {
8b2d41ed 538 sending_now = 0;
3b203673 539
c07f60e7 540 /* Logic */
8b2d41ed
BV
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;
3b203673
AG
570 devc->samples_counter += sending_now;
571 }
572
a7684294
JH
573 if (devc->limit_samples &&
574 devc->samples_counter >= devc->limit_samples) {
35e199da 575 sr_info("Requested number of samples reached.");
61c39f54 576 dev_acquisition_stop(sdi, cb_data);
c216d623 577 return TRUE;
85b5af06 578 }
1924f59f 579
85b5af06
UH
580 return TRUE;
581}
582
6078d2c9 583static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 584{
61c39f54 585 struct dev_context *devc;
85b5af06 586
e73ffd42
BV
587 if (sdi->status != SR_ST_ACTIVE)
588 return SR_ERR_DEV_CLOSED;
589
8b2d41ed 590 /* TODO: don't start without a sample limit set */
61c39f54 591 devc = sdi->priv;
b4750a3a 592 devc->samples_counter = 0;
85b5af06 593
3b203673
AG
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 */
b4750a3a 601 if (pipe(devc->pipe_fds)) {
92bcedf6 602 sr_err("%s: pipe() failed", __func__);
e46b8fb1 603 return SR_ERR;
c03ed397 604 }
85b5af06 605
e0532047 606 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
d35aaf02 607
e0532047 608 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 609
d35aaf02 610 /* Set channel encoding to binary (default is UTF-8). */
e0532047 611 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02
UH
612
613 /* Make channels to unbuffered. */
e0532047 614 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 615
e0532047 616 sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
61c39f54 617 40, prepare_data, (void *)sdi);
85b5af06 618
4afdfd46 619 /* Send header packet to the session bus. */
29a27196 620 std_session_send_df_header(cb_data, LOG_PREFIX);
f366e86c 621
3b203673
AG
622 /* We use this timestamp to decide how many more samples to send. */
623 devc->starttime = g_get_monotonic_time();
624
e46b8fb1 625 return SR_OK;
6239c175
UH
626}
627
6078d2c9 628static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 629{
8b2d41ed 630 struct dev_context *devc;
c216d623 631 struct sr_datafeed_packet packet;
7fd3e859 632
33ef7573 633 (void)cb_data;
7fd3e859 634
8b2d41ed 635 devc = sdi->priv;
49145a63
AG
636 sr_dbg("Stopping aquisition.");
637
e0532047
JH
638 sr_session_source_remove_channel(devc->channel);
639 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
640 g_io_channel_unref(devc->channel);
641 devc->channel = NULL;
c216d623
AG
642
643 /* Send last packet. */
644 packet.type = SR_DF_END;
c07f60e7 645 sr_session_send(sdi, &packet);
7fd3e859 646
3010f21c 647 return SR_OK;
6239c175
UH
648}
649
c09f0b57 650SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
651 .name = "demo",
652 .longname = "Demo driver and pattern generator",
653 .api_version = 1,
6078d2c9
UH
654 .init = init,
655 .cleanup = cleanup,
656 .scan = scan,
657 .dev_list = dev_list,
3b412e3a 658 .dev_clear = dev_clear,
035a1078
BV
659 .config_get = config_get,
660 .config_set = config_set,
a1c743fc 661 .config_list = config_list,
6078d2c9
UH
662 .dev_open = dev_open,
663 .dev_close = dev_close,
664 .dev_acquisition_start = dev_acquisition_start,
665 .dev_acquisition_stop = dev_acquisition_stop,
b4750a3a 666 .priv = NULL,
6239c175 667};