]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/demo.c
Drop unneeded std_session_send_df_header() comments.
[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
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
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
4f840ce9 392static int cleanup(const struct sr_dev_driver *di)
6239c175 393{
ed0b7fed 394 return std_dev_clear(di, clear_helper);
6239c175
UH
395}
396
584560f1 397static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 398 const struct sr_channel_group *cg)
6239c175 399{
c07f60e7 400 struct dev_context *devc;
ba7dd8bb 401 struct sr_channel *ch;
2388ae86
BV
402 struct analog_gen *ag;
403 int pattern;
6f57fd96 404
2388ae86
BV
405 if (!sdi)
406 return SR_ERR_ARG;
8f996b89 407
c07f60e7 408 devc = sdi->priv;
584560f1 409 switch (key) {
123e1313 410 case SR_CONF_SAMPLERATE:
a7684294 411 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 412 break;
2474d87e 413 case SR_CONF_LIMIT_SAMPLES:
a7684294 414 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
415 break;
416 case SR_CONF_LIMIT_MSEC:
a7684294 417 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 418 break;
7a8a1aba
BG
419 case SR_CONF_AVERAGING:
420 *data = g_variant_new_boolean(devc->avg);
421 break;
422 case SR_CONF_AVG_SAMPLES:
423 *data = g_variant_new_uint64(devc->avg_samples);
424 break;
2474d87e 425 case SR_CONF_PATTERN_MODE:
53b4680f 426 if (!cg)
660e398f 427 return SR_ERR_CHANNEL_GROUP;
49224c28 428 /* Any channel in the group will do. */
ba7dd8bb 429 ch = cg->channels->data;
3f239f08 430 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
431 pattern = devc->logic_pattern;
432 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 433 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 434 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
435 pattern = ag->pattern;
436 *data = g_variant_new_string(analog_pattern_str[pattern]);
437 } else
438 return SR_ERR_BUG;
c07f60e7 439 break;
dddabe37
BV
440 case SR_CONF_AMPLITUDE:
441 if (!cg)
442 return SR_ERR_CHANNEL_GROUP;
49224c28 443 /* Any channel in the group will do. */
dddabe37
BV
444 ch = cg->channels->data;
445 if (ch->type != SR_CHANNEL_ANALOG)
446 return SR_ERR_ARG;
49224c28 447 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
448 *data = g_variant_new_double(ag->amplitude);
449 break;
7dfcf010 450 default:
bd6fbf62 451 return SR_ERR_NA;
6239c175
UH
452 }
453
dfb0fa1a 454 return SR_OK;
6239c175
UH
455}
456
584560f1 457static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 458 const struct sr_channel_group *cg)
6239c175 459{
8b2d41ed 460 struct dev_context *devc;
4374219b 461 struct analog_gen *ag;
ba7dd8bb 462 struct sr_channel *ch;
49224c28
BV
463 GSList *l;
464 int logic_pattern, analog_pattern, ret;
61c39f54 465 unsigned int i;
1b79df2f 466 const char *stropt;
6239c175 467
8b2d41ed 468 devc = sdi->priv;
6239c175 469
e73ffd42
BV
470 if (sdi->status != SR_ST_ACTIVE)
471 return SR_ERR_DEV_CLOSED;
472
2388ae86 473 ret = SR_OK;
584560f1 474 switch (key) {
2388ae86 475 case SR_CONF_SAMPLERATE:
a7684294 476 devc->cur_samplerate = g_variant_get_uint64(data);
2388ae86
BV
477 break;
478 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
479 devc->limit_msec = 0;
480 devc->limit_samples = g_variant_get_uint64(data);
2388ae86
BV
481 break;
482 case SR_CONF_LIMIT_MSEC:
a7684294
JH
483 devc->limit_msec = g_variant_get_uint64(data);
484 devc->limit_samples = 0;
2388ae86 485 break;
7a8a1aba
BG
486 case SR_CONF_AVERAGING:
487 devc->avg = g_variant_get_boolean(data);
488 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
489 break;
490 case SR_CONF_AVG_SAMPLES:
491 devc->avg_samples = g_variant_get_uint64(data);
492 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
493 break;
2388ae86 494 case SR_CONF_PATTERN_MODE:
53b4680f 495 if (!cg)
660e398f 496 return SR_ERR_CHANNEL_GROUP;
d00088ca 497 stropt = g_variant_get_string(data, NULL);
49224c28
BV
498 logic_pattern = analog_pattern = -1;
499 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
500 if (!strcmp(stropt, logic_pattern_str[i])) {
501 logic_pattern = i;
502 break;
8b2d41ed 503 }
49224c28
BV
504 }
505 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
506 if (!strcmp(stropt, analog_pattern_str[i])) {
507 analog_pattern = i;
508 break;
8b2d41ed 509 }
49224c28
BV
510 }
511 if (logic_pattern == -1 && analog_pattern == -1)
512 return SR_ERR_ARG;
513 for (l = cg->channels; l; l = l->next) {
514 ch = l->data;
515 if (ch->type == SR_CHANNEL_LOGIC) {
516 if (logic_pattern == -1)
517 return SR_ERR_ARG;
518 sr_dbg("Setting logic pattern to %s",
519 logic_pattern_str[logic_pattern]);
520 devc->logic_pattern = logic_pattern;
521 /* Might as well do this now, these are static. */
522 if (logic_pattern == PATTERN_ALL_LOW)
523 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
524 else if (logic_pattern == PATTERN_ALL_HIGH)
525 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
526 } else if (ch->type == SR_CHANNEL_ANALOG) {
527 if (analog_pattern == -1)
528 return SR_ERR_ARG;
529 sr_dbg("Setting analog pattern for channel %s to %s",
530 ch->name, analog_pattern_str[analog_pattern]);
531 ag = g_hash_table_lookup(devc->ch_ag, ch);
532 ag->pattern = analog_pattern;
533 } else
534 return SR_ERR_BUG;
535 }
2388ae86 536 break;
dddabe37
BV
537 case SR_CONF_AMPLITUDE:
538 if (!cg)
539 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
540 for (l = cg->channels; l; l = l->next) {
541 ch = l->data;
542 if (ch->type != SR_CHANNEL_ANALOG)
543 return SR_ERR_ARG;
544 ag = g_hash_table_lookup(devc->ch_ag, ch);
545 ag->amplitude = g_variant_get_double(data);
546 }
dddabe37 547 break;
2388ae86 548 default:
bd6fbf62 549 ret = SR_ERR_NA;
6239c175
UH
550 }
551
552 return ret;
553}
554
584560f1 555static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 556 const struct sr_channel_group *cg)
a1c743fc 557{
ba7dd8bb 558 struct sr_channel *ch;
d00088ca
BV
559 GVariant *gvar;
560 GVariantBuilder gvb;
a1c743fc 561
7a1da331 562 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1
BV
563 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
564 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
7a1da331
BV
565 return SR_OK;
566 }
567
390795c0
BV
568 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
569 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 570 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
390795c0
BV
571 return SR_OK;
572 }
573
7a1da331
BV
574 if (!sdi)
575 return SR_ERR_ARG;
576
53b4680f 577 if (!cg) {
7a1da331
BV
578 switch (key) {
579 case SR_CONF_DEVICE_OPTIONS:
584560f1 580 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
1e4a7cac 581 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
7a1da331
BV
582 break;
583 case SR_CONF_SAMPLERATE:
584 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
585 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
586 ARRAY_SIZE(samplerates), sizeof(uint64_t));
587 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
588 *data = g_variant_builder_end(&gvb);
589 break;
590 default:
591 return SR_ERR_NA;
592 }
593 } else {
ba7dd8bb 594 ch = cg->channels->data;
7a1da331
BV
595 switch (key) {
596 case SR_CONF_DEVICE_OPTIONS:
49224c28 597 if (ch->type == SR_CHANNEL_LOGIC)
8249889d 598 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
49224c28 599 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
584560f1 600 sizeof(uint32_t));
e2b99f04
SA
601 else if (ch->type == SR_CHANNEL_ANALOG) {
602 if (strcmp(cg->name, "Analog") == 0)
603 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
604 devopts_cg_analog_group, ARRAY_SIZE(devopts_cg_analog_group),
605 sizeof(uint32_t));
606 else
607 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
608 devopts_cg_analog_channel, ARRAY_SIZE(devopts_cg_analog_channel),
609 sizeof(uint32_t));
610 }
49224c28
BV
611 else
612 return SR_ERR_BUG;
7a1da331
BV
613 break;
614 case SR_CONF_PATTERN_MODE:
e2b99f04
SA
615 /* The analog group (with all 4 channels) shall not have a pattern property. */
616 if (strcmp(cg->name, "Analog") == 0)
617 return SR_ERR_NA;
618
3f239f08 619 if (ch->type == SR_CHANNEL_LOGIC)
7a1da331
BV
620 *data = g_variant_new_strv(logic_pattern_str,
621 ARRAY_SIZE(logic_pattern_str));
3f239f08 622 else if (ch->type == SR_CHANNEL_ANALOG)
7a1da331
BV
623 *data = g_variant_new_strv(analog_pattern_str,
624 ARRAY_SIZE(analog_pattern_str));
2388ae86
BV
625 else
626 return SR_ERR_BUG;
7a1da331
BV
627 break;
628 default:
629 return SR_ERR_NA;
630 }
a1c743fc
BV
631 }
632
633 return SR_OK;
634}
635
c07f60e7 636static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
85b5af06 637{
61c39f54 638 struct dev_context *devc;
c07f60e7
BV
639 uint64_t i, j;
640 uint8_t pat;
85b5af06 641
61c39f54 642 devc = sdi->priv;
85b5af06 643
c07f60e7 644 switch (devc->logic_pattern) {
61c39f54 645 case PATTERN_SIGROK:
c07f60e7
BV
646 memset(devc->logic_data, 0x00, size);
647 for (i = 0; i < size; i += devc->logic_unitsize) {
648 for (j = 0; j < devc->logic_unitsize; j++) {
649 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
650 devc->logic_data[i + j] = ~pat;
651 }
652 devc->step++;
917e0e71
BV
653 }
654 break;
61c39f54 655 case PATTERN_RANDOM:
5096c6a6 656 for (i = 0; i < size; i++)
61c39f54 657 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
85b5af06 658 break;
61c39f54 659 case PATTERN_INC:
c07f60e7
BV
660 for (i = 0; i < size; i++) {
661 for (j = 0; j < devc->logic_unitsize; j++) {
662 devc->logic_data[i + j] = devc->step;
663 }
664 devc->step++;
665 }
c03ed397 666 break;
61c39f54
BV
667 case PATTERN_ALL_LOW:
668 case PATTERN_ALL_HIGH:
669 /* These were set when the pattern mode was selected. */
c03ed397
UH
670 break;
671 default:
c07f60e7 672 sr_err("Unknown pattern: %d.", devc->logic_pattern);
c03ed397 673 break;
85b5af06
UH
674 }
675}
676
7a8a1aba
BG
677static void send_analog_packet(struct analog_gen *ag,
678 struct sr_dev_inst *sdi,
679 uint64_t *analog_sent,
a49a320d 680 uint64_t analog_pos,
7a8a1aba
BG
681 uint64_t analog_todo)
682{
683 struct sr_datafeed_packet packet;
684 struct dev_context *devc;
685 uint64_t sending_now, to_avg;
686 int ag_pattern_pos;
687 unsigned int i;
688
689 devc = sdi->priv;
5faebab2 690 packet.type = SR_DF_ANALOG_OLD;
7a8a1aba
BG
691 packet.payload = &ag->packet;
692
693 if (!devc->avg) {
a49a320d 694 ag_pattern_pos = analog_pos % ag->num_samples;
7a8a1aba
BG
695 sending_now = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
696 ag->packet.data = ag->pattern_data + ag_pattern_pos;
697 ag->packet.num_samples = sending_now;
698 sr_session_send(sdi, &packet);
699
700 /* Whichever channel group gets there first. */
701 *analog_sent = MAX(*analog_sent, sending_now);
702 } else {
a49a320d 703 ag_pattern_pos = analog_pos % ag->num_samples;
7a8a1aba
BG
704 to_avg = MIN(analog_todo, ag->num_samples-ag_pattern_pos);
705
706 for (i = 0; i < to_avg; i++) {
707 ag->avg_val = (ag->avg_val +
708 *(ag->pattern_data +
709 ag_pattern_pos + i)) / 2;
710 ag->num_avgs++;
711 /* Time to send averaged data? */
712 if (devc->avg_samples > 0 &&
713 ag->num_avgs >= devc->avg_samples)
714 goto do_send;
715 }
716
717 if (devc->avg_samples == 0) {
718 /* We're averaging all the samples, so wait with
719 * sending until the very end.
720 */
721 *analog_sent = ag->num_avgs;
722 return;
723 }
724
725do_send:
726 ag->packet.data = &ag->avg_val;
727 ag->packet.num_samples = 1;
728
729 sr_session_send(sdi, &packet);
730 *analog_sent = ag->num_avgs;
731
732 ag->num_avgs = 0;
733 ag->avg_val = 0.0f;
734 }
735}
736
85b5af06 737/* Callback handling data */
61c39f54 738static int prepare_data(int fd, int revents, void *cb_data)
85b5af06 739{
61c39f54
BV
740 struct sr_dev_inst *sdi;
741 struct dev_context *devc;
b9c735a2 742 struct sr_datafeed_packet packet;
9c939c51 743 struct sr_datafeed_logic logic;
8b2d41ed 744 struct analog_gen *ag;
49224c28
BV
745 GHashTableIter iter;
746 void *value;
a49a320d
DE
747 uint64_t samples_todo, logic_done, analog_done, analog_sent, sending_now;
748 int64_t elapsed_us, limit_us, todo_us;
1924f59f 749
cb93f8a9
UH
750 (void)fd;
751 (void)revents;
1924f59f 752
61c39f54
BV
753 sdi = cb_data;
754 devc = sdi->priv;
755
a49a320d
DE
756 /* Just in case. */
757 if (devc->cur_samplerate <= 0 || devc->logic_unitsize <= 0
758 || (devc->num_logic_channels <= 0
759 && devc->num_analog_channels <= 0)) {
760 dev_acquisition_stop(sdi, sdi);
761 return G_SOURCE_CONTINUE;
762 }
7f4975b4 763
a49a320d
DE
764 /* What time span should we send samples for? */
765 elapsed_us = g_get_monotonic_time() - devc->start_us;
766 limit_us = 1000 * devc->limit_msec;
767 if (limit_us > 0 && limit_us < elapsed_us)
768 todo_us = MAX(0, limit_us - devc->spent_us);
769 else
770 todo_us = MAX(0, elapsed_us - devc->spent_us);
771
772 /* How many samples are outstanding since the last round? */
36cbd69e 773 samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
a49a320d
DE
774 / G_USEC_PER_SEC;
775 if (devc->limit_samples > 0) {
776 if (devc->limit_samples < devc->sent_samples)
777 samples_todo = 0;
778 else if (devc->limit_samples - devc->sent_samples < samples_todo)
779 samples_todo = devc->limit_samples - devc->sent_samples;
780 }
781 /* Calculate the actual time covered by this run back from the sample
782 * count, rounded towards zero. This avoids getting stuck on a too-low
783 * time delta with no samples being sent due to round-off.
784 */
785 todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
b62bb97a 786
9dfacd87
AJ
787 logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
788 analog_done = devc->num_analog_channels > 0 ? 0 : samples_todo;
85b5af06 789
a49a320d 790 while (logic_done < samples_todo || analog_done < samples_todo) {
c07f60e7 791 /* Logic */
a49a320d
DE
792 if (logic_done < samples_todo) {
793 sending_now = MIN(samples_todo - logic_done,
794 LOGIC_BUFSIZE / devc->logic_unitsize);
8b2d41ed
BV
795 logic_generator(sdi, sending_now * devc->logic_unitsize);
796 packet.type = SR_DF_LOGIC;
797 packet.payload = &logic;
798 logic.length = sending_now * devc->logic_unitsize;
799 logic.unitsize = devc->logic_unitsize;
800 logic.data = devc->logic_data;
801 sr_session_send(sdi, &packet);
a49a320d 802 logic_done += sending_now;
8b2d41ed
BV
803 }
804
ba7dd8bb 805 /* Analog, one channel at a time */
a49a320d 806 if (analog_done < samples_todo) {
b62bb97a 807 analog_sent = 0;
49224c28
BV
808
809 g_hash_table_iter_init(&iter, devc->ch_ag);
810 while (g_hash_table_iter_next(&iter, NULL, &value)) {
a49a320d
DE
811 send_analog_packet(value, sdi, &analog_sent,
812 devc->sent_samples + analog_done,
813 samples_todo - analog_done);
8b2d41ed 814 }
a49a320d 815 analog_done += analog_sent;
8b2d41ed 816 }
3b203673 817 }
a49a320d
DE
818 /* At this point, both logic_done and analog_done should be
819 * exactly equal to samples_todo, or else.
820 */
821 if (logic_done != samples_todo || analog_done != samples_todo) {
822 sr_err("BUG: Sample count mismatch.");
823 return G_SOURCE_REMOVE;
824 }
825 devc->sent_samples += samples_todo;
826 devc->spent_us += todo_us;
827
828 if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
829 || (limit_us > 0 && devc->spent_us >= limit_us)) {
3b203673 830
7a8a1aba
BG
831 /* If we're averaging everything - now is the time to send data */
832 if (devc->avg_samples == 0) {
833 g_hash_table_iter_init(&iter, devc->ch_ag);
834 while (g_hash_table_iter_next(&iter, NULL, &value)) {
835 ag = value;
5faebab2 836 packet.type = SR_DF_ANALOG_OLD;
7a8a1aba
BG
837 packet.payload = &ag->packet;
838 ag->packet.data = &ag->avg_val;
839 ag->packet.num_samples = 1;
840 sr_session_send(sdi, &packet);
841 }
842 }
7f4975b4 843 sr_dbg("Requested number of samples reached.");
a49a320d 844 dev_acquisition_stop(sdi, sdi);
85b5af06 845 }
1924f59f 846
a49a320d 847 return G_SOURCE_CONTINUE;
85b5af06
UH
848}
849
6078d2c9 850static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
6239c175 851{
61c39f54 852 struct dev_context *devc;
49224c28
BV
853 GHashTableIter iter;
854 void *value;
85b5af06 855
102f1239
BV
856 (void)cb_data;
857
e73ffd42
BV
858 if (sdi->status != SR_ST_ACTIVE)
859 return SR_ERR_DEV_CLOSED;
860
61c39f54 861 devc = sdi->priv;
a49a320d 862 devc->sent_samples = 0;
85b5af06 863
49224c28
BV
864 g_hash_table_iter_init(&iter, devc->ch_ag);
865 while (g_hash_table_iter_next(&iter, NULL, &value))
866 generate_analog_pattern(value, devc->cur_samplerate);
4374219b 867
98c01fe1
DE
868 sr_session_source_add(sdi->session, -1, 0, 100,
869 prepare_data, (struct sr_dev_inst *)sdi);
85b5af06 870
102f1239 871 std_session_send_df_header(sdi, LOG_PREFIX);
f366e86c 872
3b203673 873 /* We use this timestamp to decide how many more samples to send. */
a49a320d
DE
874 devc->start_us = g_get_monotonic_time();
875 devc->spent_us = 0;
3b203673 876
e46b8fb1 877 return SR_OK;
6239c175
UH
878}
879
6078d2c9 880static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 881{
33ef7573 882 (void)cb_data;
7fd3e859 883
a84f6ad3 884 sr_dbg("Stopping acquisition.");
027bf077 885 sr_session_source_remove(sdi->session, -1);
3be42bc2 886 std_session_send_df_end(sdi, LOG_PREFIX);
7fd3e859 887
3010f21c 888 return SR_OK;
6239c175
UH
889}
890
c09f0b57 891SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
892 .name = "demo",
893 .longname = "Demo driver and pattern generator",
894 .api_version = 1,
6078d2c9
UH
895 .init = init,
896 .cleanup = cleanup,
897 .scan = scan,
898 .dev_list = dev_list,
a6630742 899 .dev_clear = NULL,
035a1078
BV
900 .config_get = config_get,
901 .config_set = config_set,
a1c743fc 902 .config_list = config_list,
6078d2c9
UH
903 .dev_open = dev_open,
904 .dev_close = dev_close,
905 .dev_acquisition_start = dev_acquisition_start,
906 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 907 .context = NULL,
6239c175 908};