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