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