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