]> sigrok.org Git - libsigrok.git/blame - src/hardware/demo/api.c
demo: Port trigger configuration from fx2lafw.
[libsigrok.git] / src / hardware / demo / api.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
2ea1fdf1 20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6239c175
UH
21 */
22
6ec6c43b 23#include <config.h>
6239c175
UH
24#include <stdlib.h>
25#include <string.h>
4374219b 26#include <math.h>
c1aae900 27#include <libsigrok/libsigrok.h>
45c59c8b 28#include "libsigrok-internal.h"
ba508e22 29#include "protocol.h"
92bcedf6 30
7db90279 31#define DEFAULT_NUM_LOGIC_CHANNELS 8
b1e6eec6 32#define DEFAULT_LOGIC_PATTERN PATTERN_SIGROK
c03ed397 33
b1e6eec6 34#define DEFAULT_NUM_ANALOG_CHANNELS 4
d9251a2c 35#define DEFAULT_ANALOG_AMPLITUDE 10
85b5af06 36
77463bd3 37/* Note: No spaces allowed because of sigrok-cli. */
8b2d41ed 38static const char *logic_pattern_str[] = {
61c39f54
BV
39 "sigrok",
40 "random",
41 "incremental",
77463bd3
SA
42 "walking-one",
43 "walking-zero",
61c39f54
BV
44 "all-low",
45 "all-high",
81d53a29 46 "squid",
03733430 47 "graycode",
61c39f54
BV
48};
49
55fb76b3
UH
50static const uint32_t scanopts[] = {
51 SR_CONF_NUM_LOGIC_CHANNELS,
52 SR_CONF_NUM_ANALOG_CHANNELS,
53ea2461 53 SR_CONF_LIMIT_FRAMES,
55fb76b3
UH
54};
55
1e4a7cac
BV
56static const uint32_t drvopts[] = {
57 SR_CONF_DEMO_DEV,
58 SR_CONF_LOGIC_ANALYZER,
59 SR_CONF_OSCILLOSCOPE,
60};
61
390795c0 62static const uint32_t devopts[] = {
e91bb0a6 63 SR_CONF_CONTINUOUS,
5827f61b
BV
64 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
65 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
fb193945 66 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
390795c0 67 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
7a8a1aba
BG
68 SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET,
69 SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET,
31f69b09 70 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
71 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
390795c0
BV
72};
73
74static const uint32_t devopts_cg_logic[] = {
f12d9979 75 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
49224c28
BV
76};
77
e2b99f04
SA
78static const uint32_t devopts_cg_analog_group[] = {
79 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
80};
81
82static const uint32_t devopts_cg_analog_channel[] = {
f12d9979
BV
83 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
84 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
7a1da331
BV
85};
86
31f69b09 87static const int32_t trigger_matches[] = {
88 SR_TRIGGER_ZERO,
89 SR_TRIGGER_ONE,
90 SR_TRIGGER_RISING,
91 SR_TRIGGER_FALLING,
92 SR_TRIGGER_EDGE,
93};
94
d00088ca
BV
95static const uint64_t samplerates[] = {
96 SR_HZ(1),
97 SR_GHZ(1),
98 SR_HZ(1),
4bfbf9fc
BV
99};
100
4f840ce9 101static GSList *scan(struct sr_dev_driver *di, GSList *options)
6239c175 102{
33ef7573 103 struct dev_context *devc;
c07f60e7 104 struct sr_dev_inst *sdi;
ba7dd8bb 105 struct sr_channel *ch;
49224c28 106 struct sr_channel_group *cg, *acg;
c07f60e7 107 struct sr_config *src;
8b2d41ed 108 struct analog_gen *ag;
43376f33 109 GSList *l;
ba7dd8bb 110 int num_logic_channels, num_analog_channels, pattern, i;
53ea2461 111 uint64_t limit_frames;
ba7dd8bb 112 char channel_name[16];
067d0716 113
3f239f08
UH
114 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
115 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
53ea2461 116 limit_frames = DEFAULT_LIMIT_FRAMES;
c07f60e7
BV
117 for (l = options; l; l = l->next) {
118 src = l->data;
119 switch (src->key) {
3f239f08 120 case SR_CONF_NUM_LOGIC_CHANNELS:
ba7dd8bb 121 num_logic_channels = g_variant_get_int32(src->data);
c07f60e7 122 break;
3f239f08 123 case SR_CONF_NUM_ANALOG_CHANNELS:
ba7dd8bb 124 num_analog_channels = g_variant_get_int32(src->data);
c07f60e7 125 break;
53ea2461
GS
126 case SR_CONF_LIMIT_FRAMES:
127 limit_frames = g_variant_get_uint64(src->data);
128 break;
c07f60e7
BV
129 }
130 }
85b5af06 131
aac29cc1 132 sdi = g_malloc0(sizeof(struct sr_dev_inst));
45884333 133 sdi->status = SR_ST_INACTIVE;
4b664cd6 134 sdi->model = g_strdup("Demo device");
e15f48c2 135
a49a320d 136 devc = g_malloc0(sizeof(struct dev_context));
8b2d41ed 137 devc->cur_samplerate = SR_KHZ(200);
ba7dd8bb
UH
138 devc->num_logic_channels = num_logic_channels;
139 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
015f0970
GS
140 devc->all_logic_channels_mask = 1UL << 0;
141 devc->all_logic_channels_mask <<= devc->num_logic_channels;
142 devc->all_logic_channels_mask--;
b1e6eec6 143 devc->logic_pattern = DEFAULT_LOGIC_PATTERN;
ba7dd8bb 144 devc->num_analog_channels = num_analog_channels;
53ea2461 145 devc->limit_frames = limit_frames;
8b2d41ed 146
f18e0db3
LPC
147 if (num_logic_channels > 0) {
148 /* Logic channels, all in one channel group. */
149 cg = g_malloc0(sizeof(struct sr_channel_group));
150 cg->name = g_strdup("Logic");
151 for (i = 0; i < num_logic_channels; i++) {
152 sprintf(channel_name, "D%d", i);
f1c79a6a 153 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
f18e0db3
LPC
154 cg->channels = g_slist_append(cg->channels, ch);
155 }
156 sdi->channel_groups = g_slist_append(NULL, cg);
87ca93c5
BV
157 }
158
ba7dd8bb 159 /* Analog channels, channel groups and pattern generators. */
d91d0b12 160 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
f18e0db3
LPC
161 if (num_analog_channels > 0) {
162 pattern = 0;
163 /* An "Analog" channel group with all analog channels in it. */
164 acg = g_malloc0(sizeof(struct sr_channel_group));
165 acg->name = g_strdup("Analog");
166 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
167
f18e0db3
LPC
168 for (i = 0; i < num_analog_channels; i++) {
169 snprintf(channel_name, 16, "A%d", i);
170 ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
f1c79a6a 171 TRUE, channel_name);
f18e0db3
LPC
172 acg->channels = g_slist_append(acg->channels, ch);
173
174 /* Every analog channel gets its own channel group as well. */
175 cg = g_malloc0(sizeof(struct sr_channel_group));
176 cg->name = g_strdup(channel_name);
177 cg->channels = g_slist_append(NULL, ch);
178 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
179
180 /* Every channel gets a generator struct. */
181 ag = g_malloc(sizeof(struct analog_gen));
01f2adb0 182 ag->ch = ch;
f18e0db3 183 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
3be044aa 184 sr_analog_init(&ag->packet, &ag->encoding, &ag->meaning, &ag->spec, 2);
4b770103
UH
185 ag->packet.meaning->channels = cg->channels;
186 ag->packet.meaning->mq = 0;
187 ag->packet.meaning->mqflags = 0;
188 ag->packet.meaning->unit = SR_UNIT_VOLT;
f18e0db3
LPC
189 ag->packet.data = ag->pattern_data;
190 ag->pattern = pattern;
191 ag->avg_val = 0.0f;
192 ag->num_avgs = 0;
193 g_hash_table_insert(devc->ch_ag, ch, ag);
194
195 if (++pattern == ARRAY_SIZE(analog_pattern_str))
196 pattern = 0;
197 }
33ef7573 198 }
33ef7573
JH
199
200 sdi->priv = devc;
201
43376f33 202 return std_scan_complete(di, g_slist_append(NULL, sdi));
6239c175
UH
203}
204
3553451f 205static void clear_helper(struct dev_context *devc)
ed0b7fed 206{
49224c28
BV
207 GHashTableIter iter;
208 void *value;
ed0b7fed 209
49224c28
BV
210 /* Analog generators. */
211 g_hash_table_iter_init(&iter, devc->ch_ag);
212 while (g_hash_table_iter_next(&iter, NULL, &value))
213 g_free(value);
214 g_hash_table_unref(devc->ch_ag);
ed0b7fed
BV
215}
216
6ab68731 217static int dev_clear(const struct sr_dev_driver *di)
6239c175 218{
3553451f 219 return std_dev_clear_with_callback(di, (std_dev_clear_callback)clear_helper);
6239c175
UH
220}
221
dd7a72ea
UH
222static int config_get(uint32_t key, GVariant **data,
223 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
6239c175 224{
c07f60e7 225 struct dev_context *devc;
ba7dd8bb 226 struct sr_channel *ch;
2388ae86
BV
227 struct analog_gen *ag;
228 int pattern;
6f57fd96 229
2388ae86
BV
230 if (!sdi)
231 return SR_ERR_ARG;
8f996b89 232
c07f60e7 233 devc = sdi->priv;
584560f1 234 switch (key) {
123e1313 235 case SR_CONF_SAMPLERATE:
a7684294 236 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 237 break;
2474d87e 238 case SR_CONF_LIMIT_SAMPLES:
a7684294 239 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
240 break;
241 case SR_CONF_LIMIT_MSEC:
a7684294 242 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e 243 break;
fb193945
GS
244 case SR_CONF_LIMIT_FRAMES:
245 *data = g_variant_new_uint64(devc->limit_frames);
246 break;
7a8a1aba
BG
247 case SR_CONF_AVERAGING:
248 *data = g_variant_new_boolean(devc->avg);
249 break;
250 case SR_CONF_AVG_SAMPLES:
251 *data = g_variant_new_uint64(devc->avg_samples);
252 break;
2474d87e 253 case SR_CONF_PATTERN_MODE:
53b4680f 254 if (!cg)
660e398f 255 return SR_ERR_CHANNEL_GROUP;
49224c28 256 /* Any channel in the group will do. */
ba7dd8bb 257 ch = cg->channels->data;
3f239f08 258 if (ch->type == SR_CHANNEL_LOGIC) {
2388ae86
BV
259 pattern = devc->logic_pattern;
260 *data = g_variant_new_string(logic_pattern_str[pattern]);
3f239f08 261 } else if (ch->type == SR_CHANNEL_ANALOG) {
49224c28 262 ag = g_hash_table_lookup(devc->ch_ag, ch);
2388ae86
BV
263 pattern = ag->pattern;
264 *data = g_variant_new_string(analog_pattern_str[pattern]);
265 } else
266 return SR_ERR_BUG;
c07f60e7 267 break;
dddabe37
BV
268 case SR_CONF_AMPLITUDE:
269 if (!cg)
270 return SR_ERR_CHANNEL_GROUP;
49224c28 271 /* Any channel in the group will do. */
dddabe37
BV
272 ch = cg->channels->data;
273 if (ch->type != SR_CHANNEL_ANALOG)
274 return SR_ERR_ARG;
49224c28 275 ag = g_hash_table_lookup(devc->ch_ag, ch);
dddabe37
BV
276 *data = g_variant_new_double(ag->amplitude);
277 break;
31f69b09 278 case SR_CONF_CAPTURE_RATIO:
279 *data = g_variant_new_uint64(devc->capture_ratio);
280 break;
7dfcf010 281 default:
bd6fbf62 282 return SR_ERR_NA;
6239c175
UH
283 }
284
dfb0fa1a 285 return SR_OK;
6239c175
UH
286}
287
dd7a72ea
UH
288static int config_set(uint32_t key, GVariant *data,
289 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
6239c175 290{
8b2d41ed 291 struct dev_context *devc;
4374219b 292 struct analog_gen *ag;
ba7dd8bb 293 struct sr_channel *ch;
49224c28 294 GSList *l;
a9010323 295 int logic_pattern, analog_pattern;
6239c175 296
8b2d41ed 297 devc = sdi->priv;
6239c175 298
584560f1 299 switch (key) {
2388ae86 300 case SR_CONF_SAMPLERATE:
a7684294 301 devc->cur_samplerate = g_variant_get_uint64(data);
2388ae86
BV
302 break;
303 case SR_CONF_LIMIT_SAMPLES:
a7684294
JH
304 devc->limit_msec = 0;
305 devc->limit_samples = g_variant_get_uint64(data);
2388ae86
BV
306 break;
307 case SR_CONF_LIMIT_MSEC:
a7684294
JH
308 devc->limit_msec = g_variant_get_uint64(data);
309 devc->limit_samples = 0;
2388ae86 310 break;
fb193945
GS
311 case SR_CONF_LIMIT_FRAMES:
312 devc->limit_frames = g_variant_get_uint64(data);
313 break;
7a8a1aba
BG
314 case SR_CONF_AVERAGING:
315 devc->avg = g_variant_get_boolean(data);
316 sr_dbg("%s averaging", devc->avg ? "Enabling" : "Disabling");
317 break;
318 case SR_CONF_AVG_SAMPLES:
319 devc->avg_samples = g_variant_get_uint64(data);
320 sr_dbg("Setting averaging rate to %" PRIu64, devc->avg_samples);
321 break;
2388ae86 322 case SR_CONF_PATTERN_MODE:
53b4680f 323 if (!cg)
660e398f 324 return SR_ERR_CHANNEL_GROUP;
697fb6dd
UH
325 logic_pattern = std_str_idx(data, ARRAY_AND_SIZE(logic_pattern_str));
326 analog_pattern = std_str_idx(data, ARRAY_AND_SIZE(analog_pattern_str));
327 if (logic_pattern < 0 && analog_pattern < 0)
49224c28
BV
328 return SR_ERR_ARG;
329 for (l = cg->channels; l; l = l->next) {
330 ch = l->data;
331 if (ch->type == SR_CHANNEL_LOGIC) {
332 if (logic_pattern == -1)
333 return SR_ERR_ARG;
334 sr_dbg("Setting logic pattern to %s",
335 logic_pattern_str[logic_pattern]);
336 devc->logic_pattern = logic_pattern;
337 /* Might as well do this now, these are static. */
338 if (logic_pattern == PATTERN_ALL_LOW)
339 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
340 else if (logic_pattern == PATTERN_ALL_HIGH)
341 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
342 } else if (ch->type == SR_CHANNEL_ANALOG) {
343 if (analog_pattern == -1)
344 return SR_ERR_ARG;
345 sr_dbg("Setting analog pattern for channel %s to %s",
346 ch->name, analog_pattern_str[analog_pattern]);
347 ag = g_hash_table_lookup(devc->ch_ag, ch);
348 ag->pattern = analog_pattern;
349 } else
350 return SR_ERR_BUG;
351 }
2388ae86 352 break;
dddabe37
BV
353 case SR_CONF_AMPLITUDE:
354 if (!cg)
355 return SR_ERR_CHANNEL_GROUP;
49224c28
BV
356 for (l = cg->channels; l; l = l->next) {
357 ch = l->data;
358 if (ch->type != SR_CHANNEL_ANALOG)
359 return SR_ERR_ARG;
360 ag = g_hash_table_lookup(devc->ch_ag, ch);
361 ag->amplitude = g_variant_get_double(data);
362 }
dddabe37 363 break;
31f69b09 364 case SR_CONF_CAPTURE_RATIO:
365 devc->capture_ratio = g_variant_get_uint64(data);
366 break;
2388ae86 367 default:
a9010323 368 return SR_ERR_NA;
6239c175
UH
369 }
370
a9010323 371 return SR_OK;
6239c175
UH
372}
373
dd7a72ea
UH
374static int config_list(uint32_t key, GVariant **data,
375 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
a1c743fc 376{
ba7dd8bb 377 struct sr_channel *ch;
a1c743fc 378
53b4680f 379 if (!cg) {
7a1da331 380 switch (key) {
e66d1892 381 case SR_CONF_SCAN_OPTIONS:
7a1da331 382 case SR_CONF_DEVICE_OPTIONS:
e66d1892 383 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
7a1da331 384 case SR_CONF_SAMPLERATE:
53012da6 385 *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
7a1da331 386 break;
31f69b09 387 case SR_CONF_TRIGGER_MATCH:
388 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
389 break;
7a1da331
BV
390 default:
391 return SR_ERR_NA;
392 }
393 } else {
ba7dd8bb 394 ch = cg->channels->data;
7a1da331
BV
395 switch (key) {
396 case SR_CONF_DEVICE_OPTIONS:
49224c28 397 if (ch->type == SR_CHANNEL_LOGIC)
53012da6 398 *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_logic));
e2b99f04
SA
399 else if (ch->type == SR_CHANNEL_ANALOG) {
400 if (strcmp(cg->name, "Analog") == 0)
53012da6 401 *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_analog_group));
e2b99f04 402 else
53012da6 403 *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_analog_channel));
e2b99f04 404 }
49224c28
BV
405 else
406 return SR_ERR_BUG;
7a1da331
BV
407 break;
408 case SR_CONF_PATTERN_MODE:
e2b99f04
SA
409 /* The analog group (with all 4 channels) shall not have a pattern property. */
410 if (strcmp(cg->name, "Analog") == 0)
411 return SR_ERR_NA;
412
3f239f08 413 if (ch->type == SR_CHANNEL_LOGIC)
53012da6 414 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_pattern_str));
3f239f08 415 else if (ch->type == SR_CHANNEL_ANALOG)
53012da6 416 *data = g_variant_new_strv(ARRAY_AND_SIZE(analog_pattern_str));
2388ae86
BV
417 else
418 return SR_ERR_BUG;
7a1da331
BV
419 break;
420 default:
421 return SR_ERR_NA;
422 }
a1c743fc
BV
423 }
424
425 return SR_OK;
426}
427
695dc859 428static int dev_acquisition_start(const struct sr_dev_inst *sdi)
6239c175 429{
61c39f54 430 struct dev_context *devc;
1b7b72d4
GS
431 GSList *l;
432 struct sr_channel *ch;
4a465510
GS
433 int bitpos;
434 uint8_t mask;
49224c28
BV
435 GHashTableIter iter;
436 void *value;
85b5af06 437
61c39f54 438 devc = sdi->priv;
a49a320d 439 devc->sent_samples = 0;
767ca135 440 devc->sent_frame_samples = 0;
85b5af06 441
4a465510
GS
442 /*
443 * Determine the numbers of logic and analog channels that are
444 * involved in the acquisition. Determine an offset and a mask to
445 * remove excess logic data content before datafeed submission.
446 */
1b7b72d4
GS
447 devc->enabled_logic_channels = 0;
448 devc->enabled_analog_channels = 0;
449 for (l = sdi->channels; l; l = l->next) {
450 ch = l->data;
451 if (!ch->enabled)
452 continue;
453 if (ch->type == SR_CHANNEL_ANALOG) {
454 devc->enabled_analog_channels++;
455 continue;
456 }
4a465510 457 if (ch->type != SR_CHANNEL_LOGIC)
1b7b72d4 458 continue;
4a465510
GS
459 /*
460 * TODO: Need we create a channel map here, such that the
461 * session datafeed packets will have a dense representation
462 * of the enabled channels' data? For example store channels
463 * D3 and D5 in bit positions 0 and 1 respectively, when all
464 * other channels are disabled? The current implementation
465 * generates a sparse layout, might provide data for logic
466 * channels that are disabled while it might suppress data
467 * from enabled channels at the same time.
468 */
469 devc->enabled_logic_channels++;
1b7b72d4 470 }
4a465510
GS
471 devc->first_partial_logic_index = devc->enabled_logic_channels / 8;
472 bitpos = devc->enabled_logic_channels % 8;
473 mask = (1 << bitpos) - 1;
474 devc->first_partial_logic_mask = mask;
91057d2f
UH
475 sr_dbg("num logic %zu, partial off %zu, mask 0x%02x.",
476 devc->enabled_logic_channels,
4a465510
GS
477 devc->first_partial_logic_index,
478 devc->first_partial_logic_mask);
479
480 /*
481 * Have the waveform for analog patterns pre-generated. It's
482 * supposed to be periodic, so the generator just needs to
483 * access the prepared sample data (DDS style).
484 */
49224c28
BV
485 g_hash_table_iter_init(&iter, devc->ch_ag);
486 while (g_hash_table_iter_next(&iter, NULL, &value))
ba508e22 487 demo_generate_analog_pattern(value, devc->cur_samplerate);
4374219b 488
98c01fe1 489 sr_session_source_add(sdi->session, -1, 0, 100,
ba508e22 490 demo_prepare_data, (struct sr_dev_inst *)sdi);
85b5af06 491
bee2b016 492 std_session_send_df_header(sdi);
f366e86c 493
fb193945 494 if (devc->limit_frames > 0)
f55bea76
SA
495 std_session_send_frame_begin(sdi);
496
3b203673 497 /* We use this timestamp to decide how many more samples to send. */
a49a320d
DE
498 devc->start_us = g_get_monotonic_time();
499 devc->spent_us = 0;
471ac344 500 devc->step = 0;
3b203673 501
e46b8fb1 502 return SR_OK;
6239c175
UH
503}
504
695dc859 505static int dev_acquisition_stop(struct sr_dev_inst *sdi)
6239c175 506{
fb193945
GS
507 struct dev_context *devc;
508
027bf077 509 sr_session_source_remove(sdi->session, -1);
f55bea76 510
fb193945
GS
511 devc = sdi->priv;
512 if (devc->limit_frames > 0)
f55bea76
SA
513 std_session_send_frame_end(sdi);
514
bee2b016 515 std_session_send_df_end(sdi);
7fd3e859 516
3010f21c 517 return SR_OK;
6239c175
UH
518}
519
dd5c48a6 520static struct sr_dev_driver demo_driver_info = {
e519ba86
UH
521 .name = "demo",
522 .longname = "Demo driver and pattern generator",
523 .api_version = 1,
c2fdcc25 524 .init = std_init,
700d6b64 525 .cleanup = std_cleanup,
6078d2c9 526 .scan = scan,
c01bf34c 527 .dev_list = std_dev_list,
6ab68731 528 .dev_clear = dev_clear,
035a1078
BV
529 .config_get = config_get,
530 .config_set = config_set,
a1c743fc 531 .config_list = config_list,
4d67b9d9
UH
532 .dev_open = std_dummy_dev_open,
533 .dev_close = std_dummy_dev_close,
6078d2c9
UH
534 .dev_acquisition_start = dev_acquisition_start,
535 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 536 .context = NULL,
6239c175 537};
dd5c48a6 538SR_REGISTER_DEV_DRIVER(demo_driver_info);