]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
Constify a few arrays and variables.
[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
329733d9 171static const 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;
6239c175 183
6078d2c9 184static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 185
4f840ce9 186static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
61136ea6 187{
f6beaac5 188 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
189}
190
49224c28 191static void generate_analog_pattern(struct analog_gen *ag, uint64_t sample_rate)
8b2d41ed 192{
4374219b 193 double t, frequency;
8b2d41ed
BV
194 float value;
195 unsigned int num_samples, i;
196 int last_end;
197
49224c28 198 sr_dbg("Generating %s pattern.", analog_pattern_str[ag->pattern]);
4374219b 199
49224c28 200 num_samples = ANALOG_BUFSIZE / sizeof(float);
8b2d41ed 201
4374219b 202 switch (ag->pattern) {
8b2d41ed 203 case PATTERN_SQUARE:
dddabe37 204 value = ag->amplitude;
8b2d41ed
BV
205 last_end = 0;
206 for (i = 0; i < num_samples; i++) {
207 if (i % 5 == 0)
208 value = -value;
209 if (i % 10 == 0)
3772c049 210 last_end = i;
8b2d41ed
BV
211 ag->pattern_data[i] = value;
212 }
213 ag->num_samples = last_end;
214 break;
4374219b
DJ
215
216 case PATTERN_SINE:
9d156555 217 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
4374219b
DJ
218
219 /* Make sure the number of samples we put out is an integer
220 * multiple of our period size */
221 /* FIXME we actually need only one period. A ringbuffer would be
222 * usefull here.*/
223 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
224 num_samples--;
225
226 for (i = 0; i < num_samples; i++) {
227 t = (double) i / (double) sample_rate;
dddabe37 228 ag->pattern_data[i] = ag->amplitude *
4374219b
DJ
229 sin(2 * M_PI * frequency * t);
230 }
231
091c9621
DJ
232 ag->num_samples = num_samples;
233 break;
234
235 case PATTERN_TRIANGLE:
9d156555 236 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
091c9621
DJ
237
238 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
239 num_samples--;
240
241 for (i = 0; i < num_samples; i++) {
242 t = (double) i / (double) sample_rate;
dddabe37 243 ag->pattern_data[i] = (2 * ag->amplitude / M_PI) *
091c9621
DJ
244 asin(sin(2 * M_PI * frequency * t));
245 }
246
9f54e0e8
DJ
247 ag->num_samples = num_samples;
248 break;
249
250 case PATTERN_SAWTOOTH:
9d156555 251 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
9f54e0e8
DJ
252
253 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
254 num_samples--;
255
256 for (i = 0; i < num_samples; i++) {
257 t = (double) i / (double) sample_rate;
dddabe37 258 ag->pattern_data[i] = 2 * ag->amplitude *
9f54e0e8
DJ
259 ((t * frequency) - floor(0.5f + t * frequency));
260 }
261
4374219b
DJ
262 ag->num_samples = num_samples;
263 break;
8b2d41ed
BV
264 }
265}
266
4f840ce9 267static GSList *scan(struct sr_dev_driver *di, GSList *options)
6239c175 268{
b4750a3a 269 struct drv_context *drvc;
33ef7573 270 struct dev_context *devc;
c07f60e7 271 struct sr_dev_inst *sdi;
ba7dd8bb 272 struct sr_channel *ch;
49224c28 273 struct sr_channel_group *cg, *acg;
c07f60e7 274 struct sr_config *src;
8b2d41ed 275 struct analog_gen *ag;
c07f60e7 276 GSList *devices, *l;
ba7dd8bb
UH
277 int num_logic_channels, num_analog_channels, pattern, i;
278 char channel_name[16];
067d0716 279
a873c594 280 drvc = di->priv;
4b97c74e 281
3f239f08
UH
282 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
283 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
c07f60e7
BV
284 for (l = options; l; l = l->next) {
285 src = l->data;
286 switch (src->key) {
3f239f08 287 case SR_CONF_NUM_LOGIC_CHANNELS:
ba7dd8bb 288 num_logic_channels = g_variant_get_int32(src->data);
c07f60e7 289 break;
3f239f08 290 case SR_CONF_NUM_ANALOG_CHANNELS:
ba7dd8bb 291 num_analog_channels = g_variant_get_int32(src->data);
c07f60e7
BV
292 break;
293 }
294 }
85b5af06 295
c07f60e7 296 devices = NULL;
0af636be 297
aac29cc1 298 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be 299 sdi->status = SR_ST_ACTIVE;
4b664cd6 300 sdi->model = g_strdup("Demo device");
a873c594 301 sdi->driver = di;
e15f48c2 302
49224c28 303 devc = g_malloc(sizeof(struct dev_context));
8b2d41ed
BV
304 devc->cur_samplerate = SR_KHZ(200);
305 devc->limit_samples = 0;
306 devc->limit_msec = 0;
307 devc->step = 0;
b62bb97a 308 devc->continuous = FALSE;
ba7dd8bb
UH
309 devc->num_logic_channels = num_logic_channels;
310 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
8b2d41ed 311 devc->logic_pattern = PATTERN_SIGROK;
ba7dd8bb 312 devc->num_analog_channels = num_analog_channels;
7a8a1aba
BG
313 devc->avg = FALSE;
314 devc->avg_samples = 0;
8b2d41ed 315
ba7dd8bb 316 /* Logic channels, all in one channel group. */
49224c28 317 cg = g_malloc0(sizeof(struct sr_channel_group));
40fd0264 318 cg->name = g_strdup("Logic");
ba7dd8bb
UH
319 for (i = 0; i < num_logic_channels; i++) {
320 sprintf(channel_name, "D%d", i);
5e23fcab 321 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ba7dd8bb 322 cg->channels = g_slist_append(cg->channels, ch);
87ca93c5 323 }
40fd0264 324 sdi->channel_groups = g_slist_append(NULL, cg);
87ca93c5 325
ba7dd8bb 326 /* Analog channels, channel groups and pattern generators. */
2b36d6c6 327 pattern = 0;
49224c28
BV
328 /* An "Analog" channel group with all analog channels in it. */
329 acg = g_malloc0(sizeof(struct sr_channel_group));
330 acg->name = g_strdup("Analog");
331 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
332
333 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
ba7dd8bb 334 for (i = 0; i < num_analog_channels; i++) {
49224c28 335 snprintf(channel_name, 16, "A%d", i);
5e23fcab 336 ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
49224c28 337 TRUE, channel_name);
49224c28 338 acg->channels = g_slist_append(acg->channels, ch);
c07f60e7 339
49224c28
BV
340 /* Every analog channel gets its own channel group as well. */
341 cg = g_malloc0(sizeof(struct sr_channel_group));
ba7dd8bb
UH
342 cg->name = g_strdup(channel_name);
343 cg->channels = g_slist_append(NULL, ch);
49224c28 344 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
85b5af06 345
49224c28
BV
346 /* Every channel gets a generator struct. */
347 ag = g_malloc(sizeof(struct analog_gen));
dddabe37 348 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
ba7dd8bb 349 ag->packet.channels = cg->channels;
8b2d41ed
BV
350 ag->packet.mq = 0;
351 ag->packet.mqflags = 0;
352 ag->packet.unit = SR_UNIT_VOLT;
353 ag->packet.data = ag->pattern_data;
2b36d6c6 354 ag->pattern = pattern;
7a8a1aba
BG
355 ag->avg_val = 0.0f;
356 ag->num_avgs = 0;
49224c28 357 g_hash_table_insert(devc->ch_ag, ch, ag);
2b36d6c6
BV
358
359 if (++pattern == ARRAY_SIZE(analog_pattern_str))
360 pattern = 0;
33ef7573 361 }
33ef7573
JH
362
363 sdi->priv = devc;
8b2d41ed
BV
364 devices = g_slist_append(devices, sdi);
365 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 366
067d0716 367 return devices;
6239c175
UH
368}
369
4f840ce9 370static GSList *dev_list(const struct sr_dev_driver *di)
811deee4 371{
0e94d524 372 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
373}
374
6078d2c9 375static int dev_open(struct sr_dev_inst *sdi)
6239c175 376{
e73ffd42 377 sdi->status = SR_ST_ACTIVE;
697785d1 378
e46b8fb1 379 return SR_OK;
6239c175
UH
380}
381
6078d2c9 382static int dev_close(struct sr_dev_inst *sdi)
6239c175 383{
decfe89d 384 sdi->status = SR_ST_INACTIVE;
697785d1
UH
385
386 return SR_OK;
6239c175
UH
387}
388
ed0b7fed
BV
389static void clear_helper(void *priv)
390{
391 struct dev_context *devc;
49224c28
BV
392 GHashTableIter iter;
393 void *value;
ed0b7fed
BV
394
395 devc = priv;
49224c28
BV
396
397 /* Analog generators. */
398 g_hash_table_iter_init(&iter, devc->ch_ag);
399 while (g_hash_table_iter_next(&iter, NULL, &value))
400 g_free(value);
401 g_hash_table_unref(devc->ch_ag);
ed0b7fed
BV
402 g_free(devc);
403}
404
4f840ce9 405static int cleanup(const struct sr_dev_driver *di)
6239c175 406{
ed0b7fed 407 return std_dev_clear(di, clear_helper);
6239c175
UH
408}
409
584560f1 410static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 411 const struct sr_channel_group *cg)
6239c175 412{
c07f60e7 413 struct dev_context *devc;
ba7dd8bb 414 struct sr_channel *ch;
2388ae86
BV
415 struct analog_gen *ag;
416 int pattern;
6f57fd96 417
2388ae86
BV
418 if (!sdi)
419 return SR_ERR_ARG;
8f996b89 420
c07f60e7 421 devc = sdi->priv;
584560f1 422 switch (key) {
123e1313 423 case SR_CONF_SAMPLERATE:
a7684294 424 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 425 break;
2474d87e 426 case SR_CONF_LIMIT_SAMPLES:
a7684294 427 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
428 break;
429 case SR_CONF_LIMIT_MSEC:
a7684294 430 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 431 break;
7a8a1aba
BG
432 case SR_CONF_AVERAGING:
433 *data = g_variant_new_boolean(devc->avg);
434 break;
435 case SR_CONF_AVG_SAMPLES:
436 *data = g_variant_new_uint64(devc->avg_samples);
437 break;
2474d87e 438 case SR_CONF_PATTERN_MODE:
53b4680f 439 if (!cg)
660e398f 440 return SR_ERR_CHANNEL_GROUP;
49224c28 441 /* Any channel in the group will do. */
ba7dd8bb 442 ch = cg->channels->data;
3f239f08 443 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
444 pattern = devc->logic_pattern;
445 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 446 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 447 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
448 pattern = ag->pattern;
449 *data = g_variant_new_string(analog_pattern_str[pattern]);
450 } else
451 return SR_ERR_BUG;
c07f60e7 452 break;
dddabe37
BV
453 case SR_CONF_AMPLITUDE:
454 if (!cg)
455 return SR_ERR_CHANNEL_GROUP;
49224c28 456 /* Any channel in the group will do. */
dddabe37
BV
457 ch = cg->channels->data;
458 if (ch->type != SR_CHANNEL_ANALOG)
459 return SR_ERR_ARG;
49224c28 460 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
461 *data = g_variant_new_double(ag->amplitude);
462 break;
7dfcf010 463 default:
bd6fbf62 464 return SR_ERR_NA;
6239c175
UH
465 }
466
dfb0fa1a 467 return SR_OK;
6239c175
UH
468}
469
584560f1 470static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 471 const struct sr_channel_group *cg)
6239c175 472{
8b2d41ed 473 struct dev_context *devc;
4374219b 474 struct analog_gen *ag;
ba7dd8bb 475 struct sr_channel *ch;
49224c28
BV
476 GSList *l;
477 int logic_pattern, analog_pattern, ret;
61c39f54 478 unsigned int i;
1b79df2f 479 const char *stropt;
6239c175 480
8b2d41ed 481 devc = sdi->priv;
6239c175 482
e73ffd42
BV
483 if (sdi->status != SR_ST_ACTIVE)
484 return SR_ERR_DEV_CLOSED;
485
2388ae86 486 ret = SR_OK;
584560f1 487 switch (key) {
2388ae86 488 case SR_CONF_SAMPLERATE:
a7684294 489 devc->cur_samplerate = g_variant_get_uint64(data);
61c39f54 490 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
2388ae86
BV
491 break;
492 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
493 devc->limit_msec = 0;
494 devc->limit_samples = g_variant_get_uint64(data);
8b2d41ed 495 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
2388ae86
BV
496 break;
497 case SR_CONF_LIMIT_MSEC:
a7684294
JH
498 devc->limit_msec = g_variant_get_uint64(data);
499 devc->limit_samples = 0;
8b2d41ed 500 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
2388ae86 501 break;
7a8a1aba
BG
502 case SR_CONF_AVERAGING:
503 devc->avg = g_variant_get_boolean(data);
504 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
505 break;
506 case SR_CONF_AVG_SAMPLES:
507 devc->avg_samples = g_variant_get_uint64(data);
508 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
509 break;
2388ae86 510 case SR_CONF_PATTERN_MODE:
53b4680f 511 if (!cg)
660e398f 512 return SR_ERR_CHANNEL_GROUP;
d00088ca 513 stropt = g_variant_get_string(data, NULL);
49224c28
BV
514 logic_pattern = analog_pattern = -1;
515 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
516 if (!strcmp(stropt, logic_pattern_str[i])) {
517 logic_pattern = i;
518 break;
8b2d41ed 519 }
49224c28
BV
520 }
521 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
522 if (!strcmp(stropt, analog_pattern_str[i])) {
523 analog_pattern = i;
524 break;
8b2d41ed 525 }
49224c28
BV
526 }
527 if (logic_pattern == -1 && analog_pattern == -1)
528 return SR_ERR_ARG;
529 for (l = cg->channels; l; l = l->next) {
530 ch = l->data;
531 if (ch->type == SR_CHANNEL_LOGIC) {
532 if (logic_pattern == -1)
533 return SR_ERR_ARG;
534 sr_dbg("Setting logic pattern to %s",
535 logic_pattern_str[logic_pattern]);
536 devc->logic_pattern = logic_pattern;
537 /* Might as well do this now, these are static. */
538 if (logic_pattern == PATTERN_ALL_LOW)
539 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
540 else if (logic_pattern == PATTERN_ALL_HIGH)
541 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
542 } else if (ch->type == SR_CHANNEL_ANALOG) {
543 if (analog_pattern == -1)
544 return SR_ERR_ARG;
545 sr_dbg("Setting analog pattern for channel %s to %s",
546 ch->name, analog_pattern_str[analog_pattern]);
547 ag = g_hash_table_lookup(devc->ch_ag, ch);
548 ag->pattern = analog_pattern;
549 } else
550 return SR_ERR_BUG;
551 }
2388ae86 552 break;
dddabe37
BV
553 case SR_CONF_AMPLITUDE:
554 if (!cg)
555 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
556 for (l = cg->channels; l; l = l->next) {
557 ch = l->data;
558 if (ch->type != SR_CHANNEL_ANALOG)
559 return SR_ERR_ARG;
560 ag = g_hash_table_lookup(devc->ch_ag, ch);
561 ag->amplitude = g_variant_get_double(data);
562 }
dddabe37 563 break;
2388ae86 564 default:
bd6fbf62 565 ret = SR_ERR_NA;
6239c175
UH
566 }
567
568 return ret;
569}
570
584560f1 571static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 572 const struct sr_channel_group *cg)
a1c743fc 573{
ba7dd8bb 574 struct sr_channel *ch;
d00088ca
BV
575 GVariant *gvar;
576 GVariantBuilder gvb;
a1c743fc
BV
577
578 (void)sdi;
579
7a1da331 580 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1
BV
581 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
582 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
7a1da331
BV
583 return SR_OK;
584 }
585
390795c0
BV
586 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
587 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 588 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
390795c0
BV
589 return SR_OK;
590 }
591
7a1da331
BV
592 if (!sdi)
593 return SR_ERR_ARG;
594
53b4680f 595 if (!cg) {
7a1da331
BV
596 switch (key) {
597 case SR_CONF_DEVICE_OPTIONS:
584560f1 598 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 599 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
7a1da331
BV
600 break;
601 case SR_CONF_SAMPLERATE:
602 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
603 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
604 ARRAY_SIZE(samplerates), sizeof(uint64_t));
605 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
606 *data = g_variant_builder_end(&gvb);
607 break;
608 default:
609 return SR_ERR_NA;
610 }
611 } else {
49224c28 612 /* Any channel in the group will do. */
ba7dd8bb 613 ch = cg->channels->data;
7a1da331
BV
614 switch (key) {
615 case SR_CONF_DEVICE_OPTIONS:
49224c28
BV
616 if (ch->type == SR_CHANNEL_LOGIC)
617 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
618 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
584560f1 619 sizeof(uint32_t));
49224c28
BV
620 else if (ch->type == SR_CHANNEL_ANALOG)
621 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
622 devopts_cg_analog, ARRAY_SIZE(devopts_cg_analog),
584560f1 623 sizeof(uint32_t));
49224c28
BV
624 else
625 return SR_ERR_BUG;
7a1da331
BV
626 break;
627 case SR_CONF_PATTERN_MODE:
3f239f08 628 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
629 *data = g_variant_new_strv(logic_pattern_str,
630 ARRAY_SIZE(logic_pattern_str));
3f239f08 631 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
632 *data = g_variant_new_strv(analog_pattern_str,
633 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
634 else
635 return SR_ERR_BUG;
7a1da331
BV
636 break;
637 default:
638 return SR_ERR_NA;
639 }
a1c743fc
BV
640 }
641
642 return SR_OK;
643}
644
c07f60e7 645static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 646{
61c39f54 647 struct dev_context *devc;
c07f60e7
BV
648 uint64_t i, j;
649 uint8_t pat;
85b5af06 650
61c39f54 651 devc = sdi->priv;
85b5af06 652
c07f60e7 653 switch (devc->logic_pattern) {
61c39f54 654 case PATTERN_SIGROK:
c07f60e7
BV
655 memset(devc->logic_data, 0x00, size);
656 for (i = 0; i < size; i += devc->logic_unitsize) {
657 for (j = 0; j < devc->logic_unitsize; j++) {
658 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
659 devc->logic_data[i + j] = ~pat;
660 }
661 devc->step++;
917e0e71
BV
662 }
663 break;
61c39f54 664 case PATTERN_RANDOM:
5096c6a6 665 for (i = 0; i < size; i++)
61c39f54 666 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 667 break;
61c39f54 668 case PATTERN_INC:
c07f60e7
BV
669 for (i = 0; i < size; i++) {
670 for (j = 0; j < devc->logic_unitsize; j++) {
671 devc->logic_data[i + j] = devc->step;
672 }
673 devc->step++;
674 }
c03ed397 675 break;
61c39f54
BV
676 case PATTERN_ALL_LOW:
677 case PATTERN_ALL_HIGH:
678 /* These were set when the pattern mode was selected. */
c03ed397
UH
679 break;
680 default:
c07f60e7 681 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 682 break;
85b5af06
UH
683 }
684}
685
7a8a1aba
BG
686static void send_analog_packet(struct analog_gen *ag,
687 struct sr_dev_inst *sdi,
688 uint64_t *analog_sent,
689 uint64_t analog_todo)
690{
691 struct sr_datafeed_packet packet;
692 struct dev_context *devc;
693 uint64_t sending_now, to_avg;
694 int ag_pattern_pos;
695 unsigned int i;
696
697 devc = sdi->priv;
698 packet.type = SR_DF_ANALOG;
699 packet.payload = &ag->packet;
700
701 if (!devc->avg) {
702 ag_pattern_pos = devc->analog_counter % ag->num_samples;
703 sending_now = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
704 ag->packet.data = ag->pattern_data + ag_pattern_pos;
705 ag->packet.num_samples = sending_now;
706 sr_session_send(sdi, &packet);
707
708 /* Whichever channel group gets there first. */
709 *analog_sent = MAX(*analog_sent, sending_now);
710 } else {
711 ag_pattern_pos = devc->analog_counter % ag->num_samples;
712 to_avg = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
713
714 for (i = 0; i < to_avg; i++) {
715 ag->avg_val = (ag->avg_val +
716 *(ag->pattern_data +
717 ag_pattern_pos + i)) / 2;
718 ag->num_avgs++;
719 /* Time to send averaged data? */
720 if (devc->avg_samples > 0 &&
721 ag->num_avgs >= devc->avg_samples)
722 goto do_send;
723 }
724
725 if (devc->avg_samples == 0) {
726 /* We're averaging all the samples, so wait with
727 * sending until the very end.
728 */
729 *analog_sent = ag->num_avgs;
730 return;
731 }
732
733do_send:
734 ag->packet.data = &ag->avg_val;
735 ag->packet.num_samples = 1;
736
737 sr_session_send(sdi, &packet);
738 *analog_sent = ag->num_avgs;
739
740 ag->num_avgs = 0;
741 ag->avg_val = 0.0f;
742 }
743}
744
85b5af06 745/* Callback handling data */
61c39f54 746static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 747{
61c39f54
BV
748 struct sr_dev_inst *sdi;
749 struct dev_context *devc;
b9c735a2 750 struct sr_datafeed_packet packet;
9c939c51 751 struct sr_datafeed_logic logic;
8b2d41ed 752 struct analog_gen *ag;
49224c28
BV
753 GHashTableIter iter;
754 void *value;
b62bb97a 755 uint64_t logic_todo, analog_todo, expected_samplenum, analog_sent, sending_now;
3b203673 756 int64_t time, elapsed;
1924f59f 757
cb93f8a9
UH
758 (void)fd;
759 (void)revents;
1924f59f 760
61c39f54
BV
761 sdi = cb_data;
762 devc = sdi->priv;
b62bb97a 763 logic_todo = analog_todo = 0;
61c39f54 764
b62bb97a 765 /* How many samples should we have sent by now? */
3b203673
AG
766 time = g_get_monotonic_time();
767 elapsed = time - devc->starttime;
a7684294 768 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
7f4975b4 769
b62bb97a
BV
770 /* But never more than the limit, if there is one. */
771 if (!devc->continuous)
772 expected_samplenum = MIN(expected_samplenum, devc->limit_samples);
773
3b203673 774 /* Of those, how many do we still have to send? */
b62bb97a
BV
775 if (devc->num_logic_channels)
776 logic_todo = expected_samplenum - devc->logic_counter;
777 if (devc->num_analog_channels)
778 analog_todo = expected_samplenum - devc->analog_counter;
85b5af06 779
7f4975b4 780 while (logic_todo || analog_todo) {
c07f60e7 781 /* Logic */
b62bb97a
BV
782 if (logic_todo > 0) {
783 sending_now = MIN(logic_todo, LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
784 logic_generator(sdi, sending_now * devc->logic_unitsize);
785 packet.type = SR_DF_LOGIC;
786 packet.payload = &logic;
787 logic.length = sending_now * devc->logic_unitsize;
788 logic.unitsize = devc->logic_unitsize;
789 logic.data = devc->logic_data;
790 sr_session_send(sdi, &packet);
7f4975b4
BV
791 logic_todo -= sending_now;
792 devc->logic_counter += sending_now;
8b2d41ed
BV
793 }
794
ba7dd8bb 795 /* Analog, one channel at a time */
b62bb97a
BV
796 if (analog_todo > 0) {
797 analog_sent = 0;
49224c28
BV
798
799 g_hash_table_iter_init(&iter, devc->ch_ag);
800 while (g_hash_table_iter_next(&iter, NULL, &value)) {
7a8a1aba
BG
801 send_analog_packet(value, sdi,
802 &analog_sent, analog_todo);
8b2d41ed 803 }
b62bb97a
BV
804 analog_todo -= analog_sent;
805 devc->analog_counter += analog_sent;
8b2d41ed 806 }
3b203673
AG
807 }
808
b62bb97a
BV
809 if (!devc->continuous
810 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
811 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
7a8a1aba
BG
812 /* If we're averaging everything - now is the time to send data */
813 if (devc->avg_samples == 0) {
814 g_hash_table_iter_init(&iter, devc->ch_ag);
815 while (g_hash_table_iter_next(&iter, NULL, &value)) {
816 ag = value;
817 packet.type = SR_DF_ANALOG;
818 packet.payload = &ag->packet;
819 ag->packet.data = &ag->avg_val;
820 ag->packet.num_samples = 1;
821 sr_session_send(sdi, &packet);
822 }
823 }
824
7f4975b4 825 sr_dbg("Requested number of samples reached.");
61c39f54 826 dev_acquisition_stop(sdi, cb_data);
c216d623 827 return TRUE;
85b5af06 828 }
1924f59f 829
85b5af06
UH
830 return TRUE;
831}
832
6078d2c9 833static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 834{
61c39f54 835 struct dev_context *devc;
49224c28
BV
836 GHashTableIter iter;
837 void *value;
85b5af06 838
102f1239
BV
839 (void)cb_data;
840
e73ffd42
BV
841 if (sdi->status != SR_ST_ACTIVE)
842 return SR_ERR_DEV_CLOSED;
843
61c39f54 844 devc = sdi->priv;
b62bb97a 845 devc->continuous = !devc->limit_samples;
7f4975b4 846 devc->logic_counter = devc->analog_counter = 0;
85b5af06 847
3b203673
AG
848 /*
849 * Setting two channels connected by a pipe is a remnant from when the
850 * demo driver generated data in a thread, and collected and sent the
851 * data in the main program loop.
852 * They are kept here because it provides a convenient way of setting
853 * up a timeout-based polling mechanism.
854 */
b4750a3a 855 if (pipe(devc->pipe_fds)) {
92bcedf6 856 sr_err("%s: pipe() failed", __func__);
e46b8fb1 857 return SR_ERR;
c03ed397 858 }
85b5af06 859
49224c28
BV
860 g_hash_table_iter_init(&iter, devc->ch_ag);
861 while (g_hash_table_iter_next(&iter, NULL, &value))
862 generate_analog_pattern(value, devc->cur_samplerate);
4374219b 863
e0532047 864 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
e0532047 865 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 866
d35aaf02 867 /* Set channel encoding to binary (default is UTF-8). */
e0532047 868 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02 869
b62bb97a 870 /* Make channels unbuffered. */
e0532047 871 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 872
b62bb97a
BV
873 sr_session_source_add_channel(sdi->session, devc->channel,
874 G_IO_IN | G_IO_ERR, 40, prepare_data, (void *)sdi);
85b5af06 875
4afdfd46 876 /* Send header packet to the session bus. */
102f1239 877 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 878
3b203673
AG
879 /* We use this timestamp to decide how many more samples to send. */
880 devc->starttime = g_get_monotonic_time();
881
e46b8fb1 882 return SR_OK;
6239c175
UH
883}
884
6078d2c9 885static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 886{
8b2d41ed 887 struct dev_context *devc;
c216d623 888 struct sr_datafeed_packet packet;
7fd3e859 889
33ef7573 890 (void)cb_data;
7fd3e859 891
8b2d41ed 892 devc = sdi->priv;
a84f6ad3 893 sr_dbg("Stopping acquisition.");
49145a63 894
102f1239 895 sr_session_source_remove_channel(sdi->session, devc->channel);
e0532047 896 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
897 g_io_channel_unref(devc->channel);
898 devc->channel = NULL;
c216d623
AG
899
900 /* Send last packet. */
901 packet.type = SR_DF_END;
c07f60e7 902 sr_session_send(sdi, &packet);
7fd3e859 903
3010f21c 904 return SR_OK;
6239c175
UH
905}
906
c09f0b57 907SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
908 .name = "demo",
909 .longname = "Demo driver and pattern generator",
910 .api_version = 1,
6078d2c9
UH
911 .init = init,
912 .cleanup = cleanup,
913 .scan = scan,
914 .dev_list = dev_list,
a6630742 915 .dev_clear = NULL,
035a1078
BV
916 .config_get = config_get,
917 .config_set = config_set,
a1c743fc 918 .config_list = config_list,
6078d2c9
UH
919 .dev_open = dev_open,
920 .dev_close = dev_close,
921 .dev_acquisition_start = dev_acquisition_start,
922 .dev_acquisition_stop = dev_acquisition_stop,
b4750a3a 923 .priv = NULL,
6239c175 924};