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