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