2 * This file is part of the libsigrok project.
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
6 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
31 #include "libsigrok.h"
32 #include "libsigrok-internal.h"
34 /* Message logging helpers with subsystem-specific prefix string. */
35 #define LOG_PREFIX "demo: "
36 #define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
37 #define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
38 #define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
39 #define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
40 #define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
41 #define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
43 /* TODO: Number of probes should be configurable. */
46 /* The size of chunks to send through the session bus. */
47 /* TODO: Should be configurable. */
48 #define LOGIC_BUFSIZE 4096
50 /* Patterns we can generate */
53 * Spells "sigrok" across 8 probes using '0's (with '1's as
54 * "background") when displayed using the 'bits' output format.
58 /** Pseudo-)random values on all probes. */
62 * Incrementing number across all probes.
66 /** All probes have a low logic state. */
69 /** All probes have a high logic state. */
73 static const char *pattern_strings[] = {
81 /* Private, per-device-instance driver context. */
85 uint64_t cur_samplerate;
86 uint64_t limit_samples;
88 uint8_t sample_generator;
89 uint64_t samples_counter;
92 unsigned char logic_data[LOGIC_BUFSIZE];
96 static const int hwcaps[] = {
97 SR_CONF_LOGIC_ANALYZER,
100 SR_CONF_PATTERN_MODE,
101 SR_CONF_LIMIT_SAMPLES,
106 static const uint64_t samplerates[] = {
112 static uint8_t pattern_sigrok[] = {
113 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
114 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
115 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
116 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
117 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
118 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 /* Private, per-device-instance driver context. */
124 /* TODO: struct context as with the other drivers. */
126 /* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
127 SR_PRIV struct sr_dev_driver demo_driver_info;
128 static struct sr_dev_driver *di = &demo_driver_info;
130 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
132 static int dev_clear(void)
134 return std_dev_clear(di, NULL);
137 static int init(struct sr_context *sr_ctx)
139 return std_init(sr_ctx, di, LOG_PREFIX);
142 static GSList *scan(GSList *options)
144 struct sr_dev_inst *sdi;
145 struct sr_probe *probe;
146 struct drv_context *drvc;
147 struct dev_context *devc;
158 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
160 sr_err("Device instance creation failed.");
165 for (i = 0; i < NUM_PROBES; i++) {
166 sprintf(probe_name, "D%d", i);
167 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
169 sdi->probes = g_slist_append(sdi->probes, probe);
172 devices = g_slist_append(devices, sdi);
173 drvc->instances = g_slist_append(drvc->instances, sdi);
175 if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
176 sr_err("Device context malloc failed.");
180 devc->cur_samplerate = SR_KHZ(200);
181 devc->limit_samples = 0;
182 devc->limit_msec = 0;
183 devc->sample_generator = PATTERN_SIGROK;
191 static GSList *dev_list(void)
193 return ((struct drv_context *)(di->priv))->instances;
196 static int dev_open(struct sr_dev_inst *sdi)
198 sdi->status = SR_ST_ACTIVE;
203 static int dev_close(struct sr_dev_inst *sdi)
205 sdi->status = SR_ST_INACTIVE;
210 static int cleanup(void)
215 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
216 const struct sr_probe_group *probe_group)
218 struct dev_context *const devc = sdi->priv;
223 case SR_CONF_SAMPLERATE:
224 *data = g_variant_new_uint64(devc->cur_samplerate);
226 case SR_CONF_LIMIT_SAMPLES:
227 *data = g_variant_new_uint64(devc->limit_samples);
229 case SR_CONF_LIMIT_MSEC:
230 *data = g_variant_new_uint64(devc->limit_msec);
232 case SR_CONF_PATTERN_MODE:
233 *data = g_variant_new_string(pattern_strings[devc->sample_generator]);
242 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
243 const struct sr_probe_group *probe_group)
250 struct dev_context *const devc = sdi->priv;
252 if (sdi->status != SR_ST_ACTIVE)
253 return SR_ERR_DEV_CLOSED;
255 if (id == SR_CONF_SAMPLERATE) {
256 devc->cur_samplerate = g_variant_get_uint64(data);
257 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
259 } else if (id == SR_CONF_LIMIT_SAMPLES) {
260 devc->limit_msec = 0;
261 devc->limit_samples = g_variant_get_uint64(data);
262 sr_dbg("Setting limit_samples to %" PRIu64, devc->limit_samples);
264 } else if (id == SR_CONF_LIMIT_MSEC) {
265 devc->limit_msec = g_variant_get_uint64(data);
266 devc->limit_samples = 0;
267 sr_dbg("Setting limit_msec to %" PRIu64, devc->limit_msec);
269 } else if (id == SR_CONF_PATTERN_MODE) {
270 stropt = g_variant_get_string(data, NULL);
272 for (i = 0; i < ARRAY_SIZE(pattern_strings); i++) {
273 if (!strcmp(stropt, pattern_strings[i])) {
274 devc->sample_generator = i;
279 /* Might as well do this now. */
280 if (i == PATTERN_ALL_LOW)
281 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
282 else if (i == PATTERN_ALL_HIGH)
283 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
284 sr_dbg("Setting pattern to %s", pattern_strings[i]);
292 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
293 const struct sr_probe_group *probe_group)
302 case SR_CONF_DEVICE_OPTIONS:
303 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
304 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
306 case SR_CONF_SAMPLERATE:
307 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
308 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
309 ARRAY_SIZE(samplerates), sizeof(uint64_t));
310 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
311 *data = g_variant_builder_end(&gvb);
313 case SR_CONF_PATTERN_MODE:
314 *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
323 static void sample_generator(struct sr_dev_inst *sdi, uint64_t size)
325 struct dev_context *devc;
330 switch (devc->sample_generator) {
332 for (i = 0; i < size; i++) {
333 devc->logic_data[i] = ~(pattern_sigrok[
334 devc->step++ % sizeof(pattern_sigrok)] >> 1);
338 for (i = 0; i < size; i++)
339 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
342 for (i = 0; i < size; i++)
343 devc->logic_data[i] = devc->step++;
345 case PATTERN_ALL_LOW:
346 case PATTERN_ALL_HIGH:
347 /* These were set when the pattern mode was selected. */
350 sr_err("Unknown pattern: %d.", devc->sample_generator);
355 /* Callback handling data */
356 static int prepare_data(int fd, int revents, void *cb_data)
358 struct sr_dev_inst *sdi;
359 struct dev_context *devc;
360 struct sr_datafeed_packet packet;
361 struct sr_datafeed_logic logic;
362 static uint64_t samples_to_send, expected_samplenum, sending_now;
363 int64_t time, elapsed;
371 /* How many "virtual" samples should we have collected by now? */
372 time = g_get_monotonic_time();
373 elapsed = time - devc->starttime;
374 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
375 /* Of those, how many do we still have to send? */
376 samples_to_send = expected_samplenum - devc->samples_counter;
378 if (devc->limit_samples) {
379 samples_to_send = MIN(samples_to_send,
380 devc->limit_samples - devc->samples_counter);
383 while (samples_to_send > 0) {
384 sending_now = MIN(samples_to_send, LOGIC_BUFSIZE);
385 samples_to_send -= sending_now;
386 sample_generator(sdi, sending_now);
388 packet.type = SR_DF_LOGIC;
389 packet.payload = &logic;
390 logic.length = sending_now;
392 logic.data = devc->logic_data;
393 sr_session_send(devc->cb_data, &packet);
394 devc->samples_counter += sending_now;
397 if (devc->limit_samples &&
398 devc->samples_counter >= devc->limit_samples) {
399 sr_info("Requested number of samples reached.");
400 dev_acquisition_stop(sdi, cb_data);
407 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
409 struct dev_context *devc;
411 if (sdi->status != SR_ST_ACTIVE)
412 return SR_ERR_DEV_CLOSED;
415 devc->cb_data = cb_data;
416 devc->samples_counter = 0;
419 * Setting two channels connected by a pipe is a remnant from when the
420 * demo driver generated data in a thread, and collected and sent the
421 * data in the main program loop.
422 * They are kept here because it provides a convenient way of setting
423 * up a timeout-based polling mechanism.
425 if (pipe(devc->pipe_fds)) {
426 sr_err("%s: pipe() failed", __func__);
430 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
432 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
434 /* Set channel encoding to binary (default is UTF-8). */
435 g_io_channel_set_encoding(devc->channel, NULL, NULL);
437 /* Make channels to unbuffered. */
438 g_io_channel_set_buffered(devc->channel, FALSE);
440 sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
441 40, prepare_data, (void *)sdi);
443 /* Send header packet to the session bus. */
444 std_session_send_df_header(cb_data, LOG_PREFIX);
446 /* We use this timestamp to decide how many more samples to send. */
447 devc->starttime = g_get_monotonic_time();
452 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
454 struct dev_context *const devc = sdi->priv;
455 struct sr_datafeed_packet packet;
459 sr_dbg("Stopping aquisition.");
461 sr_session_source_remove_channel(devc->channel);
462 g_io_channel_shutdown(devc->channel, FALSE, NULL);
463 g_io_channel_unref(devc->channel);
464 devc->channel = NULL;
466 /* Send last packet. */
467 packet.type = SR_DF_END;
468 sr_session_send(devc->cb_data, &packet);
473 SR_PRIV struct sr_dev_driver demo_driver_info = {
475 .longname = "Demo driver and pattern generator",
480 .dev_list = dev_list,
481 .dev_clear = dev_clear,
482 .config_get = config_get,
483 .config_set = config_set,
484 .config_list = config_list,
485 .dev_open = dev_open,
486 .dev_close = dev_close,
487 .dev_acquisition_start = dev_acquisition_start,
488 .dev_acquisition_stop = dev_acquisition_stop,