]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
Construct driver array at runtime, from an array of per-file arrays.
[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>
7a8a1aba 7 * Copyright (C) 2015 Bartosz Golaszewski <bgolaszewski@baylibre.com>
6239c175
UH
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <stdlib.h>
85b5af06 25#include <unistd.h>
6239c175 26#include <string.h>
4374219b 27#include <math.h>
d35aaf02
UH
28#ifdef _WIN32
29#include <io.h>
30#include <fcntl.h>
31#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
32#endif
45c59c8b
BV
33#include "libsigrok.h"
34#include "libsigrok-internal.h"
6239c175 35
3544f848 36#define LOG_PREFIX "demo"
92bcedf6 37
3f239f08
UH
38#define DEFAULT_NUM_LOGIC_CHANNELS 8
39#define DEFAULT_NUM_ANALOG_CHANNELS 4
c03ed397 40
8b2d41ed 41/* The size in bytes of chunks to send through the session bus. */
61c39f54 42#define LOGIC_BUFSIZE 4096
8b2d41ed
BV
43/* Size of the analog pattern space per channel. */
44#define ANALOG_BUFSIZE 4096
2474d87e 45
dddabe37 46#define DEFAULT_ANALOG_AMPLITUDE 25
4374219b
DJ
47#define ANALOG_SAMPLES_PER_PERIOD 20
48
2388ae86 49/* Logic patterns we can generate. */
e15f48c2 50enum {
0d31276b 51 /**
ba7dd8bb 52 * Spells "sigrok" across 8 channels using '0's (with '1's as
61c39f54 53 * "background") when displayed using the 'bits' output format.
95035832 54 * The pattern is repeated every 8 channels, shifted to the right
c07f60e7 55 * in time by one bit.
0d31276b 56 */
c8f4624d 57 PATTERN_SIGROK,
0d31276b 58
ba7dd8bb 59 /** Pseudo-random values on all channels. */
c8f4624d 60 PATTERN_RANDOM,
0d31276b
UH
61
62 /**
95035832 63 * Incrementing number across 8 channels. The pattern is repeated
ba7dd8bb 64 * every 8 channels, shifted to the right in time by one bit.
0d31276b 65 */
c8f4624d 66 PATTERN_INC,
c03ed397 67
ba7dd8bb 68 /** All channels have a low logic state. */
c03ed397
UH
69 PATTERN_ALL_LOW,
70
ba7dd8bb 71 /** All channels have a high logic state. */
c03ed397 72 PATTERN_ALL_HIGH,
2388ae86 73};
8b2d41ed 74
2388ae86
BV
75/* Analog patterns we can generate. */
76enum {
8b2d41ed
BV
77 /**
78 * Square wave.
79 */
80 PATTERN_SQUARE,
4374219b 81 PATTERN_SINE,
091c9621 82 PATTERN_TRIANGLE,
9f54e0e8 83 PATTERN_SAWTOOTH,
e15f48c2 84};
85b5af06 85
8b2d41ed 86static const char *logic_pattern_str[] = {
61c39f54
BV
87 "sigrok",
88 "random",
89 "incremental",
90 "all-low",
91 "all-high",
92};
93
8b2d41ed
BV
94static const char *analog_pattern_str[] = {
95 "square",
4374219b 96 "sine",
091c9621 97 "triangle",
9f54e0e8 98 "sawtooth",
8b2d41ed
BV
99};
100
101struct analog_gen {
102 int pattern;
dddabe37 103 float amplitude;
8b2d41ed
BV
104 float pattern_data[ANALOG_BUFSIZE];
105 unsigned int num_samples;
106 struct sr_datafeed_analog packet;
7a8a1aba
BG
107 float avg_val; /* Average value */
108 unsigned num_avgs; /* Number of samples averaged */
8b2d41ed
BV
109};
110
b4750a3a
BV
111/* Private, per-device-instance driver context. */
112struct dev_context {
e15f48c2 113 int pipe_fds[2];
e0532047 114 GIOChannel *channel;
a7684294 115 uint64_t cur_samplerate;
b62bb97a 116 gboolean continuous;
a7684294
JH
117 uint64_t limit_samples;
118 uint64_t limit_msec;
7f4975b4
BV
119 uint64_t logic_counter;
120 uint64_t analog_counter;
3b203673 121 int64_t starttime;
61c39f54 122 uint64_t step;
8b2d41ed 123 /* Logic */
ba7dd8bb 124 int32_t num_logic_channels;
c07f60e7 125 unsigned int logic_unitsize;
660e398f 126 /* There is only ever one logic channel group, so its pattern goes here. */
c07f60e7
BV
127 uint8_t logic_pattern;
128 unsigned char logic_data[LOGIC_BUFSIZE];
8b2d41ed 129 /* Analog */
ba7dd8bb 130 int32_t num_analog_channels;
49224c28 131 GHashTable *ch_ag;
7a8a1aba
BG
132 gboolean avg; /* True if averaging is enabled */
133 uint64_t avg_samples;
c07f60e7
BV
134};
135
1e4a7cac
BV
136static const uint32_t drvopts[] = {
137 SR_CONF_DEMO_DEV,
138 SR_CONF_LOGIC_ANALYZER,
139 SR_CONF_OSCILLOSCOPE,
140};
141
584560f1 142static const uint32_t scanopts[] = {
3f239f08
UH
143 SR_CONF_NUM_LOGIC_CHANNELS,
144 SR_CONF_NUM_ANALOG_CHANNELS,
e15f48c2 145};
85b5af06 146
390795c0 147static const uint32_t devopts[] = {
1e4a7cac 148 SR_CONF_CONTINUOUS | SR_CONF_SET,
5827f61b
BV
149 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
150 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
390795c0 151 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
7a8a1aba
BG
152 SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET,
153 SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET,
390795c0
BV
154};
155
156static const uint32_t devopts_cg_logic[] = {
f12d9979 157 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
49224c28
BV
158};
159
390795c0 160static const uint32_t devopts_cg_analog[] = {
f12d9979
BV
161 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
162 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
7a1da331
BV
163};
164
d00088ca
BV
165static const uint64_t samplerates[] = {
166 SR_HZ(1),
167 SR_GHZ(1),
168 SR_HZ(1),
4bfbf9fc
BV
169};
170
c8f4624d 171static uint8_t pattern_sigrok[] = {
917e0e71
BV
172 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
173 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
174 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
175 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
176 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
177 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180};
181
dcf03d6d 182SR_PRIV struct sr_dev_driver demo_driver_info;
a873c594 183static struct sr_dev_driver *di = &demo_driver_info;
6239c175 184
6078d2c9 185static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 186
c07f60e7 187
6078d2c9 188static int init(struct sr_context *sr_ctx)
61136ea6 189{
f6beaac5 190 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
191}
192
49224c28 193static void generate_analog_pattern(struct analog_gen *ag, uint64_t sample_rate)
8b2d41ed 194{
4374219b 195 double t, frequency;
8b2d41ed
BV
196 float value;
197 unsigned int num_samples, i;
198 int last_end;
199
49224c28 200 sr_dbg("Generating %s pattern.", analog_pattern_str[ag->pattern]);
4374219b 201
49224c28 202 num_samples = ANALOG_BUFSIZE / sizeof(float);
8b2d41ed 203
4374219b 204 switch (ag->pattern) {
8b2d41ed 205 case PATTERN_SQUARE:
dddabe37 206 value = ag->amplitude;
8b2d41ed
BV
207 last_end = 0;
208 for (i = 0; i < num_samples; i++) {
209 if (i % 5 == 0)
210 value = -value;
211 if (i % 10 == 0)
3772c049 212 last_end = i;
8b2d41ed
BV
213 ag->pattern_data[i] = value;
214 }
215 ag->num_samples = last_end;
216 break;
4374219b
DJ
217
218 case PATTERN_SINE:
9d156555 219 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
4374219b
DJ
220
221 /* Make sure the number of samples we put out is an integer
222 * multiple of our period size */
223 /* FIXME we actually need only one period. A ringbuffer would be
224 * usefull here.*/
225 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
226 num_samples--;
227
228 for (i = 0; i < num_samples; i++) {
229 t = (double) i / (double) sample_rate;
dddabe37 230 ag->pattern_data[i] = ag->amplitude *
4374219b
DJ
231 sin(2 * M_PI * frequency * t);
232 }
233
091c9621
DJ
234 ag->num_samples = num_samples;
235 break;
236
237 case PATTERN_TRIANGLE:
9d156555 238 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
091c9621
DJ
239
240 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
241 num_samples--;
242
243 for (i = 0; i < num_samples; i++) {
244 t = (double) i / (double) sample_rate;
dddabe37 245 ag->pattern_data[i] = (2 * ag->amplitude / M_PI) *
091c9621
DJ
246 asin(sin(2 * M_PI * frequency * t));
247 }
248
9f54e0e8
DJ
249 ag->num_samples = num_samples;
250 break;
251
252 case PATTERN_SAWTOOTH:
9d156555 253 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
9f54e0e8
DJ
254
255 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
256 num_samples--;
257
258 for (i = 0; i < num_samples; i++) {
259 t = (double) i / (double) sample_rate;
dddabe37 260 ag->pattern_data[i] = 2 * ag->amplitude *
9f54e0e8
DJ
261 ((t * frequency) - floor(0.5f + t * frequency));
262 }
263
4374219b
DJ
264 ag->num_samples = num_samples;
265 break;
8b2d41ed
BV
266 }
267}
268
6078d2c9 269static GSList *scan(GSList *options)
6239c175 270{
b4750a3a 271 struct drv_context *drvc;
33ef7573 272 struct dev_context *devc;
c07f60e7 273 struct sr_dev_inst *sdi;
ba7dd8bb 274 struct sr_channel *ch;
49224c28 275 struct sr_channel_group *cg, *acg;
c07f60e7 276 struct sr_config *src;
8b2d41ed 277 struct analog_gen *ag;
c07f60e7 278 GSList *devices, *l;
ba7dd8bb
UH
279 int num_logic_channels, num_analog_channels, pattern, i;
280 char channel_name[16];
067d0716 281
a873c594 282 drvc = di->priv;
4b97c74e 283
3f239f08
UH
284 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
285 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
c07f60e7
BV
286 for (l = options; l; l = l->next) {
287 src = l->data;
288 switch (src->key) {
3f239f08 289 case SR_CONF_NUM_LOGIC_CHANNELS:
ba7dd8bb 290 num_logic_channels = g_variant_get_int32(src->data);
c07f60e7 291 break;
3f239f08 292 case SR_CONF_NUM_ANALOG_CHANNELS:
ba7dd8bb 293 num_analog_channels = g_variant_get_int32(src->data);
c07f60e7
BV
294 break;
295 }
296 }
85b5af06 297
c07f60e7 298 devices = NULL;
0af636be 299
aac29cc1 300 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be 301 sdi->status = SR_ST_ACTIVE;
4b664cd6 302 sdi->model = g_strdup("Demo device");
a873c594 303 sdi->driver = di;
e15f48c2 304
49224c28 305 devc = g_malloc(sizeof(struct dev_context));
8b2d41ed
BV
306 devc->cur_samplerate = SR_KHZ(200);
307 devc->limit_samples = 0;
308 devc->limit_msec = 0;
309 devc->step = 0;
b62bb97a 310 devc->continuous = FALSE;
ba7dd8bb
UH
311 devc->num_logic_channels = num_logic_channels;
312 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
8b2d41ed 313 devc->logic_pattern = PATTERN_SIGROK;
ba7dd8bb 314 devc->num_analog_channels = num_analog_channels;
7a8a1aba
BG
315 devc->avg = FALSE;
316 devc->avg_samples = 0;
8b2d41ed 317
ba7dd8bb 318 /* Logic channels, all in one channel group. */
49224c28 319 cg = g_malloc0(sizeof(struct sr_channel_group));
40fd0264 320 cg->name = g_strdup("Logic");
ba7dd8bb
UH
321 for (i = 0; i < num_logic_channels; i++) {
322 sprintf(channel_name, "D%d", i);
5e23fcab 323 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ba7dd8bb 324 cg->channels = g_slist_append(cg->channels, ch);
87ca93c5 325 }
40fd0264 326 sdi->channel_groups = g_slist_append(NULL, cg);
87ca93c5 327
ba7dd8bb 328 /* Analog channels, channel groups and pattern generators. */
2b36d6c6 329 pattern = 0;
49224c28
BV
330 /* An "Analog" channel group with all analog channels in it. */
331 acg = g_malloc0(sizeof(struct sr_channel_group));
332 acg->name = g_strdup("Analog");
333 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
334
335 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
ba7dd8bb 336 for (i = 0; i < num_analog_channels; i++) {
49224c28 337 snprintf(channel_name, 16, "A%d", i);
5e23fcab 338 ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
49224c28 339 TRUE, channel_name);
49224c28 340 acg->channels = g_slist_append(acg->channels, ch);
c07f60e7 341
49224c28
BV
342 /* Every analog channel gets its own channel group as well. */
343 cg = g_malloc0(sizeof(struct sr_channel_group));
ba7dd8bb
UH
344 cg->name = g_strdup(channel_name);
345 cg->channels = g_slist_append(NULL, ch);
49224c28 346 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
85b5af06 347
49224c28
BV
348 /* Every channel gets a generator struct. */
349 ag = g_malloc(sizeof(struct analog_gen));
dddabe37 350 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
ba7dd8bb 351 ag->packet.channels = cg->channels;
8b2d41ed
BV
352 ag->packet.mq = 0;
353 ag->packet.mqflags = 0;
354 ag->packet.unit = SR_UNIT_VOLT;
355 ag->packet.data = ag->pattern_data;
2b36d6c6 356 ag->pattern = pattern;
7a8a1aba
BG
357 ag->avg_val = 0.0f;
358 ag->num_avgs = 0;
49224c28 359 g_hash_table_insert(devc->ch_ag, ch, ag);
2b36d6c6
BV
360
361 if (++pattern == ARRAY_SIZE(analog_pattern_str))
362 pattern = 0;
33ef7573 363 }
33ef7573
JH
364
365 sdi->priv = devc;
8b2d41ed
BV
366 devices = g_slist_append(devices, sdi);
367 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 368
067d0716 369 return devices;
6239c175
UH
370}
371
6078d2c9 372static GSList *dev_list(void)
811deee4 373{
0e94d524 374 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
375}
376
6078d2c9 377static int dev_open(struct sr_dev_inst *sdi)
6239c175 378{
e73ffd42 379 sdi->status = SR_ST_ACTIVE;
697785d1 380
e46b8fb1 381 return SR_OK;
6239c175
UH
382}
383
6078d2c9 384static int dev_close(struct sr_dev_inst *sdi)
6239c175 385{
decfe89d 386 sdi->status = SR_ST_INACTIVE;
697785d1
UH
387
388 return SR_OK;
6239c175
UH
389}
390
ed0b7fed
BV
391static void clear_helper(void *priv)
392{
393 struct dev_context *devc;
49224c28
BV
394 GHashTableIter iter;
395 void *value;
ed0b7fed
BV
396
397 devc = priv;
49224c28
BV
398
399 /* Analog generators. */
400 g_hash_table_iter_init(&iter, devc->ch_ag);
401 while (g_hash_table_iter_next(&iter, NULL, &value))
402 g_free(value);
403 g_hash_table_unref(devc->ch_ag);
ed0b7fed
BV
404 g_free(devc);
405}
406
6078d2c9 407static int cleanup(void)
6239c175 408{
ed0b7fed 409 return std_dev_clear(di, clear_helper);
6239c175
UH
410}
411
584560f1 412static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 413 const struct sr_channel_group *cg)
6239c175 414{
c07f60e7 415 struct dev_context *devc;
ba7dd8bb 416 struct sr_channel *ch;
2388ae86
BV
417 struct analog_gen *ag;
418 int pattern;
6f57fd96 419
2388ae86
BV
420 if (!sdi)
421 return SR_ERR_ARG;
8f996b89 422
c07f60e7 423 devc = sdi->priv;
584560f1 424 switch (key) {
123e1313 425 case SR_CONF_SAMPLERATE:
a7684294 426 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 427 break;
2474d87e 428 case SR_CONF_LIMIT_SAMPLES:
a7684294 429 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
430 break;
431 case SR_CONF_LIMIT_MSEC:
a7684294 432 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 433 break;
7a8a1aba
BG
434 case SR_CONF_AVERAGING:
435 *data = g_variant_new_boolean(devc->avg);
436 break;
437 case SR_CONF_AVG_SAMPLES:
438 *data = g_variant_new_uint64(devc->avg_samples);
439 break;
2474d87e 440 case SR_CONF_PATTERN_MODE:
53b4680f 441 if (!cg)
660e398f 442 return SR_ERR_CHANNEL_GROUP;
49224c28 443 /* Any channel in the group will do. */
ba7dd8bb 444 ch = cg->channels->data;
3f239f08 445 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
446 pattern = devc->logic_pattern;
447 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 448 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 449 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
450 pattern = ag->pattern;
451 *data = g_variant_new_string(analog_pattern_str[pattern]);
452 } else
453 return SR_ERR_BUG;
c07f60e7 454 break;
dddabe37
BV
455 case SR_CONF_AMPLITUDE:
456 if (!cg)
457 return SR_ERR_CHANNEL_GROUP;
49224c28 458 /* Any channel in the group will do. */
dddabe37
BV
459 ch = cg->channels->data;
460 if (ch->type != SR_CHANNEL_ANALOG)
461 return SR_ERR_ARG;
49224c28 462 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
463 *data = g_variant_new_double(ag->amplitude);
464 break;
7dfcf010 465 default:
bd6fbf62 466 return SR_ERR_NA;
6239c175
UH
467 }
468
dfb0fa1a 469 return SR_OK;
6239c175
UH
470}
471
584560f1 472static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 473 const struct sr_channel_group *cg)
6239c175 474{
8b2d41ed 475 struct dev_context *devc;
4374219b 476 struct analog_gen *ag;
ba7dd8bb 477 struct sr_channel *ch;
49224c28
BV
478 GSList *l;
479 int logic_pattern, analog_pattern, ret;
61c39f54 480 unsigned int i;
1b79df2f 481 const char *stropt;
6239c175 482
8b2d41ed 483 devc = sdi->priv;
6239c175 484
e73ffd42
BV
485 if (sdi->status != SR_ST_ACTIVE)
486 return SR_ERR_DEV_CLOSED;
487
2388ae86 488 ret = SR_OK;
584560f1 489 switch (key) {
2388ae86 490 case SR_CONF_SAMPLERATE:
a7684294 491 devc->cur_samplerate = g_variant_get_uint64(data);
61c39f54 492 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
2388ae86
BV
493 break;
494 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
495 devc->limit_msec = 0;
496 devc->limit_samples = g_variant_get_uint64(data);
8b2d41ed 497 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
2388ae86
BV
498 break;
499 case SR_CONF_LIMIT_MSEC:
a7684294
JH
500 devc->limit_msec = g_variant_get_uint64(data);
501 devc->limit_samples = 0;
8b2d41ed 502 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
2388ae86 503 break;
7a8a1aba
BG
504 case SR_CONF_AVERAGING:
505 devc->avg = g_variant_get_boolean(data);
506 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
507 break;
508 case SR_CONF_AVG_SAMPLES:
509 devc->avg_samples = g_variant_get_uint64(data);
510 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
511 break;
2388ae86 512 case SR_CONF_PATTERN_MODE:
53b4680f 513 if (!cg)
660e398f 514 return SR_ERR_CHANNEL_GROUP;
d00088ca 515 stropt = g_variant_get_string(data, NULL);
49224c28
BV
516 logic_pattern = analog_pattern = -1;
517 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
518 if (!strcmp(stropt, logic_pattern_str[i])) {
519 logic_pattern = i;
520 break;
8b2d41ed 521 }
49224c28
BV
522 }
523 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
524 if (!strcmp(stropt, analog_pattern_str[i])) {
525 analog_pattern = i;
526 break;
8b2d41ed 527 }
49224c28
BV
528 }
529 if (logic_pattern == -1 && analog_pattern == -1)
530 return SR_ERR_ARG;
531 for (l = cg->channels; l; l = l->next) {
532 ch = l->data;
533 if (ch->type == SR_CHANNEL_LOGIC) {
534 if (logic_pattern == -1)
535 return SR_ERR_ARG;
536 sr_dbg("Setting logic pattern to %s",
537 logic_pattern_str[logic_pattern]);
538 devc->logic_pattern = logic_pattern;
539 /* Might as well do this now, these are static. */
540 if (logic_pattern == PATTERN_ALL_LOW)
541 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
542 else if (logic_pattern == PATTERN_ALL_HIGH)
543 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
544 } else if (ch->type == SR_CHANNEL_ANALOG) {
545 if (analog_pattern == -1)
546 return SR_ERR_ARG;
547 sr_dbg("Setting analog pattern for channel %s to %s",
548 ch->name, analog_pattern_str[analog_pattern]);
549 ag = g_hash_table_lookup(devc->ch_ag, ch);
550 ag->pattern = analog_pattern;
551 } else
552 return SR_ERR_BUG;
553 }
2388ae86 554 break;
dddabe37
BV
555 case SR_CONF_AMPLITUDE:
556 if (!cg)
557 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
558 for (l = cg->channels; l; l = l->next) {
559 ch = l->data;
560 if (ch->type != SR_CHANNEL_ANALOG)
561 return SR_ERR_ARG;
562 ag = g_hash_table_lookup(devc->ch_ag, ch);
563 ag->amplitude = g_variant_get_double(data);
564 }
dddabe37 565 break;
2388ae86 566 default:
bd6fbf62 567 ret = SR_ERR_NA;
6239c175
UH
568 }
569
570 return ret;
571}
572
584560f1 573static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 574 const struct sr_channel_group *cg)
a1c743fc 575{
ba7dd8bb 576 struct sr_channel *ch;
d00088ca
BV
577 GVariant *gvar;
578 GVariantBuilder gvb;
a1c743fc
BV
579
580 (void)sdi;
581
7a1da331 582 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1
BV
583 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
584 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
7a1da331
BV
585 return SR_OK;
586 }
587
390795c0
BV
588 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
589 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 590 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
390795c0
BV
591 return SR_OK;
592 }
593
7a1da331
BV
594 if (!sdi)
595 return SR_ERR_ARG;
596
53b4680f 597 if (!cg) {
7a1da331
BV
598 switch (key) {
599 case SR_CONF_DEVICE_OPTIONS:
584560f1 600 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 601 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
7a1da331
BV
602 break;
603 case SR_CONF_SAMPLERATE:
604 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
605 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
606 ARRAY_SIZE(samplerates), sizeof(uint64_t));
607 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
608 *data = g_variant_builder_end(&gvb);
609 break;
610 default:
611 return SR_ERR_NA;
612 }
613 } else {
49224c28 614 /* Any channel in the group will do. */
ba7dd8bb 615 ch = cg->channels->data;
7a1da331
BV
616 switch (key) {
617 case SR_CONF_DEVICE_OPTIONS:
49224c28
BV
618 if (ch->type == SR_CHANNEL_LOGIC)
619 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
620 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
584560f1 621 sizeof(uint32_t));
49224c28
BV
622 else if (ch->type == SR_CHANNEL_ANALOG)
623 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
624 devopts_cg_analog, ARRAY_SIZE(devopts_cg_analog),
584560f1 625 sizeof(uint32_t));
49224c28
BV
626 else
627 return SR_ERR_BUG;
7a1da331
BV
628 break;
629 case SR_CONF_PATTERN_MODE:
3f239f08 630 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
631 *data = g_variant_new_strv(logic_pattern_str,
632 ARRAY_SIZE(logic_pattern_str));
3f239f08 633 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
634 *data = g_variant_new_strv(analog_pattern_str,
635 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
636 else
637 return SR_ERR_BUG;
7a1da331
BV
638 break;
639 default:
640 return SR_ERR_NA;
641 }
a1c743fc
BV
642 }
643
644 return SR_OK;
645}
646
c07f60e7 647static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 648{
61c39f54 649 struct dev_context *devc;
c07f60e7
BV
650 uint64_t i, j;
651 uint8_t pat;
85b5af06 652
61c39f54 653 devc = sdi->priv;
85b5af06 654
c07f60e7 655 switch (devc->logic_pattern) {
61c39f54 656 case PATTERN_SIGROK:
c07f60e7
BV
657 memset(devc->logic_data, 0x00, size);
658 for (i = 0; i < size; i += devc->logic_unitsize) {
659 for (j = 0; j < devc->logic_unitsize; j++) {
660 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
661 devc->logic_data[i + j] = ~pat;
662 }
663 devc->step++;
917e0e71
BV
664 }
665 break;
61c39f54 666 case PATTERN_RANDOM:
5096c6a6 667 for (i = 0; i < size; i++)
61c39f54 668 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 669 break;
61c39f54 670 case PATTERN_INC:
c07f60e7
BV
671 for (i = 0; i < size; i++) {
672 for (j = 0; j < devc->logic_unitsize; j++) {
673 devc->logic_data[i + j] = devc->step;
674 }
675 devc->step++;
676 }
c03ed397 677 break;
61c39f54
BV
678 case PATTERN_ALL_LOW:
679 case PATTERN_ALL_HIGH:
680 /* These were set when the pattern mode was selected. */
c03ed397
UH
681 break;
682 default:
c07f60e7 683 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 684 break;
85b5af06
UH
685 }
686}
687
7a8a1aba
BG
688static void send_analog_packet(struct analog_gen *ag,
689 struct sr_dev_inst *sdi,
690 uint64_t *analog_sent,
691 uint64_t analog_todo)
692{
693 struct sr_datafeed_packet packet;
694 struct dev_context *devc;
695 uint64_t sending_now, to_avg;
696 int ag_pattern_pos;
697 unsigned int i;
698
699 devc = sdi->priv;
700 packet.type = SR_DF_ANALOG;
701 packet.payload = &ag->packet;
702
703 if (!devc->avg) {
704 ag_pattern_pos = devc->analog_counter % ag->num_samples;
705 sending_now = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
706 ag->packet.data = ag->pattern_data + ag_pattern_pos;
707 ag->packet.num_samples = sending_now;
708 sr_session_send(sdi, &packet);
709
710 /* Whichever channel group gets there first. */
711 *analog_sent = MAX(*analog_sent, sending_now);
712 } else {
713 ag_pattern_pos = devc->analog_counter % ag->num_samples;
714 to_avg = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
715
716 for (i = 0; i < to_avg; i++) {
717 ag->avg_val = (ag->avg_val +
718 *(ag->pattern_data +
719 ag_pattern_pos + i)) / 2;
720 ag->num_avgs++;
721 /* Time to send averaged data? */
722 if (devc->avg_samples > 0 &&
723 ag->num_avgs >= devc->avg_samples)
724 goto do_send;
725 }
726
727 if (devc->avg_samples == 0) {
728 /* We're averaging all the samples, so wait with
729 * sending until the very end.
730 */
731 *analog_sent = ag->num_avgs;
732 return;
733 }
734
735do_send:
736 ag->packet.data = &ag->avg_val;
737 ag->packet.num_samples = 1;
738
739 sr_session_send(sdi, &packet);
740 *analog_sent = ag->num_avgs;
741
742 ag->num_avgs = 0;
743 ag->avg_val = 0.0f;
744 }
745}
746
85b5af06 747/* Callback handling data */
61c39f54 748static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 749{
61c39f54
BV
750 struct sr_dev_inst *sdi;
751 struct dev_context *devc;
b9c735a2 752 struct sr_datafeed_packet packet;
9c939c51 753 struct sr_datafeed_logic logic;
8b2d41ed 754 struct analog_gen *ag;
49224c28
BV
755 GHashTableIter iter;
756 void *value;
b62bb97a 757 uint64_t logic_todo, analog_todo, expected_samplenum, analog_sent, sending_now;
3b203673 758 int64_t time, elapsed;
1924f59f 759
cb93f8a9
UH
760 (void)fd;
761 (void)revents;
1924f59f 762
61c39f54
BV
763 sdi = cb_data;
764 devc = sdi->priv;
b62bb97a 765 logic_todo = analog_todo = 0;
61c39f54 766
b62bb97a 767 /* How many samples should we have sent by now? */
3b203673
AG
768 time = g_get_monotonic_time();
769 elapsed = time - devc->starttime;
a7684294 770 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
7f4975b4 771
b62bb97a
BV
772 /* But never more than the limit, if there is one. */
773 if (!devc->continuous)
774 expected_samplenum = MIN(expected_samplenum, devc->limit_samples);
775
3b203673 776 /* Of those, how many do we still have to send? */
b62bb97a
BV
777 if (devc->num_logic_channels)
778 logic_todo = expected_samplenum - devc->logic_counter;
779 if (devc->num_analog_channels)
780 analog_todo = expected_samplenum - devc->analog_counter;
85b5af06 781
7f4975b4 782 while (logic_todo || analog_todo) {
c07f60e7 783 /* Logic */
b62bb97a
BV
784 if (logic_todo > 0) {
785 sending_now = MIN(logic_todo, LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
786 logic_generator(sdi, sending_now * devc->logic_unitsize);
787 packet.type = SR_DF_LOGIC;
788 packet.payload = &logic;
789 logic.length = sending_now * devc->logic_unitsize;
790 logic.unitsize = devc->logic_unitsize;
791 logic.data = devc->logic_data;
792 sr_session_send(sdi, &packet);
7f4975b4
BV
793 logic_todo -= sending_now;
794 devc->logic_counter += sending_now;
8b2d41ed
BV
795 }
796
ba7dd8bb 797 /* Analog, one channel at a time */
b62bb97a
BV
798 if (analog_todo > 0) {
799 analog_sent = 0;
49224c28
BV
800
801 g_hash_table_iter_init(&iter, devc->ch_ag);
802 while (g_hash_table_iter_next(&iter, NULL, &value)) {
7a8a1aba
BG
803 send_analog_packet(value, sdi,
804 &analog_sent, analog_todo);
8b2d41ed 805 }
b62bb97a
BV
806 analog_todo -= analog_sent;
807 devc->analog_counter += analog_sent;
8b2d41ed 808 }
3b203673
AG
809 }
810
b62bb97a
BV
811 if (!devc->continuous
812 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
813 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
7a8a1aba
BG
814 /* If we're averaging everything - now is the time to send data */
815 if (devc->avg_samples == 0) {
816 g_hash_table_iter_init(&iter, devc->ch_ag);
817 while (g_hash_table_iter_next(&iter, NULL, &value)) {
818 ag = value;
819 packet.type = SR_DF_ANALOG;
820 packet.payload = &ag->packet;
821 ag->packet.data = &ag->avg_val;
822 ag->packet.num_samples = 1;
823 sr_session_send(sdi, &packet);
824 }
825 }
826
7f4975b4 827 sr_dbg("Requested number of samples reached.");
61c39f54 828 dev_acquisition_stop(sdi, cb_data);
c216d623 829 return TRUE;
85b5af06 830 }
1924f59f 831
85b5af06
UH
832 return TRUE;
833}
834
6078d2c9 835static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 836{
61c39f54 837 struct dev_context *devc;
49224c28
BV
838 GHashTableIter iter;
839 void *value;
85b5af06 840
102f1239
BV
841 (void)cb_data;
842
e73ffd42
BV
843 if (sdi->status != SR_ST_ACTIVE)
844 return SR_ERR_DEV_CLOSED;
845
61c39f54 846 devc = sdi->priv;
b62bb97a 847 devc->continuous = !devc->limit_samples;
7f4975b4 848 devc->logic_counter = devc->analog_counter = 0;
85b5af06 849
3b203673
AG
850 /*
851 * Setting two channels connected by a pipe is a remnant from when the
852 * demo driver generated data in a thread, and collected and sent the
853 * data in the main program loop.
854 * They are kept here because it provides a convenient way of setting
855 * up a timeout-based polling mechanism.
856 */
b4750a3a 857 if (pipe(devc->pipe_fds)) {
92bcedf6 858 sr_err("%s: pipe() failed", __func__);
e46b8fb1 859 return SR_ERR;
c03ed397 860 }
85b5af06 861
49224c28
BV
862 g_hash_table_iter_init(&iter, devc->ch_ag);
863 while (g_hash_table_iter_next(&iter, NULL, &value))
864 generate_analog_pattern(value, devc->cur_samplerate);
4374219b 865
e0532047 866 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
e0532047 867 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 868
d35aaf02 869 /* Set channel encoding to binary (default is UTF-8). */
e0532047 870 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02 871
b62bb97a 872 /* Make channels unbuffered. */
e0532047 873 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 874
b62bb97a
BV
875 sr_session_source_add_channel(sdi->session, devc->channel,
876 G_IO_IN | G_IO_ERR, 40, prepare_data, (void *)sdi);
85b5af06 877
4afdfd46 878 /* Send header packet to the session bus. */
102f1239 879 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 880
3b203673
AG
881 /* We use this timestamp to decide how many more samples to send. */
882 devc->starttime = g_get_monotonic_time();
883
e46b8fb1 884 return SR_OK;
6239c175
UH
885}
886
6078d2c9 887static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 888{
8b2d41ed 889 struct dev_context *devc;
c216d623 890 struct sr_datafeed_packet packet;
7fd3e859 891
33ef7573 892 (void)cb_data;
7fd3e859 893
8b2d41ed 894 devc = sdi->priv;
a84f6ad3 895 sr_dbg("Stopping acquisition.");
49145a63 896
102f1239 897 sr_session_source_remove_channel(sdi->session, devc->channel);
e0532047 898 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
899 g_io_channel_unref(devc->channel);
900 devc->channel = NULL;
c216d623
AG
901
902 /* Send last packet. */
903 packet.type = SR_DF_END;
c07f60e7 904 sr_session_send(sdi, &packet);
7fd3e859 905
3010f21c 906 return SR_OK;
6239c175
UH
907}
908
c09f0b57 909SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
910 .name = "demo",
911 .longname = "Demo driver and pattern generator",
912 .api_version = 1,
6078d2c9
UH
913 .init = init,
914 .cleanup = cleanup,
915 .scan = scan,
916 .dev_list = dev_list,
a6630742 917 .dev_clear = NULL,
035a1078
BV
918 .config_get = config_get,
919 .config_set = config_set,
a1c743fc 920 .config_list = config_list,
6078d2c9
UH
921 .dev_open = dev_open,
922 .dev_close = dev_close,
923 .dev_acquisition_start = dev_acquisition_start,
924 .dev_acquisition_stop = dev_acquisition_stop,
b4750a3a 925 .priv = NULL,
6239c175 926};