]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
libsigrok-internal.h: Remove unused prototypes
[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>
25#include <string.h>
4374219b 26#include <math.h>
c1aae900 27#include <libsigrok/libsigrok.h>
45c59c8b 28#include "libsigrok-internal.h"
6239c175 29
3544f848 30#define LOG_PREFIX "demo"
92bcedf6 31
3f239f08
UH
32#define DEFAULT_NUM_LOGIC_CHANNELS 8
33#define DEFAULT_NUM_ANALOG_CHANNELS 4
c03ed397 34
8b2d41ed 35/* The size in bytes of chunks to send through the session bus. */
61c39f54 36#define LOGIC_BUFSIZE 4096
8b2d41ed
BV
37/* Size of the analog pattern space per channel. */
38#define ANALOG_BUFSIZE 4096
2474d87e 39
dddabe37 40#define DEFAULT_ANALOG_AMPLITUDE 25
4374219b
DJ
41#define ANALOG_SAMPLES_PER_PERIOD 20
42
2388ae86 43/* Logic patterns we can generate. */
e15f48c2 44enum {
0d31276b 45 /**
ba7dd8bb 46 * Spells "sigrok" across 8 channels using '0's (with '1's as
61c39f54 47 * "background") when displayed using the 'bits' output format.
95035832 48 * The pattern is repeated every 8 channels, shifted to the right
c07f60e7 49 * in time by one bit.
0d31276b 50 */
c8f4624d 51 PATTERN_SIGROK,
0d31276b 52
ba7dd8bb 53 /** Pseudo-random values on all channels. */
c8f4624d 54 PATTERN_RANDOM,
0d31276b
UH
55
56 /**
95035832 57 * Incrementing number across 8 channels. The pattern is repeated
ba7dd8bb 58 * every 8 channels, shifted to the right in time by one bit.
0d31276b 59 */
c8f4624d 60 PATTERN_INC,
c03ed397 61
ba7dd8bb 62 /** All channels have a low logic state. */
c03ed397
UH
63 PATTERN_ALL_LOW,
64
ba7dd8bb 65 /** All channels have a high logic state. */
c03ed397 66 PATTERN_ALL_HIGH,
2388ae86 67};
8b2d41ed 68
2388ae86
BV
69/* Analog patterns we can generate. */
70enum {
8b2d41ed
BV
71 /**
72 * Square wave.
73 */
74 PATTERN_SQUARE,
4374219b 75 PATTERN_SINE,
091c9621 76 PATTERN_TRIANGLE,
9f54e0e8 77 PATTERN_SAWTOOTH,
e15f48c2 78};
85b5af06 79
8b2d41ed 80static const char *logic_pattern_str[] = {
61c39f54
BV
81 "sigrok",
82 "random",
83 "incremental",
84 "all-low",
85 "all-high",
86};
87
8b2d41ed
BV
88static const char *analog_pattern_str[] = {
89 "square",
4374219b 90 "sine",
091c9621 91 "triangle",
9f54e0e8 92 "sawtooth",
8b2d41ed
BV
93};
94
95struct analog_gen {
96 int pattern;
dddabe37 97 float amplitude;
8b2d41ed
BV
98 float pattern_data[ANALOG_BUFSIZE];
99 unsigned int num_samples;
100 struct sr_datafeed_analog packet;
7a8a1aba
BG
101 float avg_val; /* Average value */
102 unsigned num_avgs; /* Number of samples averaged */
8b2d41ed
BV
103};
104
b4750a3a
BV
105/* Private, per-device-instance driver context. */
106struct dev_context {
a7684294 107 uint64_t cur_samplerate;
b62bb97a 108 gboolean continuous;
a7684294
JH
109 uint64_t limit_samples;
110 uint64_t limit_msec;
7f4975b4
BV
111 uint64_t logic_counter;
112 uint64_t analog_counter;
3b203673 113 int64_t starttime;
61c39f54 114 uint64_t step;
8b2d41ed 115 /* Logic */
ba7dd8bb 116 int32_t num_logic_channels;
c07f60e7 117 unsigned int logic_unitsize;
660e398f 118 /* There is only ever one logic channel group, so its pattern goes here. */
c07f60e7
BV
119 uint8_t logic_pattern;
120 unsigned char logic_data[LOGIC_BUFSIZE];
8b2d41ed 121 /* Analog */
ba7dd8bb 122 int32_t num_analog_channels;
49224c28 123 GHashTable *ch_ag;
7a8a1aba
BG
124 gboolean avg; /* True if averaging is enabled */
125 uint64_t avg_samples;
c07f60e7
BV
126};
127
1e4a7cac
BV
128static const uint32_t drvopts[] = {
129 SR_CONF_DEMO_DEV,
130 SR_CONF_LOGIC_ANALYZER,
131 SR_CONF_OSCILLOSCOPE,
132};
133
584560f1 134static const uint32_t scanopts[] = {
3f239f08
UH
135 SR_CONF_NUM_LOGIC_CHANNELS,
136 SR_CONF_NUM_ANALOG_CHANNELS,
e15f48c2 137};
85b5af06 138
390795c0 139static const uint32_t devopts[] = {
1e4a7cac 140 SR_CONF_CONTINUOUS | SR_CONF_SET,
5827f61b
BV
141 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
142 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
390795c0 143 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
7a8a1aba
BG
144 SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET,
145 SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET,
390795c0
BV
146};
147
148static const uint32_t devopts_cg_logic[] = {
f12d9979 149 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
49224c28
BV
150};
151
e2b99f04
SA
152static const uint32_t devopts_cg_analog_group[] = {
153 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
154};
155
156static const uint32_t devopts_cg_analog_channel[] = {
f12d9979
BV
157 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
158 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
7a1da331
BV
159};
160
d00088ca
BV
161static const uint64_t samplerates[] = {
162 SR_HZ(1),
163 SR_GHZ(1),
164 SR_HZ(1),
4bfbf9fc
BV
165};
166
329733d9 167static const uint8_t pattern_sigrok[] = {
917e0e71
BV
168 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
169 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
170 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
171 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
172 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
173 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176};
177
dcf03d6d 178SR_PRIV struct sr_dev_driver demo_driver_info;
6239c175 179
6078d2c9 180static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 181
4f840ce9 182static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
61136ea6 183{
f6beaac5 184 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
185}
186
49224c28 187static void generate_analog_pattern(struct analog_gen *ag, uint64_t sample_rate)
8b2d41ed 188{
4374219b 189 double t, frequency;
8b2d41ed
BV
190 float value;
191 unsigned int num_samples, i;
192 int last_end;
193
49224c28 194 sr_dbg("Generating %s pattern.", analog_pattern_str[ag->pattern]);
4374219b 195
49224c28 196 num_samples = ANALOG_BUFSIZE / sizeof(float);
8b2d41ed 197
4374219b 198 switch (ag->pattern) {
8b2d41ed 199 case PATTERN_SQUARE:
dddabe37 200 value = ag->amplitude;
8b2d41ed
BV
201 last_end = 0;
202 for (i = 0; i < num_samples; i++) {
203 if (i % 5 == 0)
204 value = -value;
205 if (i % 10 == 0)
3772c049 206 last_end = i;
8b2d41ed
BV
207 ag->pattern_data[i] = value;
208 }
209 ag->num_samples = last_end;
210 break;
4374219b 211 case PATTERN_SINE:
9d156555 212 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
4374219b
DJ
213
214 /* Make sure the number of samples we put out is an integer
215 * multiple of our period size */
216 /* FIXME we actually need only one period. A ringbuffer would be
f3f19d11 217 * useful here. */
4374219b
DJ
218 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
219 num_samples--;
220
221 for (i = 0; i < num_samples; i++) {
222 t = (double) i / (double) sample_rate;
dddabe37 223 ag->pattern_data[i] = ag->amplitude *
bbc42811 224 sin(2 * G_PI * frequency * t);
4374219b
DJ
225 }
226
091c9621
DJ
227 ag->num_samples = num_samples;
228 break;
091c9621 229 case PATTERN_TRIANGLE:
9d156555 230 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
091c9621
DJ
231
232 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
233 num_samples--;
234
235 for (i = 0; i < num_samples; i++) {
236 t = (double) i / (double) sample_rate;
bbc42811
AJ
237 ag->pattern_data[i] = (2 * ag->amplitude / G_PI) *
238 asin(sin(2 * G_PI * frequency * t));
091c9621
DJ
239 }
240
9f54e0e8
DJ
241 ag->num_samples = num_samples;
242 break;
9f54e0e8 243 case PATTERN_SAWTOOTH:
9d156555 244 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
9f54e0e8
DJ
245
246 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
247 num_samples--;
248
249 for (i = 0; i < num_samples; i++) {
250 t = (double) i / (double) sample_rate;
dddabe37 251 ag->pattern_data[i] = 2 * ag->amplitude *
9f54e0e8
DJ
252 ((t * frequency) - floor(0.5f + t * frequency));
253 }
254
4374219b
DJ
255 ag->num_samples = num_samples;
256 break;
8b2d41ed
BV
257 }
258}
259
4f840ce9 260static GSList *scan(struct sr_dev_driver *di, GSList *options)
6239c175 261{
b4750a3a 262 struct drv_context *drvc;
33ef7573 263 struct dev_context *devc;
c07f60e7 264 struct sr_dev_inst *sdi;
ba7dd8bb 265 struct sr_channel *ch;
49224c28 266 struct sr_channel_group *cg, *acg;
c07f60e7 267 struct sr_config *src;
8b2d41ed 268 struct analog_gen *ag;
c07f60e7 269 GSList *devices, *l;
ba7dd8bb
UH
270 int num_logic_channels, num_analog_channels, pattern, i;
271 char channel_name[16];
067d0716 272
41812aca 273 drvc = di->context;
4b97c74e 274
3f239f08
UH
275 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
276 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
c07f60e7
BV
277 for (l = options; l; l = l->next) {
278 src = l->data;
279 switch (src->key) {
3f239f08 280 case SR_CONF_NUM_LOGIC_CHANNELS:
ba7dd8bb 281 num_logic_channels = g_variant_get_int32(src->data);
c07f60e7 282 break;
3f239f08 283 case SR_CONF_NUM_ANALOG_CHANNELS:
ba7dd8bb 284 num_analog_channels = g_variant_get_int32(src->data);
c07f60e7
BV
285 break;
286 }
287 }
85b5af06 288
c07f60e7 289 devices = NULL;
0af636be 290
aac29cc1 291 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be 292 sdi->status = SR_ST_ACTIVE;
4b664cd6 293 sdi->model = g_strdup("Demo device");
a873c594 294 sdi->driver = di;
e15f48c2 295
49224c28 296 devc = g_malloc(sizeof(struct dev_context));
8b2d41ed
BV
297 devc->cur_samplerate = SR_KHZ(200);
298 devc->limit_samples = 0;
299 devc->limit_msec = 0;
300 devc->step = 0;
b62bb97a 301 devc->continuous = FALSE;
ba7dd8bb
UH
302 devc->num_logic_channels = num_logic_channels;
303 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
8b2d41ed 304 devc->logic_pattern = PATTERN_SIGROK;
ba7dd8bb 305 devc->num_analog_channels = num_analog_channels;
7a8a1aba
BG
306 devc->avg = FALSE;
307 devc->avg_samples = 0;
8b2d41ed 308
ba7dd8bb 309 /* Logic channels, all in one channel group. */
49224c28 310 cg = g_malloc0(sizeof(struct sr_channel_group));
40fd0264 311 cg->name = g_strdup("Logic");
ba7dd8bb
UH
312 for (i = 0; i < num_logic_channels; i++) {
313 sprintf(channel_name, "D%d", i);
5e23fcab 314 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ba7dd8bb 315 cg->channels = g_slist_append(cg->channels, ch);
87ca93c5 316 }
40fd0264 317 sdi->channel_groups = g_slist_append(NULL, cg);
87ca93c5 318
ba7dd8bb 319 /* Analog channels, channel groups and pattern generators. */
2b36d6c6 320 pattern = 0;
49224c28
BV
321 /* An "Analog" channel group with all analog channels in it. */
322 acg = g_malloc0(sizeof(struct sr_channel_group));
323 acg->name = g_strdup("Analog");
324 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
325
326 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
ba7dd8bb 327 for (i = 0; i < num_analog_channels; i++) {
49224c28 328 snprintf(channel_name, 16, "A%d", i);
5e23fcab 329 ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
49224c28 330 TRUE, channel_name);
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;
7a8a1aba
BG
348 ag->avg_val = 0.0f;
349 ag->num_avgs = 0;
49224c28 350 g_hash_table_insert(devc->ch_ag, ch, ag);
2b36d6c6
BV
351
352 if (++pattern == ARRAY_SIZE(analog_pattern_str))
353 pattern = 0;
33ef7573 354 }
33ef7573
JH
355
356 sdi->priv = devc;
8b2d41ed
BV
357 devices = g_slist_append(devices, sdi);
358 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 359
067d0716 360 return devices;
6239c175
UH
361}
362
4f840ce9 363static GSList *dev_list(const struct sr_dev_driver *di)
811deee4 364{
41812aca 365 return ((struct drv_context *)(di->context))->instances;
811deee4
BV
366}
367
6078d2c9 368static int dev_open(struct sr_dev_inst *sdi)
6239c175 369{
e73ffd42 370 sdi->status = SR_ST_ACTIVE;
697785d1 371
e46b8fb1 372 return SR_OK;
6239c175
UH
373}
374
6078d2c9 375static int dev_close(struct sr_dev_inst *sdi)
6239c175 376{
decfe89d 377 sdi->status = SR_ST_INACTIVE;
697785d1
UH
378
379 return SR_OK;
6239c175
UH
380}
381
ed0b7fed
BV
382static void clear_helper(void *priv)
383{
384 struct dev_context *devc;
49224c28
BV
385 GHashTableIter iter;
386 void *value;
ed0b7fed
BV
387
388 devc = priv;
49224c28
BV
389
390 /* Analog generators. */
391 g_hash_table_iter_init(&iter, devc->ch_ag);
392 while (g_hash_table_iter_next(&iter, NULL, &value))
393 g_free(value);
394 g_hash_table_unref(devc->ch_ag);
ed0b7fed
BV
395 g_free(devc);
396}
397
4f840ce9 398static int cleanup(const struct sr_dev_driver *di)
6239c175 399{
ed0b7fed 400 return std_dev_clear(di, clear_helper);
6239c175
UH
401}
402
584560f1 403static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 404 const struct sr_channel_group *cg)
6239c175 405{
c07f60e7 406 struct dev_context *devc;
ba7dd8bb 407 struct sr_channel *ch;
2388ae86
BV
408 struct analog_gen *ag;
409 int pattern;
6f57fd96 410
2388ae86
BV
411 if (!sdi)
412 return SR_ERR_ARG;
8f996b89 413
c07f60e7 414 devc = sdi->priv;
584560f1 415 switch (key) {
123e1313 416 case SR_CONF_SAMPLERATE:
a7684294 417 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 418 break;
2474d87e 419 case SR_CONF_LIMIT_SAMPLES:
a7684294 420 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
421 break;
422 case SR_CONF_LIMIT_MSEC:
a7684294 423 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 424 break;
7a8a1aba
BG
425 case SR_CONF_AVERAGING:
426 *data = g_variant_new_boolean(devc->avg);
427 break;
428 case SR_CONF_AVG_SAMPLES:
429 *data = g_variant_new_uint64(devc->avg_samples);
430 break;
2474d87e 431 case SR_CONF_PATTERN_MODE:
53b4680f 432 if (!cg)
660e398f 433 return SR_ERR_CHANNEL_GROUP;
49224c28 434 /* Any channel in the group will do. */
ba7dd8bb 435 ch = cg->channels->data;
3f239f08 436 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
437 pattern = devc->logic_pattern;
438 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 439 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 440 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
441 pattern = ag->pattern;
442 *data = g_variant_new_string(analog_pattern_str[pattern]);
443 } else
444 return SR_ERR_BUG;
c07f60e7 445 break;
dddabe37
BV
446 case SR_CONF_AMPLITUDE:
447 if (!cg)
448 return SR_ERR_CHANNEL_GROUP;
49224c28 449 /* Any channel in the group will do. */
dddabe37
BV
450 ch = cg->channels->data;
451 if (ch->type != SR_CHANNEL_ANALOG)
452 return SR_ERR_ARG;
49224c28 453 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
454 *data = g_variant_new_double(ag->amplitude);
455 break;
7dfcf010 456 default:
bd6fbf62 457 return SR_ERR_NA;
6239c175
UH
458 }
459
dfb0fa1a 460 return SR_OK;
6239c175
UH
461}
462
584560f1 463static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 464 const struct sr_channel_group *cg)
6239c175 465{
8b2d41ed 466 struct dev_context *devc;
4374219b 467 struct analog_gen *ag;
ba7dd8bb 468 struct sr_channel *ch;
49224c28
BV
469 GSList *l;
470 int logic_pattern, analog_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 479 ret = SR_OK;
584560f1 480 switch (key) {
2388ae86 481 case SR_CONF_SAMPLERATE:
a7684294 482 devc->cur_samplerate = g_variant_get_uint64(data);
2388ae86
BV
483 break;
484 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
485 devc->limit_msec = 0;
486 devc->limit_samples = g_variant_get_uint64(data);
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;
2388ae86 491 break;
7a8a1aba
BG
492 case SR_CONF_AVERAGING:
493 devc->avg = g_variant_get_boolean(data);
494 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
495 break;
496 case SR_CONF_AVG_SAMPLES:
497 devc->avg_samples = g_variant_get_uint64(data);
498 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
499 break;
2388ae86 500 case SR_CONF_PATTERN_MODE:
53b4680f 501 if (!cg)
660e398f 502 return SR_ERR_CHANNEL_GROUP;
d00088ca 503 stropt = g_variant_get_string(data, NULL);
49224c28
BV
504 logic_pattern = analog_pattern = -1;
505 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
506 if (!strcmp(stropt, logic_pattern_str[i])) {
507 logic_pattern = i;
508 break;
8b2d41ed 509 }
49224c28
BV
510 }
511 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
512 if (!strcmp(stropt, analog_pattern_str[i])) {
513 analog_pattern = i;
514 break;
8b2d41ed 515 }
49224c28
BV
516 }
517 if (logic_pattern == -1 && analog_pattern == -1)
518 return SR_ERR_ARG;
519 for (l = cg->channels; l; l = l->next) {
520 ch = l->data;
521 if (ch->type == SR_CHANNEL_LOGIC) {
522 if (logic_pattern == -1)
523 return SR_ERR_ARG;
524 sr_dbg("Setting logic pattern to %s",
525 logic_pattern_str[logic_pattern]);
526 devc->logic_pattern = logic_pattern;
527 /* Might as well do this now, these are static. */
528 if (logic_pattern == PATTERN_ALL_LOW)
529 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
530 else if (logic_pattern == PATTERN_ALL_HIGH)
531 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
532 } else if (ch->type == SR_CHANNEL_ANALOG) {
533 if (analog_pattern == -1)
534 return SR_ERR_ARG;
535 sr_dbg("Setting analog pattern for channel %s to %s",
536 ch->name, analog_pattern_str[analog_pattern]);
537 ag = g_hash_table_lookup(devc->ch_ag, ch);
538 ag->pattern = analog_pattern;
539 } else
540 return SR_ERR_BUG;
541 }
2388ae86 542 break;
dddabe37
BV
543 case SR_CONF_AMPLITUDE:
544 if (!cg)
545 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
546 for (l = cg->channels; l; l = l->next) {
547 ch = l->data;
548 if (ch->type != SR_CHANNEL_ANALOG)
549 return SR_ERR_ARG;
550 ag = g_hash_table_lookup(devc->ch_ag, ch);
551 ag->amplitude = g_variant_get_double(data);
552 }
dddabe37 553 break;
2388ae86 554 default:
bd6fbf62 555 ret = SR_ERR_NA;
6239c175
UH
556 }
557
558 return ret;
559}
560
584560f1 561static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 562 const struct sr_channel_group *cg)
a1c743fc 563{
ba7dd8bb 564 struct sr_channel *ch;
d00088ca
BV
565 GVariant *gvar;
566 GVariantBuilder gvb;
a1c743fc 567
7a1da331 568 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1
BV
569 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
570 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
7a1da331
BV
571 return SR_OK;
572 }
573
390795c0
BV
574 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
575 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 576 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
390795c0
BV
577 return SR_OK;
578 }
579
7a1da331
BV
580 if (!sdi)
581 return SR_ERR_ARG;
582
53b4680f 583 if (!cg) {
7a1da331
BV
584 switch (key) {
585 case SR_CONF_DEVICE_OPTIONS:
584560f1 586 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 587 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
7a1da331
BV
588 break;
589 case SR_CONF_SAMPLERATE:
590 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
591 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
592 ARRAY_SIZE(samplerates), sizeof(uint64_t));
593 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
594 *data = g_variant_builder_end(&gvb);
595 break;
596 default:
597 return SR_ERR_NA;
598 }
599 } else {
ba7dd8bb 600 ch = cg->channels->data;
7a1da331
BV
601 switch (key) {
602 case SR_CONF_DEVICE_OPTIONS:
49224c28 603 if (ch->type == SR_CHANNEL_LOGIC)
8249889d 604 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
49224c28 605 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
584560f1 606 sizeof(uint32_t));
e2b99f04
SA
607 else if (ch->type == SR_CHANNEL_ANALOG) {
608 if (strcmp(cg->name, "Analog") == 0)
609 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
610 devopts_cg_analog_group, ARRAY_SIZE(devopts_cg_analog_group),
611 sizeof(uint32_t));
612 else
613 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
614 devopts_cg_analog_channel, ARRAY_SIZE(devopts_cg_analog_channel),
615 sizeof(uint32_t));
616 }
49224c28
BV
617 else
618 return SR_ERR_BUG;
7a1da331
BV
619 break;
620 case SR_CONF_PATTERN_MODE:
e2b99f04
SA
621 /* The analog group (with all 4 channels) shall not have a pattern property. */
622 if (strcmp(cg->name, "Analog") == 0)
623 return SR_ERR_NA;
624
3f239f08 625 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
626 *data = g_variant_new_strv(logic_pattern_str,
627 ARRAY_SIZE(logic_pattern_str));
3f239f08 628 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
629 *data = g_variant_new_strv(analog_pattern_str,
630 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
631 else
632 return SR_ERR_BUG;
7a1da331
BV
633 break;
634 default:
635 return SR_ERR_NA;
636 }
a1c743fc
BV
637 }
638
639 return SR_OK;
640}
641
c07f60e7 642static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 643{
61c39f54 644 struct dev_context *devc;
c07f60e7
BV
645 uint64_t i, j;
646 uint8_t pat;
85b5af06 647
61c39f54 648 devc = sdi->priv;
85b5af06 649
c07f60e7 650 switch (devc->logic_pattern) {
61c39f54 651 case PATTERN_SIGROK:
c07f60e7
BV
652 memset(devc->logic_data, 0x00, size);
653 for (i = 0; i < size; i += devc->logic_unitsize) {
654 for (j = 0; j < devc->logic_unitsize; j++) {
655 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
656 devc->logic_data[i + j] = ~pat;
657 }
658 devc->step++;
917e0e71
BV
659 }
660 break;
61c39f54 661 case PATTERN_RANDOM:
5096c6a6 662 for (i = 0; i < size; i++)
61c39f54 663 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 664 break;
61c39f54 665 case PATTERN_INC:
c07f60e7
BV
666 for (i = 0; i < size; i++) {
667 for (j = 0; j < devc->logic_unitsize; j++) {
668 devc->logic_data[i + j] = devc->step;
669 }
670 devc->step++;
671 }
c03ed397 672 break;
61c39f54
BV
673 case PATTERN_ALL_LOW:
674 case PATTERN_ALL_HIGH:
675 /* These were set when the pattern mode was selected. */
c03ed397
UH
676 break;
677 default:
c07f60e7 678 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 679 break;
85b5af06
UH
680 }
681}
682
7a8a1aba
BG
683static void send_analog_packet(struct analog_gen *ag,
684 struct sr_dev_inst *sdi,
685 uint64_t *analog_sent,
686 uint64_t analog_todo)
687{
688 struct sr_datafeed_packet packet;
689 struct dev_context *devc;
690 uint64_t sending_now, to_avg;
691 int ag_pattern_pos;
692 unsigned int i;
693
694 devc = sdi->priv;
695 packet.type = SR_DF_ANALOG;
696 packet.payload = &ag->packet;
697
698 if (!devc->avg) {
699 ag_pattern_pos = devc->analog_counter % ag->num_samples;
700 sending_now = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
701 ag->packet.data = ag->pattern_data + ag_pattern_pos;
702 ag->packet.num_samples = sending_now;
703 sr_session_send(sdi, &packet);
704
705 /* Whichever channel group gets there first. */
706 *analog_sent = MAX(*analog_sent, sending_now);
707 } else {
708 ag_pattern_pos = devc->analog_counter % ag->num_samples;
709 to_avg = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
710
711 for (i = 0; i < to_avg; i++) {
712 ag->avg_val = (ag->avg_val +
713 *(ag->pattern_data +
714 ag_pattern_pos + i)) / 2;
715 ag->num_avgs++;
716 /* Time to send averaged data? */
717 if (devc->avg_samples > 0 &&
718 ag->num_avgs >= devc->avg_samples)
719 goto do_send;
720 }
721
722 if (devc->avg_samples == 0) {
723 /* We're averaging all the samples, so wait with
724 * sending until the very end.
725 */
726 *analog_sent = ag->num_avgs;
727 return;
728 }
729
730do_send:
731 ag->packet.data = &ag->avg_val;
732 ag->packet.num_samples = 1;
733
734 sr_session_send(sdi, &packet);
735 *analog_sent = ag->num_avgs;
736
737 ag->num_avgs = 0;
738 ag->avg_val = 0.0f;
739 }
740}
741
85b5af06 742/* Callback handling data */
61c39f54 743static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 744{
61c39f54
BV
745 struct sr_dev_inst *sdi;
746 struct dev_context *devc;
b9c735a2 747 struct sr_datafeed_packet packet;
9c939c51 748 struct sr_datafeed_logic logic;
8b2d41ed 749 struct analog_gen *ag;
49224c28
BV
750 GHashTableIter iter;
751 void *value;
b62bb97a 752 uint64_t logic_todo, analog_todo, expected_samplenum, analog_sent, sending_now;
3b203673 753 int64_t time, elapsed;
1924f59f 754
cb93f8a9
UH
755 (void)fd;
756 (void)revents;
1924f59f 757
61c39f54
BV
758 sdi = cb_data;
759 devc = sdi->priv;
b62bb97a 760 logic_todo = analog_todo = 0;
61c39f54 761
b62bb97a 762 /* How many samples should we have sent by now? */
3b203673
AG
763 time = g_get_monotonic_time();
764 elapsed = time - devc->starttime;
1a46cc62 765 expected_samplenum = elapsed * devc->cur_samplerate / (1000 * 1000);
7f4975b4 766
b62bb97a
BV
767 /* But never more than the limit, if there is one. */
768 if (!devc->continuous)
769 expected_samplenum = MIN(expected_samplenum, devc->limit_samples);
770
3b203673 771 /* Of those, how many do we still have to send? */
536141ff 772 if (devc->num_logic_channels && (devc->logic_counter < devc->limit_samples))
b62bb97a 773 logic_todo = expected_samplenum - devc->logic_counter;
536141ff 774 if (devc->num_analog_channels && (devc->analog_counter < devc->limit_samples))
b62bb97a 775 analog_todo = expected_samplenum - devc->analog_counter;
85b5af06 776
7f4975b4 777 while (logic_todo || analog_todo) {
c07f60e7 778 /* Logic */
b62bb97a
BV
779 if (logic_todo > 0) {
780 sending_now = MIN(logic_todo, LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
781 logic_generator(sdi, sending_now * devc->logic_unitsize);
782 packet.type = SR_DF_LOGIC;
783 packet.payload = &logic;
784 logic.length = sending_now * devc->logic_unitsize;
785 logic.unitsize = devc->logic_unitsize;
786 logic.data = devc->logic_data;
787 sr_session_send(sdi, &packet);
7f4975b4
BV
788 logic_todo -= sending_now;
789 devc->logic_counter += sending_now;
8b2d41ed
BV
790 }
791
ba7dd8bb 792 /* Analog, one channel at a time */
b62bb97a
BV
793 if (analog_todo > 0) {
794 analog_sent = 0;
49224c28
BV
795
796 g_hash_table_iter_init(&iter, devc->ch_ag);
797 while (g_hash_table_iter_next(&iter, NULL, &value)) {
7a8a1aba
BG
798 send_analog_packet(value, sdi,
799 &analog_sent, analog_todo);
8b2d41ed 800 }
b62bb97a
BV
801 analog_todo -= analog_sent;
802 devc->analog_counter += analog_sent;
8b2d41ed 803 }
3b203673
AG
804 }
805
b62bb97a
BV
806 if (!devc->continuous
807 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
808 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
7a8a1aba
BG
809 /* If we're averaging everything - now is the time to send data */
810 if (devc->avg_samples == 0) {
811 g_hash_table_iter_init(&iter, devc->ch_ag);
812 while (g_hash_table_iter_next(&iter, NULL, &value)) {
813 ag = value;
814 packet.type = SR_DF_ANALOG;
815 packet.payload = &ag->packet;
816 ag->packet.data = &ag->avg_val;
817 ag->packet.num_samples = 1;
818 sr_session_send(sdi, &packet);
819 }
820 }
821
7f4975b4 822 sr_dbg("Requested number of samples reached.");
61c39f54 823 dev_acquisition_stop(sdi, cb_data);
c216d623 824 return TRUE;
85b5af06 825 }
1924f59f 826
85b5af06
UH
827 return TRUE;
828}
829
6078d2c9 830static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 831{
61c39f54 832 struct dev_context *devc;
49224c28
BV
833 GHashTableIter iter;
834 void *value;
85b5af06 835
102f1239
BV
836 (void)cb_data;
837
e73ffd42
BV
838 if (sdi->status != SR_ST_ACTIVE)
839 return SR_ERR_DEV_CLOSED;
840
61c39f54 841 devc = sdi->priv;
b62bb97a 842 devc->continuous = !devc->limit_samples;
7f4975b4 843 devc->logic_counter = devc->analog_counter = 0;
85b5af06 844
49224c28
BV
845 g_hash_table_iter_init(&iter, devc->ch_ag);
846 while (g_hash_table_iter_next(&iter, NULL, &value))
847 generate_analog_pattern(value, devc->cur_samplerate);
4374219b 848
027bf077 849 sr_session_source_add(sdi->session, -1, 0, 40, prepare_data, (void *)sdi);
85b5af06 850
4afdfd46 851 /* Send header packet to the session bus. */
102f1239 852 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 853
3b203673
AG
854 /* We use this timestamp to decide how many more samples to send. */
855 devc->starttime = g_get_monotonic_time();
856
e46b8fb1 857 return SR_OK;
6239c175
UH
858}
859
6078d2c9 860static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 861{
c216d623 862 struct sr_datafeed_packet packet;
7fd3e859 863
33ef7573 864 (void)cb_data;
7fd3e859 865
a84f6ad3 866 sr_dbg("Stopping acquisition.");
49145a63 867
027bf077 868 sr_session_source_remove(sdi->session, -1);
c216d623
AG
869
870 /* Send last packet. */
871 packet.type = SR_DF_END;
c07f60e7 872 sr_session_send(sdi, &packet);
7fd3e859 873
3010f21c 874 return SR_OK;
6239c175
UH
875}
876
c09f0b57 877SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
878 .name = "demo",
879 .longname = "Demo driver and pattern generator",
880 .api_version = 1,
6078d2c9
UH
881 .init = init,
882 .cleanup = cleanup,
883 .scan = scan,
884 .dev_list = dev_list,
a6630742 885 .dev_clear = NULL,
035a1078
BV
886 .config_get = config_get,
887 .config_set = config_set,
a1c743fc 888 .config_list = config_list,
6078d2c9
UH
889 .dev_open = dev_open,
890 .dev_close = dev_close,
891 .dev_acquisition_start = dev_acquisition_start,
892 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 893 .context = NULL,
6239c175 894};