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