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