]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
scpi-pps: Fix dev_clear() implementation
[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
600cc1a8 41#define DEFAULT_ANALOG_AMPLITUDE 10
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;
5faebab2 101 struct sr_datafeed_analog_old 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
JH
108 uint64_t cur_samplerate;
109 uint64_t limit_samples;
110 uint64_t limit_msec;
a49a320d
DE
111 uint64_t sent_samples;
112 int64_t start_us;
113 int64_t spent_us;
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
695dc859 180static int dev_acquisition_stop(struct sr_dev_inst *sdi);
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
a49a320d 296 devc = g_malloc0(sizeof(struct dev_context));
8b2d41ed 297 devc->cur_samplerate = SR_KHZ(200);
ba7dd8bb
UH
298 devc->num_logic_channels = num_logic_channels;
299 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
8b2d41ed 300 devc->logic_pattern = PATTERN_SIGROK;
ba7dd8bb 301 devc->num_analog_channels = num_analog_channels;
8b2d41ed 302
ba7dd8bb 303 /* Logic channels, all in one channel group. */
49224c28 304 cg = g_malloc0(sizeof(struct sr_channel_group));
40fd0264 305 cg->name = g_strdup("Logic");
ba7dd8bb
UH
306 for (i = 0; i < num_logic_channels; i++) {
307 sprintf(channel_name, "D%d", i);
5e23fcab 308 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ba7dd8bb 309 cg->channels = g_slist_append(cg->channels, ch);
87ca93c5 310 }
40fd0264 311 sdi->channel_groups = g_slist_append(NULL, cg);
87ca93c5 312
ba7dd8bb 313 /* Analog channels, channel groups and pattern generators. */
2b36d6c6 314 pattern = 0;
49224c28
BV
315 /* An "Analog" channel group with all analog channels in it. */
316 acg = g_malloc0(sizeof(struct sr_channel_group));
317 acg->name = g_strdup("Analog");
318 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
319
320 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
ba7dd8bb 321 for (i = 0; i < num_analog_channels; i++) {
49224c28 322 snprintf(channel_name, 16, "A%d", i);
5e23fcab 323 ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
49224c28 324 TRUE, channel_name);
49224c28 325 acg->channels = g_slist_append(acg->channels, ch);
c07f60e7 326
49224c28
BV
327 /* Every analog channel gets its own channel group as well. */
328 cg = g_malloc0(sizeof(struct sr_channel_group));
ba7dd8bb
UH
329 cg->name = g_strdup(channel_name);
330 cg->channels = g_slist_append(NULL, ch);
49224c28 331 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
85b5af06 332
49224c28
BV
333 /* Every channel gets a generator struct. */
334 ag = g_malloc(sizeof(struct analog_gen));
dddabe37 335 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
ba7dd8bb 336 ag->packet.channels = cg->channels;
8b2d41ed
BV
337 ag->packet.mq = 0;
338 ag->packet.mqflags = 0;
339 ag->packet.unit = SR_UNIT_VOLT;
340 ag->packet.data = ag->pattern_data;
2b36d6c6 341 ag->pattern = pattern;
7a8a1aba
BG
342 ag->avg_val = 0.0f;
343 ag->num_avgs = 0;
49224c28 344 g_hash_table_insert(devc->ch_ag, ch, ag);
2b36d6c6
BV
345
346 if (++pattern == ARRAY_SIZE(analog_pattern_str))
347 pattern = 0;
33ef7573 348 }
33ef7573
JH
349
350 sdi->priv = devc;
8b2d41ed
BV
351 devices = g_slist_append(devices, sdi);
352 drvc->instances = g_slist_append(drvc->instances, sdi);
33ef7573 353
067d0716 354 return devices;
6239c175
UH
355}
356
4f840ce9 357static GSList *dev_list(const struct sr_dev_driver *di)
811deee4 358{
41812aca 359 return ((struct drv_context *)(di->context))->instances;
811deee4
BV
360}
361
6078d2c9 362static int dev_open(struct sr_dev_inst *sdi)
6239c175 363{
e73ffd42 364 sdi->status = SR_ST_ACTIVE;
697785d1 365
e46b8fb1 366 return SR_OK;
6239c175
UH
367}
368
6078d2c9 369static int dev_close(struct sr_dev_inst *sdi)
6239c175 370{
decfe89d 371 sdi->status = SR_ST_INACTIVE;
697785d1
UH
372
373 return SR_OK;
6239c175
UH
374}
375
ed0b7fed
BV
376static void clear_helper(void *priv)
377{
378 struct dev_context *devc;
49224c28
BV
379 GHashTableIter iter;
380 void *value;
ed0b7fed
BV
381
382 devc = priv;
49224c28
BV
383
384 /* Analog generators. */
385 g_hash_table_iter_init(&iter, devc->ch_ag);
386 while (g_hash_table_iter_next(&iter, NULL, &value))
387 g_free(value);
388 g_hash_table_unref(devc->ch_ag);
ed0b7fed
BV
389 g_free(devc);
390}
391
6ab68731 392static int dev_clear(const struct sr_dev_driver *di)
6239c175 393{
ed0b7fed 394 return std_dev_clear(di, clear_helper);
6239c175
UH
395}
396
6ab68731
LPC
397static int cleanup(const struct sr_dev_driver *di)
398{
399 return dev_clear(di);
400}
401
584560f1 402static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 403 const struct sr_channel_group *cg)
6239c175 404{
c07f60e7 405 struct dev_context *devc;
ba7dd8bb 406 struct sr_channel *ch;
2388ae86
BV
407 struct analog_gen *ag;
408 int pattern;
6f57fd96 409
2388ae86
BV
410 if (!sdi)
411 return SR_ERR_ARG;
8f996b89 412
c07f60e7 413 devc = sdi->priv;
584560f1 414 switch (key) {
123e1313 415 case SR_CONF_SAMPLERATE:
a7684294 416 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 417 break;
2474d87e 418 case SR_CONF_LIMIT_SAMPLES:
a7684294 419 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
420 break;
421 case SR_CONF_LIMIT_MSEC:
a7684294 422 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 423 break;
7a8a1aba
BG
424 case SR_CONF_AVERAGING:
425 *data = g_variant_new_boolean(devc->avg);
426 break;
427 case SR_CONF_AVG_SAMPLES:
428 *data = g_variant_new_uint64(devc->avg_samples);
429 break;
2474d87e 430 case SR_CONF_PATTERN_MODE:
53b4680f 431 if (!cg)
660e398f 432 return SR_ERR_CHANNEL_GROUP;
49224c28 433 /* Any channel in the group will do. */
ba7dd8bb 434 ch = cg->channels->data;
3f239f08 435 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
436 pattern = devc->logic_pattern;
437 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 438 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 439 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
440 pattern = ag->pattern;
441 *data = g_variant_new_string(analog_pattern_str[pattern]);
442 } else
443 return SR_ERR_BUG;
c07f60e7 444 break;
dddabe37
BV
445 case SR_CONF_AMPLITUDE:
446 if (!cg)
447 return SR_ERR_CHANNEL_GROUP;
49224c28 448 /* Any channel in the group will do. */
dddabe37
BV
449 ch = cg->channels->data;
450 if (ch->type != SR_CHANNEL_ANALOG)
451 return SR_ERR_ARG;
49224c28 452 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
453 *data = g_variant_new_double(ag->amplitude);
454 break;
7dfcf010 455 default:
bd6fbf62 456 return SR_ERR_NA;
6239c175
UH
457 }
458
dfb0fa1a 459 return SR_OK;
6239c175
UH
460}
461
584560f1 462static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 463 const struct sr_channel_group *cg)
6239c175 464{
8b2d41ed 465 struct dev_context *devc;
4374219b 466 struct analog_gen *ag;
ba7dd8bb 467 struct sr_channel *ch;
49224c28
BV
468 GSList *l;
469 int logic_pattern, analog_pattern, ret;
61c39f54 470 unsigned int i;
1b79df2f 471 const char *stropt;
6239c175 472
8b2d41ed 473 devc = sdi->priv;
6239c175 474
e73ffd42
BV
475 if (sdi->status != SR_ST_ACTIVE)
476 return SR_ERR_DEV_CLOSED;
477
2388ae86 478 ret = SR_OK;
584560f1 479 switch (key) {
2388ae86 480 case SR_CONF_SAMPLERATE:
a7684294 481 devc->cur_samplerate = g_variant_get_uint64(data);
2388ae86
BV
482 break;
483 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
484 devc->limit_msec = 0;
485 devc->limit_samples = g_variant_get_uint64(data);
2388ae86
BV
486 break;
487 case SR_CONF_LIMIT_MSEC:
a7684294
JH
488 devc->limit_msec = g_variant_get_uint64(data);
489 devc->limit_samples = 0;
2388ae86 490 break;
7a8a1aba
BG
491 case SR_CONF_AVERAGING:
492 devc->avg = g_variant_get_boolean(data);
493 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
494 break;
495 case SR_CONF_AVG_SAMPLES:
496 devc->avg_samples = g_variant_get_uint64(data);
497 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
498 break;
2388ae86 499 case SR_CONF_PATTERN_MODE:
53b4680f 500 if (!cg)
660e398f 501 return SR_ERR_CHANNEL_GROUP;
d00088ca 502 stropt = g_variant_get_string(data, NULL);
49224c28
BV
503 logic_pattern = analog_pattern = -1;
504 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
505 if (!strcmp(stropt, logic_pattern_str[i])) {
506 logic_pattern = i;
507 break;
8b2d41ed 508 }
49224c28
BV
509 }
510 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
511 if (!strcmp(stropt, analog_pattern_str[i])) {
512 analog_pattern = i;
513 break;
8b2d41ed 514 }
49224c28
BV
515 }
516 if (logic_pattern == -1 && analog_pattern == -1)
517 return SR_ERR_ARG;
518 for (l = cg->channels; l; l = l->next) {
519 ch = l->data;
520 if (ch->type == SR_CHANNEL_LOGIC) {
521 if (logic_pattern == -1)
522 return SR_ERR_ARG;
523 sr_dbg("Setting logic pattern to %s",
524 logic_pattern_str[logic_pattern]);
525 devc->logic_pattern = logic_pattern;
526 /* Might as well do this now, these are static. */
527 if (logic_pattern == PATTERN_ALL_LOW)
528 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
529 else if (logic_pattern == PATTERN_ALL_HIGH)
530 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
531 } else if (ch->type == SR_CHANNEL_ANALOG) {
532 if (analog_pattern == -1)
533 return SR_ERR_ARG;
534 sr_dbg("Setting analog pattern for channel %s to %s",
535 ch->name, analog_pattern_str[analog_pattern]);
536 ag = g_hash_table_lookup(devc->ch_ag, ch);
537 ag->pattern = analog_pattern;
538 } else
539 return SR_ERR_BUG;
540 }
2388ae86 541 break;
dddabe37
BV
542 case SR_CONF_AMPLITUDE:
543 if (!cg)
544 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
545 for (l = cg->channels; l; l = l->next) {
546 ch = l->data;
547 if (ch->type != SR_CHANNEL_ANALOG)
548 return SR_ERR_ARG;
549 ag = g_hash_table_lookup(devc->ch_ag, ch);
550 ag->amplitude = g_variant_get_double(data);
551 }
dddabe37 552 break;
2388ae86 553 default:
bd6fbf62 554 ret = SR_ERR_NA;
6239c175
UH
555 }
556
557 return ret;
558}
559
584560f1 560static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 561 const struct sr_channel_group *cg)
a1c743fc 562{
ba7dd8bb 563 struct sr_channel *ch;
d00088ca
BV
564 GVariant *gvar;
565 GVariantBuilder gvb;
a1c743fc 566
7a1da331 567 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1
BV
568 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
569 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
7a1da331
BV
570 return SR_OK;
571 }
572
390795c0
BV
573 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
574 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 575 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
390795c0
BV
576 return SR_OK;
577 }
578
7a1da331
BV
579 if (!sdi)
580 return SR_ERR_ARG;
581
53b4680f 582 if (!cg) {
7a1da331
BV
583 switch (key) {
584 case SR_CONF_DEVICE_OPTIONS:
584560f1 585 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 586 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
7a1da331
BV
587 break;
588 case SR_CONF_SAMPLERATE:
589 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
590 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
591 ARRAY_SIZE(samplerates), sizeof(uint64_t));
592 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
593 *data = g_variant_builder_end(&gvb);
594 break;
595 default:
596 return SR_ERR_NA;
597 }
598 } else {
ba7dd8bb 599 ch = cg->channels->data;
7a1da331
BV
600 switch (key) {
601 case SR_CONF_DEVICE_OPTIONS:
49224c28 602 if (ch->type == SR_CHANNEL_LOGIC)
8249889d 603 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
49224c28 604 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
584560f1 605 sizeof(uint32_t));
e2b99f04
SA
606 else if (ch->type == SR_CHANNEL_ANALOG) {
607 if (strcmp(cg->name, "Analog") == 0)
608 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
609 devopts_cg_analog_group, ARRAY_SIZE(devopts_cg_analog_group),
610 sizeof(uint32_t));
611 else
612 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
613 devopts_cg_analog_channel, ARRAY_SIZE(devopts_cg_analog_channel),
614 sizeof(uint32_t));
615 }
49224c28
BV
616 else
617 return SR_ERR_BUG;
7a1da331
BV
618 break;
619 case SR_CONF_PATTERN_MODE:
e2b99f04
SA
620 /* The analog group (with all 4 channels) shall not have a pattern property. */
621 if (strcmp(cg->name, "Analog") == 0)
622 return SR_ERR_NA;
623
3f239f08 624 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
625 *data = g_variant_new_strv(logic_pattern_str,
626 ARRAY_SIZE(logic_pattern_str));
3f239f08 627 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
628 *data = g_variant_new_strv(analog_pattern_str,
629 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
630 else
631 return SR_ERR_BUG;
7a1da331
BV
632 break;
633 default:
634 return SR_ERR_NA;
635 }
a1c743fc
BV
636 }
637
638 return SR_OK;
639}
640
c07f60e7 641static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 642{
61c39f54 643 struct dev_context *devc;
c07f60e7
BV
644 uint64_t i, j;
645 uint8_t pat;
85b5af06 646
61c39f54 647 devc = sdi->priv;
85b5af06 648
c07f60e7 649 switch (devc->logic_pattern) {
61c39f54 650 case PATTERN_SIGROK:
c07f60e7
BV
651 memset(devc->logic_data, 0x00, size);
652 for (i = 0; i < size; i += devc->logic_unitsize) {
653 for (j = 0; j < devc->logic_unitsize; j++) {
654 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
655 devc->logic_data[i + j] = ~pat;
656 }
657 devc->step++;
917e0e71
BV
658 }
659 break;
61c39f54 660 case PATTERN_RANDOM:
5096c6a6 661 for (i = 0; i < size; i++)
61c39f54 662 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 663 break;
61c39f54 664 case PATTERN_INC:
c07f60e7
BV
665 for (i = 0; i < size; i++) {
666 for (j = 0; j < devc->logic_unitsize; j++) {
667 devc->logic_data[i + j] = devc->step;
668 }
669 devc->step++;
670 }
c03ed397 671 break;
61c39f54
BV
672 case PATTERN_ALL_LOW:
673 case PATTERN_ALL_HIGH:
674 /* These were set when the pattern mode was selected. */
c03ed397
UH
675 break;
676 default:
c07f60e7 677 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 678 break;
85b5af06
UH
679 }
680}
681
7a8a1aba
BG
682static void send_analog_packet(struct analog_gen *ag,
683 struct sr_dev_inst *sdi,
684 uint64_t *analog_sent,
a49a320d 685 uint64_t analog_pos,
7a8a1aba
BG
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;
5faebab2 695 packet.type = SR_DF_ANALOG_OLD;
7a8a1aba
BG
696 packet.payload = &ag->packet;
697
698 if (!devc->avg) {
a49a320d 699 ag_pattern_pos = analog_pos % ag->num_samples;
7a8a1aba
BG
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 {
a49a320d 708 ag_pattern_pos = analog_pos % ag->num_samples;
7a8a1aba
BG
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;
a49a320d
DE
752 uint64_t samples_todo, logic_done, analog_done, analog_sent, sending_now;
753 int64_t elapsed_us, limit_us, todo_us;
1924f59f 754
cb93f8a9
UH
755 (void)fd;
756 (void)revents;
1924f59f 757
61c39f54
BV
758 sdi = cb_data;
759 devc = sdi->priv;
760
a49a320d
DE
761 /* Just in case. */
762 if (devc->cur_samplerate <= 0 || devc->logic_unitsize <= 0
763 || (devc->num_logic_channels <= 0
764 && devc->num_analog_channels <= 0)) {
695dc859 765 dev_acquisition_stop(sdi);
a49a320d
DE
766 return G_SOURCE_CONTINUE;
767 }
7f4975b4 768
a49a320d
DE
769 /* What time span should we send samples for? */
770 elapsed_us = g_get_monotonic_time() - devc->start_us;
771 limit_us = 1000 * devc->limit_msec;
772 if (limit_us > 0 && limit_us < elapsed_us)
773 todo_us = MAX(0, limit_us - devc->spent_us);
774 else
775 todo_us = MAX(0, elapsed_us - devc->spent_us);
776
777 /* How many samples are outstanding since the last round? */
36cbd69e 778 samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
a49a320d
DE
779 / G_USEC_PER_SEC;
780 if (devc->limit_samples > 0) {
781 if (devc->limit_samples < devc->sent_samples)
782 samples_todo = 0;
783 else if (devc->limit_samples - devc->sent_samples < samples_todo)
784 samples_todo = devc->limit_samples - devc->sent_samples;
785 }
786 /* Calculate the actual time covered by this run back from the sample
787 * count, rounded towards zero. This avoids getting stuck on a too-low
788 * time delta with no samples being sent due to round-off.
789 */
790 todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
b62bb97a 791
9dfacd87
AJ
792 logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
793 analog_done = devc->num_analog_channels > 0 ? 0 : samples_todo;
85b5af06 794
a49a320d 795 while (logic_done < samples_todo || analog_done < samples_todo) {
c07f60e7 796 /* Logic */
a49a320d
DE
797 if (logic_done < samples_todo) {
798 sending_now = MIN(samples_todo - logic_done,
799 LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
800 logic_generator(sdi, sending_now * devc->logic_unitsize);
801 packet.type = SR_DF_LOGIC;
802 packet.payload = &logic;
803 logic.length = sending_now * devc->logic_unitsize;
804 logic.unitsize = devc->logic_unitsize;
805 logic.data = devc->logic_data;
806 sr_session_send(sdi, &packet);
a49a320d 807 logic_done += sending_now;
8b2d41ed
BV
808 }
809
ba7dd8bb 810 /* Analog, one channel at a time */
a49a320d 811 if (analog_done < samples_todo) {
b62bb97a 812 analog_sent = 0;
49224c28
BV
813
814 g_hash_table_iter_init(&iter, devc->ch_ag);
815 while (g_hash_table_iter_next(&iter, NULL, &value)) {
a49a320d
DE
816 send_analog_packet(value, sdi, &analog_sent,
817 devc->sent_samples + analog_done,
818 samples_todo - analog_done);
8b2d41ed 819 }
a49a320d 820 analog_done += analog_sent;
8b2d41ed 821 }
3b203673 822 }
a49a320d
DE
823 /* At this point, both logic_done and analog_done should be
824 * exactly equal to samples_todo, or else.
825 */
826 if (logic_done != samples_todo || analog_done != samples_todo) {
827 sr_err("BUG: Sample count mismatch.");
828 return G_SOURCE_REMOVE;
829 }
830 devc->sent_samples += samples_todo;
831 devc->spent_us += todo_us;
832
833 if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
834 || (limit_us > 0 && devc->spent_us >= limit_us)) {
3b203673 835
7a8a1aba
BG
836 /* If we're averaging everything - now is the time to send data */
837 if (devc->avg_samples == 0) {
838 g_hash_table_iter_init(&iter, devc->ch_ag);
839 while (g_hash_table_iter_next(&iter, NULL, &value)) {
840 ag = value;
5faebab2 841 packet.type = SR_DF_ANALOG_OLD;
7a8a1aba
BG
842 packet.payload = &ag->packet;
843 ag->packet.data = &ag->avg_val;
844 ag->packet.num_samples = 1;
845 sr_session_send(sdi, &packet);
846 }
847 }
7f4975b4 848 sr_dbg("Requested number of samples reached.");
695dc859 849 dev_acquisition_stop(sdi);
85b5af06 850 }
1924f59f 851
a49a320d 852 return G_SOURCE_CONTINUE;
85b5af06
UH
853}
854
695dc859 855static int dev_acquisition_start(const struct sr_dev_inst *sdi)
6239c175 856{
61c39f54 857 struct dev_context *devc;
49224c28
BV
858 GHashTableIter iter;
859 void *value;
85b5af06 860
e73ffd42
BV
861 if (sdi->status != SR_ST_ACTIVE)
862 return SR_ERR_DEV_CLOSED;
863
61c39f54 864 devc = sdi->priv;
a49a320d 865 devc->sent_samples = 0;
85b5af06 866
49224c28
BV
867 g_hash_table_iter_init(&iter, devc->ch_ag);
868 while (g_hash_table_iter_next(&iter, NULL, &value))
869 generate_analog_pattern(value, devc->cur_samplerate);
4374219b 870
98c01fe1
DE
871 sr_session_source_add(sdi->session, -1, 0, 100,
872 prepare_data, (struct sr_dev_inst *)sdi);
85b5af06 873
102f1239 874 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 875
3b203673 876 /* We use this timestamp to decide how many more samples to send. */
a49a320d
DE
877 devc->start_us = g_get_monotonic_time();
878 devc->spent_us = 0;
3b203673 879
e46b8fb1 880 return SR_OK;
6239c175
UH
881}
882
695dc859 883static int dev_acquisition_stop(struct sr_dev_inst *sdi)
6239c175 884{
a84f6ad3 885 sr_dbg("Stopping acquisition.");
027bf077 886 sr_session_source_remove(sdi->session, -1);
3be42bc2 887 std_session_send_df_end(sdi, LOG_PREFIX);
7fd3e859 888
3010f21c 889 return SR_OK;
6239c175
UH
890}
891
c09f0b57 892SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
893 .name = "demo",
894 .longname = "Demo driver and pattern generator",
895 .api_version = 1,
6078d2c9
UH
896 .init = init,
897 .cleanup = cleanup,
898 .scan = scan,
899 .dev_list = dev_list,
6ab68731 900 .dev_clear = dev_clear,
035a1078
BV
901 .config_get = config_get,
902 .config_set = config_set,
a1c743fc 903 .config_list = config_list,
6078d2c9
UH
904 .dev_open = dev_open,
905 .dev_close = dev_close,
906 .dev_acquisition_start = dev_acquisition_start,
907 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 908 .context = NULL,
6239c175 909};