*
* Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
+ * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "libsigrok.h"
#include "libsigrok-internal.h"
+/* Message logging helpers with driver-specific prefix string. */
+#define DRIVER_LOG_DOMAIN "demo: "
+#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args)
+#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args)
+#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args)
+#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args)
+#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args)
+#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
+
/* TODO: Number of probes should be configurable. */
#define NUM_PROBES 8
PATTERN_ALL_HIGH,
};
-/* FIXME: Should not be global. */
-
-/* Private driver context. */
-struct drv_context {
- GSList *instances;
-};
-
/* Private, per-device-instance driver context. */
struct dev_context {
int pipe_fds[2];
static GThread *my_thread;
static int thread_running;
-static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi,
- void *cb_data);
+static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
static int hw_init(void)
{
struct drv_context *drvc;
if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
- sr_err("fx2lafw: driver context malloc failed.");
- return SR_ERR;
+ sr_err("Driver context malloc failed.");
+ return SR_ERR_MALLOC;
}
ddi->priv = drvc;
int i;
(void)options;
+
drvc = ddi->priv;
devices = NULL;
sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
if (!sdi) {
- sr_err("demo: %s: sr_dev_inst_new failed", __func__);
+ sr_err("%s: sr_dev_inst_new failed", __func__);
return 0;
}
sdi->driver = ddi;
for (i = 0; probe_names[i]; i++) {
- if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
+ if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
probe_names[i])))
return NULL;
sdi->probes = g_slist_append(sdi->probes, probe);
return devices;
}
+static GSList *hw_dev_list(void)
+{
+ struct drv_context *drvc;
+
+ drvc = ddi->priv;
+
+ return drvc->instances;
+}
+
static int hw_dev_open(struct sr_dev_inst *sdi)
{
- /* Avoid compiler warnings. */
(void)sdi;
/* Nothing needed so far. */
static int hw_dev_close(struct sr_dev_inst *sdi)
{
- /* Avoid compiler warnings. */
(void)sdi;
/* Nothing needed so far. */
static int hw_info_get(int info_id, const void **data,
const struct sr_dev_inst *sdi)
{
-
(void)sdi;
switch (info_id) {
(void)sdi;
- if (hwcap == SR_HWCAP_PROBECONFIG) {
- /* Nothing to do, but must be supported */
- ret = SR_OK;
- } else if (hwcap == SR_HWCAP_SAMPLERATE) {
+ if (hwcap == SR_HWCAP_SAMPLERATE) {
cur_samplerate = *(const uint64_t *)value;
- sr_dbg("demo: %s: setting samplerate to %" PRIu64, __func__,
+ sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
cur_samplerate);
ret = SR_OK;
} else if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
limit_msec = 0;
limit_samples = *(const uint64_t *)value;
- sr_dbg("demo: %s: setting limit_samples to %" PRIu64, __func__,
+ sr_dbg("%s: setting limit_samples to %" PRIu64, __func__,
limit_samples);
ret = SR_OK;
} else if (hwcap == SR_HWCAP_LIMIT_MSEC) {
limit_msec = *(const uint64_t *)value;
limit_samples = 0;
- sr_dbg("demo: %s: setting limit_msec to %" PRIu64, __func__,
+ sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
limit_msec);
ret = SR_OK;
} else if (hwcap == SR_HWCAP_PATTERN_MODE) {
} else {
ret = SR_ERR;
}
- sr_dbg("demo: %s: setting pattern to %d", __func__,
- default_pattern);
+ sr_dbg("%s: setting pattern to %d", __func__, default_pattern);
} else {
ret = SR_ERR;
}
memset(buf, 0xff, size);
break;
default:
- sr_err("demo: %s: unknown pattern %d", __func__,
- devc->sample_generator);
+ sr_err("Unknown pattern: %d.", devc->sample_generator);
break;
}
}
unsigned char c[BUFSIZE];
gsize z;
- /* Avoid compiler warnings. */
(void)fd;
(void)revents;
if (!thread_running && z <= 0) {
/* Make sure we don't receive more packets. */
- g_io_channel_shutdown(devc->channels[0], FALSE, NULL);
-
- /* Send last packet. */
- packet.type = SR_DF_END;
- sr_session_send(devc->session_dev_id, &packet);
-
- return FALSE;
+ hw_dev_acquisition_stop(NULL, cb_data);
+ return TRUE;
}
return TRUE;
(void)sdi;
+ sr_dbg("Starting acquisition.");
+
/* TODO: 'devc' is never g_free()'d? */
if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
- sr_err("demo: %s: devc malloc failed", __func__);
+ sr_err("%s: devc malloc failed", __func__);
return SR_ERR_MALLOC;
}
if (pipe(devc->pipe_fds)) {
/* TODO: Better error message. */
- sr_err("demo: %s: pipe() failed", __func__);
+ sr_err("%s: pipe() failed", __func__);
return SR_ERR;
}
40, receive_data, devc);
/* Run the demo thread. */
- g_thread_init(NULL);
- /* This must to be done between g_thread_init() & g_thread_create(). */
devc->timer = g_timer_new();
thread_running = 1;
- my_thread =
- g_thread_create((GThreadFunc)thread_func, devc, TRUE, NULL);
+ my_thread = g_thread_try_new("sigrok demo generator",
+ (GThreadFunc)thread_func, devc, NULL);
if (!my_thread) {
- sr_err("demo: %s: g_thread_create failed", __func__);
+ sr_err("%s: g_thread_try_new failed", __func__);
return SR_ERR; /* TODO */
}
if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
- sr_err("demo: %s: packet malloc failed", __func__);
+ sr_err("%s: packet malloc failed", __func__);
return SR_ERR_MALLOC;
}
if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
- sr_err("demo: %s: header malloc failed", __func__);
+ sr_err("%s: header malloc failed", __func__);
return SR_ERR_MALLOC;
}
return SR_OK;
}
-static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi,
- void *cb_data)
+static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
{
struct dev_context *devc;
+ struct sr_datafeed_packet packet;
- /* Avoid compiler warnings. */
- (void)cb_data;
+ (void)sdi;
+
+ devc = cb_data;
- devc = sdi->priv;
+ sr_dbg("Stopping aquisition.");
/* Stop generate thread. */
thread_running = 0;
sr_session_source_remove_channel(devc->channels[0]);
+ g_io_channel_shutdown(devc->channels[0], FALSE, NULL);
+
+ /* Send last packet. */
+ packet.type = SR_DF_END;
+ sr_session_send(devc->session_dev_id, &packet);
return SR_OK;
}
.init = hw_init,
.cleanup = hw_cleanup,
.scan = hw_scan,
+ .dev_list = hw_dev_list,
.dev_open = hw_dev_open,
.dev_close = hw_dev_close,
.info_get = hw_info_get,