]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
Add config key for amplitude.
[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
ed0b7fed
BV
382static void clear_helper(void *priv)
383{
384 struct dev_context *devc;
385 struct sr_channel_group *cg;
386 GSList *l;
387
388 devc = priv;
389 for (l = devc->analog_channel_groups; l; l = l->next) {
390 cg = l->data;
391 /* Analog generators. */
392 g_free(cg->priv);
393 }
394 g_slist_free(devc->analog_channel_groups);
395 g_free(devc);
396}
397
6078d2c9 398static int cleanup(void)
6239c175 399{
ed0b7fed 400 return std_dev_clear(di, clear_helper);
6239c175
UH
401}
402
8f996b89 403static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 404 const struct sr_channel_group *cg)
6239c175 405{
c07f60e7 406 struct dev_context *devc;
ba7dd8bb 407 struct sr_channel *ch;
2388ae86
BV
408 struct analog_gen *ag;
409 int pattern;
6f57fd96 410
2388ae86
BV
411 if (!sdi)
412 return SR_ERR_ARG;
8f996b89 413
c07f60e7 414 devc = sdi->priv;
035a1078 415 switch (id) {
123e1313 416 case SR_CONF_SAMPLERATE:
a7684294 417 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 418 break;
2474d87e 419 case SR_CONF_LIMIT_SAMPLES:
a7684294 420 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
421 break;
422 case SR_CONF_LIMIT_MSEC:
a7684294 423 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e
BV
424 break;
425 case SR_CONF_PATTERN_MODE:
53b4680f 426 if (!cg)
660e398f 427 return SR_ERR_CHANNEL_GROUP;
ba7dd8bb 428 ch = cg->channels->data;
3f239f08 429 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
430 pattern = devc->logic_pattern;
431 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 432 } else if (ch->type == SR_CHANNEL_ANALOG) {
53b4680f 433 ag = cg->priv;
2388ae86
BV
434 pattern = ag->pattern;
435 *data = g_variant_new_string(analog_pattern_str[pattern]);
436 } else
437 return SR_ERR_BUG;
c07f60e7 438 break;
3f239f08 439 case SR_CONF_NUM_LOGIC_CHANNELS:
ba7dd8bb 440 *data = g_variant_new_int32(devc->num_logic_channels);
c07f60e7 441 break;
3f239f08 442 case SR_CONF_NUM_ANALOG_CHANNELS:
ba7dd8bb 443 *data = g_variant_new_int32(devc->num_analog_channels);
2474d87e 444 break;
7dfcf010 445 default:
bd6fbf62 446 return SR_ERR_NA;
6239c175
UH
447 }
448
dfb0fa1a 449 return SR_OK;
6239c175
UH
450}
451
8f996b89 452static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 453 const struct sr_channel_group *cg)
6239c175 454{
8b2d41ed 455 struct dev_context *devc;
4374219b 456 struct analog_gen *ag;
ba7dd8bb 457 struct sr_channel *ch;
2388ae86 458 int pattern, ret;
61c39f54 459 unsigned int i;
1b79df2f 460 const char *stropt;
6239c175 461
8b2d41ed 462 devc = sdi->priv;
6239c175 463
e73ffd42
BV
464 if (sdi->status != SR_ST_ACTIVE)
465 return SR_ERR_DEV_CLOSED;
466
2388ae86
BV
467 ret = SR_OK;
468 switch (id) {
469 case SR_CONF_SAMPLERATE:
a7684294 470 devc->cur_samplerate = g_variant_get_uint64(data);
61c39f54 471 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
2388ae86
BV
472 break;
473 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
474 devc->limit_msec = 0;
475 devc->limit_samples = g_variant_get_uint64(data);
8b2d41ed 476 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
2388ae86
BV
477 break;
478 case SR_CONF_LIMIT_MSEC:
a7684294
JH
479 devc->limit_msec = g_variant_get_uint64(data);
480 devc->limit_samples = 0;
8b2d41ed 481 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
2388ae86
BV
482 break;
483 case SR_CONF_PATTERN_MODE:
53b4680f 484 if (!cg)
660e398f 485 return SR_ERR_CHANNEL_GROUP;
d00088ca 486 stropt = g_variant_get_string(data, NULL);
ba7dd8bb 487 ch = cg->channels->data;
2388ae86 488 pattern = -1;
3f239f08 489 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
490 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
491 if (!strcmp(stropt, logic_pattern_str[i])) {
492 pattern = i;
8b2d41ed
BV
493 break;
494 }
495 }
2388ae86
BV
496 if (pattern == -1)
497 return SR_ERR_ARG;
498 devc->logic_pattern = pattern;
499
500 /* Might as well do this now, these are static. */
501 if (pattern == PATTERN_ALL_LOW)
8b2d41ed 502 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
2388ae86 503 else if (pattern == PATTERN_ALL_HIGH)
8b2d41ed 504 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
2388ae86
BV
505 sr_dbg("Setting logic pattern to %s",
506 logic_pattern_str[pattern]);
3f239f08 507 } else if (ch->type == SR_CHANNEL_ANALOG) {
2388ae86
BV
508 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
509 if (!strcmp(stropt, analog_pattern_str[i])) {
510 pattern = i;
511 break;
8b2d41ed 512 }
8b2d41ed 513 }
2388ae86
BV
514 if (pattern == -1)
515 return SR_ERR_ARG;
660e398f 516 sr_dbg("Setting analog pattern for channel group %s to %s",
53b4680f
UH
517 cg->name, analog_pattern_str[pattern]);
518 ag = cg->priv;
4374219b 519 ag->pattern = pattern;
2388ae86
BV
520 } else
521 return SR_ERR_BUG;
522 break;
523 default:
bd6fbf62 524 ret = SR_ERR_NA;
6239c175
UH
525 }
526
527 return ret;
528}
529
8f996b89 530static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 531 const struct sr_channel_group *cg)
a1c743fc 532{
ba7dd8bb 533 struct sr_channel *ch;
d00088ca
BV
534 GVariant *gvar;
535 GVariantBuilder gvb;
a1c743fc
BV
536
537 (void)sdi;
538
7a1da331 539 if (key == SR_CONF_SCAN_OPTIONS) {
c07f60e7 540 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
7a1da331
BV
541 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
542 return SR_OK;
543 }
544
545 if (!sdi)
546 return SR_ERR_ARG;
547
53b4680f 548 if (!cg) {
7a1da331
BV
549 switch (key) {
550 case SR_CONF_DEVICE_OPTIONS:
551 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
552 devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
553 break;
554 case SR_CONF_SAMPLERATE:
555 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
556 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
557 ARRAY_SIZE(samplerates), sizeof(uint64_t));
558 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
559 *data = g_variant_builder_end(&gvb);
560 break;
561 default:
562 return SR_ERR_NA;
563 }
564 } else {
ba7dd8bb 565 ch = cg->channels->data;
7a1da331
BV
566 switch (key) {
567 case SR_CONF_DEVICE_OPTIONS:
568 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
40fd0264 569 devopts_cg, ARRAY_SIZE(devopts_cg), sizeof(int32_t));
7a1da331
BV
570 break;
571 case SR_CONF_PATTERN_MODE:
3f239f08 572 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
573 *data = g_variant_new_strv(logic_pattern_str,
574 ARRAY_SIZE(logic_pattern_str));
3f239f08 575 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
576 *data = g_variant_new_strv(analog_pattern_str,
577 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
578 else
579 return SR_ERR_BUG;
7a1da331
BV
580 break;
581 default:
582 return SR_ERR_NA;
583 }
a1c743fc
BV
584 }
585
586 return SR_OK;
587}
588
c07f60e7 589static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 590{
61c39f54 591 struct dev_context *devc;
c07f60e7
BV
592 uint64_t i, j;
593 uint8_t pat;
85b5af06 594
61c39f54 595 devc = sdi->priv;
85b5af06 596
c07f60e7 597 switch (devc->logic_pattern) {
61c39f54 598 case PATTERN_SIGROK:
c07f60e7
BV
599 memset(devc->logic_data, 0x00, size);
600 for (i = 0; i < size; i += devc->logic_unitsize) {
601 for (j = 0; j < devc->logic_unitsize; j++) {
602 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
603 devc->logic_data[i + j] = ~pat;
604 }
605 devc->step++;
917e0e71
BV
606 }
607 break;
61c39f54 608 case PATTERN_RANDOM:
5096c6a6 609 for (i = 0; i < size; i++)
61c39f54 610 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 611 break;
61c39f54 612 case PATTERN_INC:
c07f60e7
BV
613 for (i = 0; i < size; i++) {
614 for (j = 0; j < devc->logic_unitsize; j++) {
615 devc->logic_data[i + j] = devc->step;
616 }
617 devc->step++;
618 }
c03ed397 619 break;
61c39f54
BV
620 case PATTERN_ALL_LOW:
621 case PATTERN_ALL_HIGH:
622 /* These were set when the pattern mode was selected. */
c03ed397
UH
623 break;
624 default:
c07f60e7 625 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 626 break;
85b5af06
UH
627 }
628}
629
85b5af06 630/* Callback handling data */
61c39f54 631static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 632{
61c39f54
BV
633 struct sr_dev_inst *sdi;
634 struct dev_context *devc;
b9c735a2 635 struct sr_datafeed_packet packet;
9c939c51 636 struct sr_datafeed_logic logic;
40fd0264 637 struct sr_channel_group *cg;
8b2d41ed
BV
638 struct analog_gen *ag;
639 GSList *l;
b62bb97a 640 uint64_t logic_todo, analog_todo, expected_samplenum, analog_sent, sending_now;
3b203673 641 int64_t time, elapsed;
1924f59f 642
cb93f8a9
UH
643 (void)fd;
644 (void)revents;
1924f59f 645
61c39f54
BV
646 sdi = cb_data;
647 devc = sdi->priv;
b62bb97a 648 logic_todo = analog_todo = 0;
61c39f54 649
b62bb97a 650 /* How many samples should we have sent by now? */
3b203673
AG
651 time = g_get_monotonic_time();
652 elapsed = time - devc->starttime;
a7684294 653 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
7f4975b4 654
b62bb97a
BV
655 /* But never more than the limit, if there is one. */
656 if (!devc->continuous)
657 expected_samplenum = MIN(expected_samplenum, devc->limit_samples);
658
3b203673 659 /* Of those, how many do we still have to send? */
b62bb97a
BV
660 if (devc->num_logic_channels)
661 logic_todo = expected_samplenum - devc->logic_counter;
662 if (devc->num_analog_channels)
663 analog_todo = expected_samplenum - devc->analog_counter;
85b5af06 664
7f4975b4 665 while (logic_todo || analog_todo) {
c07f60e7 666 /* Logic */
b62bb97a
BV
667 if (logic_todo > 0) {
668 sending_now = MIN(logic_todo, LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
669 logic_generator(sdi, sending_now * devc->logic_unitsize);
670 packet.type = SR_DF_LOGIC;
671 packet.payload = &logic;
672 logic.length = sending_now * devc->logic_unitsize;
673 logic.unitsize = devc->logic_unitsize;
674 logic.data = devc->logic_data;
675 sr_session_send(sdi, &packet);
7f4975b4
BV
676 logic_todo -= sending_now;
677 devc->logic_counter += sending_now;
8b2d41ed
BV
678 }
679
ba7dd8bb 680 /* Analog, one channel at a time */
b62bb97a
BV
681 if (analog_todo > 0) {
682 analog_sent = 0;
660e398f 683 for (l = devc->analog_channel_groups; l; l = l->next) {
40fd0264
UH
684 cg = l->data;
685 ag = cg->priv;
8b2d41ed
BV
686 packet.type = SR_DF_ANALOG;
687 packet.payload = &ag->packet;
4374219b
DJ
688
689 /* FIXME we should make sure we output a whole
690 * period of data before we send out again the
691 * beginning of our buffer. A ring buffer would
692 * help here as well */
693
b62bb97a
BV
694 sending_now = MIN(analog_todo, ag->num_samples);
695 ag->packet.num_samples = sending_now;
8b2d41ed 696 sr_session_send(sdi, &packet);
b62bb97a
BV
697
698 /* Whichever channel group gets there first. */
699 analog_sent = MAX(analog_sent, sending_now);
8b2d41ed 700 }
b62bb97a
BV
701 analog_todo -= analog_sent;
702 devc->analog_counter += analog_sent;
8b2d41ed 703 }
3b203673
AG
704 }
705
b62bb97a
BV
706 if (!devc->continuous
707 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
708 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
7f4975b4 709 sr_dbg("Requested number of samples reached.");
61c39f54 710 dev_acquisition_stop(sdi, cb_data);
c216d623 711 return TRUE;
85b5af06 712 }
1924f59f 713
85b5af06
UH
714 return TRUE;
715}
716
6078d2c9 717static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 718{
4374219b 719 GSList *l;
61c39f54 720 struct dev_context *devc;
85b5af06 721
102f1239
BV
722 (void)cb_data;
723
e73ffd42
BV
724 if (sdi->status != SR_ST_ACTIVE)
725 return SR_ERR_DEV_CLOSED;
726
61c39f54 727 devc = sdi->priv;
b62bb97a 728 devc->continuous = !devc->limit_samples;
7f4975b4 729 devc->logic_counter = devc->analog_counter = 0;
85b5af06 730
3b203673
AG
731 /*
732 * Setting two channels connected by a pipe is a remnant from when the
733 * demo driver generated data in a thread, and collected and sent the
734 * data in the main program loop.
735 * They are kept here because it provides a convenient way of setting
736 * up a timeout-based polling mechanism.
737 */
b4750a3a 738 if (pipe(devc->pipe_fds)) {
92bcedf6 739 sr_err("%s: pipe() failed", __func__);
e46b8fb1 740 return SR_ERR;
c03ed397 741 }
85b5af06 742
b62bb97a 743 for (l = devc->analog_channel_groups; l; l = l->next)
4374219b 744 generate_analog_pattern(l->data, devc->cur_samplerate);
4374219b 745
e0532047 746 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
e0532047 747 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 748
d35aaf02 749 /* Set channel encoding to binary (default is UTF-8). */
e0532047 750 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02 751
b62bb97a 752 /* Make channels unbuffered. */
e0532047 753 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 754
b62bb97a
BV
755 sr_session_source_add_channel(sdi->session, devc->channel,
756 G_IO_IN | G_IO_ERR, 40, prepare_data, (void *)sdi);
85b5af06 757
4afdfd46 758 /* Send header packet to the session bus. */
102f1239 759 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 760
3b203673
AG
761 /* We use this timestamp to decide how many more samples to send. */
762 devc->starttime = g_get_monotonic_time();
763
e46b8fb1 764 return SR_OK;
6239c175
UH
765}
766
6078d2c9 767static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 768{
8b2d41ed 769 struct dev_context *devc;
c216d623 770 struct sr_datafeed_packet packet;
7fd3e859 771
33ef7573 772 (void)cb_data;
7fd3e859 773
8b2d41ed 774 devc = sdi->priv;
a84f6ad3 775 sr_dbg("Stopping acquisition.");
49145a63 776
102f1239 777 sr_session_source_remove_channel(sdi->session, devc->channel);
e0532047 778 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
779 g_io_channel_unref(devc->channel);
780 devc->channel = NULL;
c216d623
AG
781
782 /* Send last packet. */
783 packet.type = SR_DF_END;
c07f60e7 784 sr_session_send(sdi, &packet);
7fd3e859 785
3010f21c 786 return SR_OK;
6239c175
UH
787}
788
c09f0b57 789SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
790 .name = "demo",
791 .longname = "Demo driver and pattern generator",
792 .api_version = 1,
6078d2c9
UH
793 .init = init,
794 .cleanup = cleanup,
795 .scan = scan,
796 .dev_list = dev_list,
a6630742 797 .dev_clear = NULL,
035a1078
BV
798 .config_get = config_get,
799 .config_set = config_set,
a1c743fc 800 .config_list = config_list,
6078d2c9
UH
801 .dev_open = dev_open,
802 .dev_close = dev_close,
803 .dev_acquisition_start = dev_acquisition_start,
804 .dev_acquisition_stop = dev_acquisition_stop,
b4750a3a 805 .priv = NULL,
6239c175 806};