From b5e4994a82740c4da908c61ff35d56fa04500816 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Thu, 27 Mar 2014 11:04:57 +0100 Subject: [PATCH] Switch multiosc to using libiio Most of the multiosc is now using libiio. However, some parts are still using iio_utils.c (libini.c). Also, the plugin_data_capture() function has not been converted, as I couldn't think of a proper way to switch it to libiio without having conflicts everywhere. Signed-off-by: Paul Cercueil --- Makefile | 2 +- datatypes.h | 40 +-- iio_widget.c | 191 +++++++----- iio_widget.h | 33 +- osc.c | 739 ++++++++++++++++----------------------------- osc.h | 2 + oscplot.c | 474 +++++++++++++++++------------ oscplot.h | 2 +- plugins/fmcomms2.c | 24 +- 9 files changed, 707 insertions(+), 800 deletions(-) diff --git a/Makefile b/Makefile index 7d6446500..504da10d1 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ PKG_CONFIG := env PKG_CONFIG_SYSROOT_DIR="$(SYSROOT)" \ PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config LDFLAGS := $(shell $(PKG_CONFIG) --libs gtk+-2.0 gthread-2.0 gtkdatabox fftw3) \ - $(shell $(SYSROOT)/usr/bin/xml2-config --libs) -lmatio -lz + $(shell $(SYSROOT)/usr/bin/xml2-config --libs) -lmatio -lz -liio CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk+-2.0 gthread-2.0 gtkdatabox fftw3) \ $(shell $(SYSROOT)/usr/bin/xml2-config --cflags) \ diff --git a/datatypes.h b/datatypes.h index 6ab7deb3f..1c2a319cb 100644 --- a/datatypes.h +++ b/datatypes.h @@ -13,7 +13,7 @@ #include #include -#include "iio_utils.h" +#include #define FORCE_UPDATE TRUE #define NORMAL_UPDATE FALSE @@ -39,9 +39,19 @@ typedef struct _transform Transform; typedef struct _tr_list TrList; struct extra_info { - struct _device_list *device_parent; + struct iio_device *dev; gfloat *data_ref; + off_t offset; int shadow_of_enabled; + bool may_be_enabled; +}; + +struct extra_dev_info { + struct iio_buffer *buffer; + unsigned int sample_count; + double adc_freq, lo_freq; + char adc_scale; + GSList *plots_sample_counts; }; struct buffer { @@ -69,30 +79,12 @@ struct _fft_alg_data{ int num_active_channels; }; -struct _device_list { - char *device_name; - struct iio_channel_info *channel_list; - unsigned int num_channels; - unsigned int sample_count; - GSList *plots_sample_counts; - double adc_freq; - double lo_freq; - char adc_scale[10]; - void *settings_dialog_builder; - struct buffer data_buffer; - unsigned int num_active_channels; - unsigned int bytes_per_sample; - unsigned int current_sample; - gfloat **channel_data; - int buffer_fd; -}; - struct _transform { int type_id; - struct iio_channel_info *channel_parent; - struct iio_channel_info *channel_parent2; - struct iio_channel_info *channel_parent3; - struct iio_channel_info *channel_parent4; + struct iio_channel *channel_parent, + *channel_parent2, + *channel_parent3, + *channel_parent4; gfloat **in_data; gfloat *x_axis; gfloat *y_axis; diff --git a/iio_widget.c b/iio_widget.c index e1fb0b139..5916483d9 100644 --- a/iio_widget.c +++ b/iio_widget.c @@ -9,10 +9,10 @@ #include #include #include +#include #include "osc.h" #include "iio_widget.h" -#include "iio_utils.h" void g_builder_connect_signal(GtkBuilder *builder, const gchar *name, const gchar *signal, GCallback callback, gpointer data) @@ -50,14 +50,19 @@ void g_builder_bind_property(GtkBuilder *builder, } -static void iio_widget_init(struct iio_widget *widget, const char *device_name, - const char *attr_name, const char *attr_name_avail, GtkWidget *gtk_widget, void *priv, +static void iio_widget_init(struct iio_widget *widget, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, + const char *attr_name_avail, GtkWidget *gtk_widget, void *priv, void (*update)(struct iio_widget *), void (*save)(struct iio_widget *)) { - if (!gtk_widget) - printf("Missing widget for %s/%s\n", device_name, attr_name); + if (!gtk_widget) { + const char *name = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + printf("Missing widget for %s/%s\n", name, attr_name); + } - widget->device_name = device_name; + widget->dev = dev; + widget->chn = chn; widget->attr_name = attr_name; widget->attr_name_avail = attr_name_avail; widget->widget = gtk_widget; @@ -70,90 +75,112 @@ static void iio_spin_button_update(struct iio_widget *widget) { gdouble freq; gdouble scale = widget->priv ? *(gdouble *)widget->priv : 1.0; + int ret; + + if (widget->chn) + ret = iio_channel_attr_read_double(widget->chn, + widget->attr_name, &freq); + else + ret = iio_device_attr_read_double(widget->dev, + widget->attr_name, &freq); + if (ret < 0) + return; - read_devattr_double(widget->attr_name, &freq); freq /= scale; gtk_spin_button_set_value(GTK_SPIN_BUTTON (widget->widget), freq); } -static void iio_spin_button_save(struct iio_widget *widget) +static void spin_button_save(struct iio_widget *widget, bool is_double) { gdouble freq; gdouble scale = widget->priv ? *(gdouble *)widget->priv : 1.0; freq = gtk_spin_button_get_value(GTK_SPIN_BUTTON (widget->widget)); freq *= scale; - write_devattr_double(widget->attr_name, freq); + + if (widget->chn) { + if (is_double) + iio_channel_attr_write_double(widget->chn, + widget->attr_name, freq); + else + iio_channel_attr_write_longlong(widget->chn, + widget->attr_name, (long long) freq); + } else { + if (is_double) + iio_device_attr_write_double(widget->dev, + widget->attr_name, freq); + else + iio_device_attr_write_longlong(widget->dev, + widget->attr_name, (long long) freq); + } } -static void iio_spin_button_int_save(struct iio_widget *widget) +static void iio_spin_button_savedbl(struct iio_widget *widget) { - gdouble freq; - gdouble scale = widget->priv ? *(gdouble *)widget->priv : 1.0; - - freq = gtk_spin_button_get_value(GTK_SPIN_BUTTON (widget->widget)); - freq *= scale; - write_devattr_int(widget->attr_name, freq); + return spin_button_save(widget, true); } -static void iio_spin_button_s64_save(struct iio_widget *widget) +static void iio_spin_button_save(struct iio_widget *widget) { - gdouble freq; - gdouble scale = widget->priv ? *(gdouble *)widget->priv : 1.0; - - freq = gtk_spin_button_get_value(GTK_SPIN_BUTTON (widget->widget)); - freq *= scale; - write_devattr_slonglong(widget->attr_name, (long long) freq); + return spin_button_save(widget, false); } -void iio_spin_button_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, +void iio_spin_button_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, GtkWidget *spin_button, const gdouble *scale) { - iio_widget_init(widget, device_name, attr_name, NULL, spin_button, - (void *)scale, iio_spin_button_update, iio_spin_button_save); + iio_widget_init(widget, dev, chn, attr_name, NULL, spin_button, + (void *)scale, iio_spin_button_update, iio_spin_button_savedbl); } -void iio_spin_button_int_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, +void iio_spin_button_int_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, GtkWidget *spin_button, const gdouble *scale) { - iio_widget_init(widget, device_name, attr_name, NULL, spin_button, - (void *)scale, iio_spin_button_update, iio_spin_button_int_save); + iio_widget_init(widget, dev, chn, attr_name, NULL, spin_button, + (void *)scale, iio_spin_button_update, iio_spin_button_save); } -void iio_spin_button_s64_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, +void iio_spin_button_s64_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, GtkWidget *spin_button, const gdouble *scale) { - iio_widget_init(widget, device_name, attr_name, NULL, spin_button, - (void *)scale, iio_spin_button_update, iio_spin_button_s64_save); + iio_widget_init(widget, dev, chn, attr_name, NULL, spin_button, + (void *)scale, iio_spin_button_update, iio_spin_button_save); } static void iio_toggle_button_save(struct iio_widget *widget) { - bool active; - - active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget->widget)); - + bool active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget->widget)); active = widget->priv ? !active : active; - write_devattr(widget->attr_name, active ? "1" : "0"); + + if (widget->chn) + iio_channel_attr_write_bool(widget->chn, + widget->attr_name, active); + else + iio_device_attr_write_bool(widget->dev, + widget->attr_name, active); } static void iio_toggle_button_update(struct iio_widget *widget) { - bool active = false; + bool active; - read_devattr_bool(widget->attr_name, &active); + if (widget->chn) + iio_channel_attr_read_bool(widget->chn, + widget->attr_name, &active); + else + iio_device_attr_read_bool(widget->dev, + widget->attr_name, &active); active = widget->priv ? !active : active; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (widget->widget), active); } static void iio_toggle_button_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkWidget *toggle_button, const bool invert) { - iio_widget_init(widget, device_name, attr_name, NULL, toggle_button, + iio_widget_init(widget, dev, chn, attr_name, NULL, toggle_button, (void *)invert, iio_toggle_button_update, iio_toggle_button_save); } @@ -165,7 +192,10 @@ static void iio_combo_box_save(struct iio_widget *widget) if (text == NULL) return; - write_devattr(widget->attr_name, text); + if (widget->chn) + iio_channel_attr_write(widget->chn, widget->attr_name, text); + else + iio_device_attr_write(widget->dev, widget->attr_name, text); } static void iio_combo_box_update(struct iio_widget *widget) @@ -174,12 +204,17 @@ static void iio_combo_box_update(struct iio_widget *widget) GtkComboBox *combo_box; GtkTreeIter iter; GtkTreeModel *model; - char *text, *item, *text2; + char text[1024], text2[1024], *item; gchar **items_avail = NULL, **saveditems_avail; gboolean has_iter; - int ret; + ssize_t ret; - ret = read_devattr(widget->attr_name, &text); + if (widget->chn) + ret = iio_channel_attr_read(widget->chn, + widget->attr_name, text, sizeof(text)); + else + ret = iio_device_attr_read(widget->dev, + widget->attr_name, text, sizeof(text)); if (ret < 0) return; @@ -187,7 +222,12 @@ static void iio_combo_box_update(struct iio_widget *widget) model = gtk_combo_box_get_model(combo_box); if (widget->attr_name_avail) { - ret = read_devattr(widget->attr_name_avail, &text2); + if (widget->chn) + ret = iio_channel_attr_read(widget->chn, + widget->attr_name_avail, text2, sizeof(text2)); + else + ret = iio_device_attr_read(widget->dev, + widget->attr_name_avail, text2, sizeof(text2)); if (ret < 0) return; @@ -204,8 +244,6 @@ static void iio_combo_box_update(struct iio_widget *widget) if (saveditems_avail) g_strfreev(saveditems_avail); - - free(text2); } if (widget->priv) @@ -224,27 +262,23 @@ static void iio_combo_box_update(struct iio_widget *widget) g_free(item); has_iter = gtk_tree_model_iter_next(model, &iter); } - - free(text); } -void iio_combo_box_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, const char *attr_name_avail, +void iio_combo_box_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, const char *attr_name_avail, GtkWidget *combo_box, int (*compare)(const char *a, const char *b)) { - iio_widget_init(widget, device_name, attr_name, attr_name_avail, combo_box, + iio_widget_init(widget, dev, chn, attr_name, attr_name_avail, combo_box, (void *)compare, iio_combo_box_update, iio_combo_box_save); } void iio_widget_update(struct iio_widget *widget) { - set_dev_paths(widget->device_name); widget->update(widget); } void iio_widget_save(struct iio_widget *widget) { - set_dev_paths(widget->device_name); widget->save(widget); widget->update(widget); } @@ -266,47 +300,48 @@ void iio_save_widgets(struct iio_widget *widgets, unsigned int num_widgets) } void iio_spin_button_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale) { - iio_spin_button_init(widget, device_name, attr_name, + iio_spin_button_init(widget, dev, chn, attr_name, GTK_WIDGET(gtk_builder_get_object(builder, widget_name)), scale); } void iio_spin_button_int_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale) { - iio_spin_button_int_init(widget, device_name, attr_name, + iio_spin_button_int_init(widget, dev, chn, attr_name, GTK_WIDGET(gtk_builder_get_object(builder, widget_name)), scale); } void iio_spin_button_s64_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale) { - iio_spin_button_s64_init(widget, device_name, attr_name, + iio_spin_button_s64_init(widget, dev, chn, attr_name, GTK_WIDGET(gtk_builder_get_object(builder, widget_name)), scale); } void iio_combo_box_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, const char *attr_name_avail, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, + const char *attr_name_avail, GtkBuilder *builder, const char *widget_name, int (*compare)(const char *a, const char *b)) { - iio_combo_box_init(widget, device_name, attr_name, attr_name_avail, + iio_combo_box_init(widget, dev, chn, attr_name, attr_name_avail, GTK_WIDGET(gtk_builder_get_object(builder, widget_name)), compare); } void iio_toggle_button_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const bool invert) { - iio_toggle_button_init(widget, device_name, attr_name, + iio_toggle_button_init(widget, dev, chn, attr_name, GTK_WIDGET(gtk_builder_get_object(builder, widget_name)), invert); } @@ -381,8 +416,10 @@ void iio_spin_button_add_progress(struct iio_widget *iio_w) struct progress_data *pdata; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { + const char *name = iio_device_get_name(iio_w->dev) ?: + iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", - iio_w->attr_name, iio_w->device_name); + iio_w->attr_name, name); return; } @@ -404,8 +441,10 @@ void iio_spin_button_progress_activate(struct iio_widget *iio_w) struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { + const char *name = iio_device_get_name(iio_w->dev) ?: + iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", - iio_w->attr_name, iio_w->device_name); + iio_w->attr_name, name); return; } @@ -423,8 +462,10 @@ void iio_spin_button_set_on_complete_function(struct iio_widget *iio_w, struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { + const char *name = iio_device_get_name(iio_w->dev) ?: + iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", - iio_w->attr_name, iio_w->device_name); + iio_w->attr_name, name); return; } @@ -440,8 +481,10 @@ void iio_spin_button_progress_deactivate(struct iio_widget *iio_w) struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { + const char *name = iio_device_get_name(iio_w->dev) ?: + iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", - iio_w->attr_name, iio_w->device_name); + iio_w->attr_name, name); return; } @@ -455,8 +498,10 @@ void iio_spin_button_progress_deactivate(struct iio_widget *iio_w) void iio_spin_button_remove_progress(struct iio_widget *iio_w) { if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { + const char *name = iio_device_get_name(iio_w->dev) ?: + iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", - iio_w->attr_name, iio_w->device_name); + iio_w->attr_name, name); return; } diff --git a/iio_widget.h b/iio_widget.h index 0f5d40fad..22c6f513b 100644 --- a/iio_widget.h +++ b/iio_widget.h @@ -8,8 +8,11 @@ #ifndef __IIO_WIDGET_H__ #define __IIO_WIDGET_H__ +#include + struct iio_widget { - const char *device_name; + struct iio_device *dev; + struct iio_channel *chn; const char *attr_name; const char *attr_name_avail; GtkWidget *widget; @@ -32,38 +35,38 @@ void iio_widget_update(struct iio_widget *widget); void iio_widget_save(struct iio_widget *widget); void iio_save_widgets(struct iio_widget *widgets, unsigned int num_widgets); -void iio_spin_button_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, - GtkWidget *gtk_widget, const gdouble *scale); +void iio_spin_button_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, + GtkWidget *spin_button, const gdouble *scale); void iio_spin_button_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale); -void iio_combo_box_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, const char *attr_name_avail, +void iio_combo_box_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, const char *attr_name_avail, GtkWidget *combo_box, int (*compare)(const char *a, const char *b)); void iio_combo_box_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, const char *attr_name_avail, GtkBuilder *builder, const char *widget_name, int (*compare)(const char *a, const char *b)); void iio_toggle_button_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const bool invert); void iio_spin_button_int_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale); -void iio_spin_button_int_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, +void iio_spin_button_int_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, GtkWidget *spin_button, const gdouble *scale); void iio_spin_button_s64_init_from_builder(struct iio_widget *widget, - const char *device_name, const char *attr_name, + struct iio_device *dev, struct iio_channel *chn, const char *attr_name, GtkBuilder *builder, const char *widget_name, const gdouble *scale); -void iio_spin_button_s64_init(struct iio_widget *widget, - const char *device_name, const char *attr_name, +void iio_spin_button_s64_init(struct iio_widget *widget, struct iio_device *dev, + struct iio_channel *chn, const char *attr_name, GtkWidget *spin_button, const gdouble *scale); void iio_spin_button_add_progress(struct iio_widget *iio_w); diff --git a/osc.c b/osc.c index 5635dc8df..93f50240e 100644 --- a/osc.c +++ b/osc.c @@ -20,9 +20,12 @@ #include #include #include +#include +#include #include #include +#include #include "ini/ini.h" #include "osc.h" @@ -37,12 +40,9 @@ extern char *get_filename_from_path(const char *path); GSList *plugin_list = NULL; -struct _device_list *device_list = NULL; -unsigned num_devices = 0; gint capture_function = 0; gfloat plugin_fft_corr = 0.0; static GList *plot_list = NULL; -static const char *current_device; static int num_capturing_plots; G_LOCK_DEFINE_STATIC(buffer_full); static gboolean stop_capture; @@ -51,6 +51,9 @@ static int num_check_fcts = 0; static GSList *dplugin_list = NULL; GtkWidget *notebook; +struct iio_context *ctx; +unsigned int num_devices = 0; + static void gfunc_save_plot_data_to_ini(gpointer data, gpointer user_data); static void plugin_restore_ini_state(char *plugin_name, gboolean detached); @@ -147,7 +150,7 @@ static void do_fft(Transform *tr) } if (fft->num_active_channels == 2) { - ch_info = tr->channel_parent2->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent2); in_data_c = ch_info->data_ref; for (cnt = 0, i = 0; cnt < fft_size; cnt++) { /* normalization and scaling see fft_corr */ @@ -429,13 +432,13 @@ void cross_correlation_transform_function(Transform *tr, gboolean init_transform gfloat *i_1, *q_1; int i; - ch_info = tr->channel_parent->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent); i_0 = ch_info->data_ref; - ch_info = tr->channel_parent2->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent2); q_0 = ch_info->data_ref; - ch_info = tr->channel_parent3->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent3); i_1 = ch_info->data_ref; - ch_info = tr->channel_parent4->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent4); q_1 = ch_info->data_ref; if (init_transform) { @@ -475,30 +478,32 @@ void cross_correlation_transform_function(Transform *tr, gboolean init_transform void fft_transform_function(Transform *tr, gboolean init_transform) { - struct extra_info *ch_info = tr->channel_parent->extra_field; + struct iio_channel *chn = tr->channel_parent; + struct extra_info *ch_info = iio_channel_get_data(chn); + struct extra_dev_info *dev_info = iio_device_get_data(ch_info->dev); struct _fft_settings *settings = tr->settings; - struct _device_list *device = ch_info->device_parent; unsigned axis_length; - unsigned num_samples = device->sample_count; + unsigned num_samples = dev_info->sample_count; double corr; int i; if (init_transform) { + unsigned int bits_used = iio_channel_get_data_format(chn)->bits; axis_length = settings->fft_size * settings->fft_alg_data.num_active_channels / 2; Transform_resize_x_axis(tr, axis_length); Transform_resize_y_axis(tr, axis_length); tr->y_axis_size = axis_length; if (settings->fft_alg_data.num_active_channels == 2) - corr = device->adc_freq / 2; + corr = dev_info->adc_freq / 2.0; else corr = 0; for (i = 0; i < axis_length; i++) { - tr->x_axis[i] = i * device->adc_freq / num_samples - corr; + tr->x_axis[i] = i * dev_info->adc_freq / num_samples - corr; tr->y_axis[i] = FLT_MAX; } /* Compute FFT normalization and scaling offset */ - settings->fft_alg_data.fft_corr = 20 * log10(2.0 / (1 << (tr->channel_parent->bits_used - 1))); + settings->fft_alg_data.fft_corr = 20 * log10(2.0 / (1 << (bits_used - 1))); return; } do_fft(tr); @@ -506,7 +511,7 @@ void fft_transform_function(Transform *tr, gboolean init_transform) void constellation_transform_function(Transform *tr, gboolean init_transform) { - struct extra_info *ch_info = tr->channel_parent2->extra_field; + struct extra_info *ch_info = iio_channel_get_data(tr->channel_parent2); gfloat *y_axis = ch_info->data_ref; struct _constellation_settings *settings = tr->settings; unsigned axis_length = settings->num_samples; @@ -569,173 +574,27 @@ static void destroy_all_plots(void) g_list_foreach(plot_list, gfunc_destroy_plot, NULL); } -static int sign_extend(unsigned int val, unsigned int bits) +static void disable_all_channels(struct iio_device *dev) { - unsigned int shift = 32 - bits; - return ((int )(val << shift)) >> shift; + unsigned int i, nb_channels = iio_device_get_channels_count(dev); + for (i = 0; i < nb_channels; i++) + iio_channel_disable(iio_device_get_channel(dev, i)); } -static void demux_data_stream(void *data_in, gfloat **data_out, - unsigned int num_samples, unsigned int offset, unsigned int data_out_size, - struct iio_channel_info *channels, unsigned int num_channels) +static void close_active_buffers(void) { - unsigned int i, j, n; - unsigned int val; - unsigned int k; + unsigned int i; - for (i = 0; i < num_samples; i++) { - n = (offset + i) % data_out_size; - k = 0; - for (j = 0; j < num_channels; j++) { - if (!channels[j].enabled) - continue; - switch (channels[j].bytes) { - case 1: - val = *(uint8_t *)data_in; - break; - case 2: - switch (channels[j].endianness) { - case IIO_BE: - val = be16toh(*(uint16_t *)data_in); - break; - case IIO_LE: - val = le16toh(*(uint16_t *)data_in); - break; - default: - val = 0; - break; - } - break; - case 4: - switch (channels[j].endianness) { - case IIO_BE: - val = be32toh(*(uint32_t *)data_in); - break; - case IIO_LE: - val = le32toh(*(uint32_t *)data_in); - break; - default: - val = 0; - break; - } - break; - default: - continue; - } - data_in += channels[j].bytes; - val >>= channels[j].shift; - val &= channels[j].mask; - if (channels[j].is_signed) - data_out[k][n] = sign_extend(val, channels[j].bits_used); - else - data_out[k][n] = val; - k++; + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *info = iio_device_get_data(dev); + if (info->buffer) { + iio_buffer_destroy(info->buffer); + info->buffer = NULL; } - } - -} - -static int buffer_open(unsigned int length, int flags) -{ - int ret; - int fd; - - if (!current_device) - return -ENODEV; - - set_dev_paths(current_device); - - fd = iio_buffer_open(true, flags); - if (fd < 0) { - ret = -errno; - fprintf(stderr, "Failed to open buffer: %d\n", ret); - return ret; - } - - /* Setup ring buffer parameters */ - ret = write_devattr_int("buffer/length", length); - if (ret < 0) { - fprintf(stderr, "Failed to set buffer length: %d\n", ret); - goto err_close; - } - - /* Enable the buffer */ - ret = write_devattr_int("buffer/enable", 1); - if (ret < 0) { - fprintf(stderr, "Failed to enable buffer: %d\n", ret); - goto err_close; - } - return fd; - -err_close: - close(fd); - return ret; -} - -static void buffer_close(unsigned int fd) -{ - int ret; - - if (!current_device) - return; - - set_dev_paths(current_device); - - /* Enable the buffer */ - ret = write_devattr_int("buffer/enable", 0); - if (ret < 0) { - fprintf(stderr, "Failed to disable buffer: %d\n", ret); - } - - close(fd); -} - -unsigned int set_channel_attr_enable(const char *device_name, struct iio_channel_info *channel, unsigned enable) -{ - char buf[512]; - FILE *f; - int ret; - - set_dev_paths(device_name); - snprintf(buf, sizeof(buf), "%s/scan_elements/%s_en", dev_name_dir(), channel->name); - f = fopen(buf, "w"); - if (f) { - fprintf(f, "%u\n", enable); - fclose(f); - - f = fopen(buf, "r"); - ret = fscanf(f, "%u", &enable); - if (ret != 1) - enable = 0; - fclose(f); - } else { - enable = 0; + disable_all_channels(dev); } - - return enable; -} - -static void disable_all_channels(void) -{ - int i, j; - - for (i = 0; i < num_devices; i++) - for (j = 0; j < device_list[i].num_channels; j++) - set_channel_attr_enable(device_list[i].device_name, &device_list[i].channel_list[j], 0); -} - -static void close_active_buffers(void) -{ - int i; - - for (i = 0; i < num_devices; i++) - if (device_list[i].buffer_fd >= 0) { - current_device = device_list[i].device_name; - buffer_close(device_list[i].buffer_fd); - device_list[i].buffer_fd = -1; - } - disable_all_channels(); } static void stop_sampling(void) @@ -752,70 +611,6 @@ static void abort_sampling(void) close_all_plots(); } -static bool is_oneshot_mode(void) -{ - if (strncmp(current_device, "cf-ad9", 5) == 0) - return true; - if (strncmp(current_device, "ad-mc-", 5) == 0) - return true; - - return false; -} - -static int sample_iio_data_continuous(int buffer_fd, struct buffer *buf) -{ - int ret; - - ret = read(buffer_fd, buf->data + buf->available, buf->size - buf->available); - - if (ret == 0) - return 0; - if (ret < 0) { - if (errno == EAGAIN) - return 0; - else - return -errno; - } - - buf->available += ret; - - return 0; -} - -static int sample_iio_data_oneshot(struct buffer *buf) -{ - int fd, ret; - - fd = buffer_open(buf->size, 0); - if (fd < 0) - return fd; - - ret = sample_iio_data_continuous(fd, buf); - - buffer_close(fd); - - return ret; -} - -static int sample_iio_data(struct _device_list *device) -{ - int ret; - struct buffer *buf = &device->data_buffer; - - if (is_oneshot_mode()) - ret = sample_iio_data_oneshot(buf); - else - ret = sample_iio_data_continuous(device->buffer_fd, buf); - - if ((buf->data_copy) && (buf->available == buf->size)) { - memcpy(buf->data_copy, buf->data, buf->size); - buf->data_copy = NULL; - G_UNLOCK(buffer_full); - } - - return ret; -} - static void detach_plugin(GtkToolButton *btn, gpointer data); static GtkWidget* plugin_tab_add_detach_btn(GtkWidget *page, const struct detachable_plugin *d_plugin) @@ -972,34 +767,25 @@ static void detach_plugin(GtkToolButton *btn, gpointer data) gtk_widget_show_all(vbox); } -const char * device_name_check(const char *device_name) +static struct iio_device * find_device_by_name(const char *name) { - int i; - - if (!device_name) - return NULL; + unsigned int i; for (i = 0; i < num_devices; i++) { - if (strcmp(device_name, device_list[i].device_name) == 0) - return device_list[i].device_name; + struct iio_device *dev = iio_context_get_device(ctx, i); + const char *id = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + if (!strcmp(id, name)) + return dev; } return NULL; } -void * find_device_by_name(const char *device_name) +static const char * device_name_check(const char *name) { - int i; - - if (!device_name) - return NULL; - - for (i = 0; i < num_devices; i++) { - if (strcmp(device_name, device_list[i].device_name) == 0) - return (void *)&device_list[i]; - } - - return NULL; + struct iio_device *dev = find_device_by_name(name); + return iio_device_get_name(dev) ?: iio_device_get_id(dev); } static OscPlot * find_a_fft_plot(GList *list) @@ -1071,37 +857,44 @@ gdouble plugin_get_fft_avg(const char *device) int plugin_data_capture_size(const char *device) { - struct _device_list *dev; - - dev = find_device_by_name(device); + struct extra_dev_info *info; + struct iio_device *dev = find_device_by_name(device); if (!dev) return 0; - return dev->data_buffer.size; + info = iio_device_get_data(dev); + return info->sample_count * iio_device_get_sample_size(dev); } int plugin_data_capture_num_active_channels(const char *device) { - struct _device_list *dev; - - dev = find_device_by_name(device); + int nb_active = 0; + unsigned int i, nb_channels; + struct iio_device *dev = find_device_by_name(device); if (!dev) return 0; - return dev->num_active_channels; + nb_channels = iio_device_get_channels_count(dev); + for (i = 0; i < nb_channels; i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + if (iio_channel_is_enabled(chn)) + nb_active++; + } + + return nb_active; } int plugin_data_capture_bytes_per_sample(const char *device) { - struct _device_list *dev; - - dev = find_device_by_name(device); + struct iio_device *dev = find_device_by_name(device); if (!dev) return 0; - - return dev->bytes_per_sample; + else + return iio_device_get_sample_size(dev); } +#if 0 +/* TODO(pcercuei): convert this to libiio */ int plugin_data_capture(const char *device, void **buf, gfloat ***cooked_data, struct marker_type **markers_cp) { @@ -1112,7 +905,7 @@ int plugin_data_capture(const char *device, void **buf, gfloat ***cooked_data, bool is_fft_mode; int i, j; bool new = FALSE; - char *tmp = NULL; + const char *tmp = NULL; dev = find_device_by_name(device); fft_plot = find_a_fft_plot(plot_list); @@ -1260,6 +1053,7 @@ int plugin_data_capture(const char *device, void **buf, gfloat ***cooked_data, printf("%s:%s malloc failed\n", __FILE__, __func__); return -ENOMEM; } +#endif static bool force_plugin(const char *name) { @@ -1425,38 +1219,61 @@ static void plugin_state_ini_save(gpointer data, gpointer user_data) fprintf(fp, "plugin.%s.detached=%d\n", p->plugin->name, p->detached_state); } -static gboolean capture_proccess(void) +static ssize_t demux_sample(const struct iio_channel *chn, + void *sample, size_t size, void *d) { - unsigned int n; - int ret; - int i; + struct extra_info *info = iio_channel_get_data(chn); + struct extra_dev_info *dev_info = iio_device_get_data(info->dev); - for (i = 0; i < num_devices; i++) { - if (device_list[i].bytes_per_sample == 0) - continue; - current_device = device_list[i].device_name; - ret = sample_iio_data(&device_list[i]); - if (ret < 0) { - abort_sampling(); - fprintf(stderr, "Failed to capture samples: %s\n", strerror(-ret)); - return FALSE; - } + /* Prevent buffer overflow */ + if (info->offset == dev_info->sample_count) + return 0; + + if (size == 1) { + int8_t val; + iio_channel_convert(chn, &val, sample); + *(info->data_ref + info->offset++) = (gfloat) val; + } else if (size == 2) { + int16_t val; + iio_channel_convert(chn, &val, sample); + *(info->data_ref + info->offset++) = (gfloat) val; + } else { + int32_t val; + iio_channel_convert(chn, &val, sample); + *(info->data_ref + info->offset++) = (gfloat) val; } + return size; +} + +static gboolean capture_process(void) +{ + unsigned int i; + for (i = 0; i < num_devices; i++) { - if (device_list[i].bytes_per_sample == 0) + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *dev_info = iio_device_get_data(dev); + unsigned int i, sample_size = iio_device_get_sample_size(dev); + unsigned int nb_channels = iio_device_get_channels_count(dev); + unsigned int sample_count = dev_info->sample_count; + + if (sample_size == 0) continue; - n = device_list[i].data_buffer.available / device_list[i].bytes_per_sample; - demux_data_stream(device_list[i].data_buffer.data, device_list[i].channel_data, n, device_list[i].current_sample, - device_list[i].sample_count, device_list[i].channel_list, device_list[i].num_channels); - device_list[i].current_sample = (device_list[i].current_sample + n) % device_list[i].sample_count; - device_list[i].data_buffer.available -= n * device_list[i].bytes_per_sample; - if (device_list[i].data_buffer.available != 0) { - memmove(device_list[i].data_buffer.data, - device_list[i].data_buffer.data + n * device_list[i].bytes_per_sample, - device_list[i].data_buffer.available); + /* Reset the data offset for all channels */ + for (i = 0; i < nb_channels; i++) { + struct iio_channel *ch = iio_device_get_channel(dev, i); + struct extra_info *info = iio_channel_get_data(ch); + info->offset = 0; } + + do { + ssize_t ret; + iio_buffer_refill(dev_info->buffer); + ret = iio_buffer_foreach_sample( + dev_info->buffer, demux_sample, NULL); + sample_count -= ret / sample_size; + } while (sample_count); } update_all_plots(); @@ -1466,14 +1283,13 @@ static gboolean capture_proccess(void) return !stop_capture; } -static unsigned int max_sample_count_from_plots(struct _device_list *device) +static unsigned int max_sample_count_from_plots(struct extra_dev_info *info) { unsigned int max_count = 0; struct plot_params *prm; - GSList *list; GSList *node; + GSList *list = info->plots_sample_counts; - list = device->plots_sample_counts; for (node = list; node; node = g_slist_next(node)) { prm = node->data; if (prm->sample_count > max_count) @@ -1483,62 +1299,49 @@ static unsigned int max_sample_count_from_plots(struct _device_list *device) return max_count; } -static void resize_device_data(struct _device_list *device) +static int capture_setup(void) { - struct iio_channel_info *channel; - struct extra_info *ch_info; - unsigned enable; - int i; - int k; - - /* Check the enable status of the channels from all windows and update the channels enable attributes. */ - device->bytes_per_sample = 0; - device->num_active_channels = 0; - for (i = 0; i < device->num_channels; i++) { - channel = &device->channel_list[i]; - ch_info = channel->extra_field; - enable = (ch_info->shadow_of_enabled > 0) ? 1 : 0; - channel->enabled = enable; - enable = set_channel_attr_enable(device->device_name, channel, enable); - if (enable) { - device->bytes_per_sample += channel->bytes; - device->num_active_channels++; - } - } + unsigned int i, j; - /* Reallocate memory for the active channels of the device */ - device->data_buffer.size = device->sample_count * device->bytes_per_sample; - device->data_buffer.data = g_renew(int8_t, device->data_buffer.data, device->data_buffer.size); - device->data_buffer.available = 0; - device->data_buffer.data_copy = NULL; - device->current_sample = 0; - k = 0; - for (i = 0; i < device->num_channels; i++) { - channel = &device->channel_list[i]; - if (channel->enabled) { - ch_info = (struct extra_info *)channel->extra_field; - if (ch_info->data_ref) - g_free(ch_info->data_ref); - ch_info->data_ref = (gfloat *)g_new0(gfloat, device->sample_count); - /* Copy the channel data address to variable */ - device->channel_data[k++] = ch_info->data_ref; + fprintf(stderr, "capture setup\n"); + + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *dev_info = iio_device_get_data(dev); + unsigned int nb_channels = iio_device_get_channels_count(dev); + unsigned int sample_size, sample_count = max_sample_count_from_plots(dev_info); + + for (j = 0; j < nb_channels; j++) { + struct iio_channel *ch = iio_device_get_channel(dev, j); + struct extra_info *info = iio_channel_get_data(ch); + if (info->shadow_of_enabled > 0) + iio_channel_enable(ch); + else + iio_channel_disable(ch); } - } -} -static int capture_setup(void) -{ - int i; + sample_size = iio_device_get_sample_size(dev); + if (sample_size == 0) + continue; - for (i = 0; i < num_devices; i++) { - device_list[i].sample_count = max_sample_count_from_plots(&device_list[i]); - resize_device_data(&device_list[i]); - current_device = device_list[i].device_name; - if ((!is_oneshot_mode()) && (device_list[i].bytes_per_sample != 0)) { - device_list[i].buffer_fd = buffer_open(device_list[i].sample_count, O_NONBLOCK); - if (device_list[i].buffer_fd < 0) - return -1; + for (j = 0; j < nb_channels; j++) { + struct iio_channel *ch = iio_device_get_channel(dev, j); + struct extra_info *info = iio_channel_get_data(ch); + + if (info->data_ref) + g_free(info->data_ref); + info->data_ref = (gfloat *) g_new0(gfloat, sample_count); + } + + dev_info->buffer = iio_device_create_buffer(dev, + sample_count, false); + if (!dev_info->buffer) { + fprintf(stderr, "Unable to create buffer\n"); + return -1; } + dev_info->sample_count = sample_count; + + iio_device_set_data(dev, dev_info); } return 0; @@ -1551,7 +1354,8 @@ static void capture_start(void) } else { stop_capture = FALSE; - capture_function = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 50, (GSourceFunc) capture_proccess, NULL, NULL); + fprintf(stderr, "Starting capture process\n"); + capture_function = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 50, (GSourceFunc) capture_process, NULL, NULL); } } @@ -1681,100 +1485,27 @@ void sigterm (int signum) application_quit(); } -bool is_input_device(const char *device) -{ - struct iio_channel_info *channels = NULL; - unsigned int num_channels; - bool is_input = false; - int ret; - int i; - - set_dev_paths(device); - - ret = build_channel_array(dev_name_dir(), &channels, &num_channels); - if (ret) - return false; - - for (i = 0; i < num_channels; i++) { - if (strncmp("in", channels[i].name, 2) == 0) { - is_input = true; - break; - } - } - free_channel_array(channels, num_channels); - - return is_input; -} - -static struct _device_list *add_device(struct _device_list *dev_list, const char *device) +static void init_device_list(void) { - struct extra_info *ch_info; - int dev_name_len; - int ret; - int n; - int j; - - /* Add device */ - dev_list = (struct _device_list *)realloc(dev_list, sizeof(*dev_list) * num_devices); - set_dev_paths(device); - - /* Init device */ - n = num_devices - 1; - - dev_name_len = strlen(device) + 1; - dev_list[n].device_name = (char *)malloc(sizeof(char) * dev_name_len); - snprintf(dev_list[n].device_name, dev_name_len, "%s", device); - - ret = build_channel_array(dev_name_dir(), &dev_list[n].channel_list, &dev_list[n].num_channels); - if (ret) - return NULL; + unsigned int i, j; - for (j = 0; j < dev_list[n].num_channels; j++) { - ch_info = (struct extra_info *)malloc(sizeof(struct extra_info)); - ch_info->device_parent = NULL; /* Don't add the device parrent yet(dev_list addresses may change due to realloc) */ - ch_info->data_ref = NULL; - ch_info->shadow_of_enabled = 0; - dev_list[n].channel_list[j].extra_field = ch_info; - } - - dev_list[n].data_buffer.data = NULL; - dev_list[n].data_buffer.data_copy = NULL; - dev_list[n].sample_count = 400; - dev_list[n].plots_sample_counts = NULL; - dev_list[n].channel_data = (gfloat **)malloc(sizeof(gfloat *) * dev_list[n].num_channels); - dev_list[n].buffer_fd = -1; - dev_list[n].lo_freq = 0; + ctx = osc_create_context(); + if (!ctx) + return; - return dev_list; -} + num_devices = iio_context_get_devices_count(ctx); -static void init_device_list(void) -{ - char *devices = NULL, *device; - unsigned int num; - struct iio_channel_info *channel; - int i, j; - - num = find_iio_names(&devices, "iio:device"); - if (devices != NULL) { - device = devices; - for (; num > 0; num--) { - if (is_input_device(device)) { - num_devices++; - device_list = add_device(device_list, device); - } - device += strlen(device) + 1; - } - } - free(devices); - - /* Disable all channels. Link parent references to channels*/ - for (i = 0; i < num_devices; i++) { - for (j = 0; j < device_list[i].num_channels; j++) { - channel = &device_list[i].channel_list[j]; - set_channel_attr_enable(device_list[i].device_name, channel, 0); - channel->enabled = 0; - ((struct extra_info *)channel->extra_field)->device_parent = &device_list[i]; + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + unsigned int nb_channels = iio_device_get_channels_count(dev); + struct extra_dev_info *dev_info = calloc(1, sizeof(*dev_info)); + iio_device_set_data(dev, dev_info); + + for (j = 0; j < nb_channels; j++) { + struct iio_channel *ch = iio_device_get_channel(dev, j); + struct extra_info *info = calloc(1, sizeof(*info)); + info->dev = dev; + iio_channel_set_data(ch, info); } } } @@ -1790,68 +1521,95 @@ gboolean save_sample_count_cb(GtkWidget *widget, GdkEventKey *event, gpointer da return FALSE; } -static double read_sampling_frequency(const char *device) +static double read_sampling_frequency(const struct iio_device *dev) { - double freq = 1.0; - int ret; + double freq = 400.0; + int ret = -1; + unsigned int i, nb_channels = iio_device_get_channels_count(dev); + char buf[1024]; - if (set_dev_paths(device) < 0) - return -1.0f; + for (i = 0; i < nb_channels; i++) { + struct iio_channel *ch = iio_device_get_channel(dev, i); - if (iio_devattr_exists(device, "in_voltage_sampling_frequency")) { - read_devattr_double("in_voltage_sampling_frequency", &freq); - if (freq < 0) - freq = ((double)4294967296) + freq; - } else if (iio_devattr_exists(device, "sampling_frequency")) { - read_devattr_double("sampling_frequency", &freq); - } else { - char *trigger; - - ret = read_devattr("trigger/current_trigger", &trigger); - if (ret >= 0) { - if (*trigger != '\0') { - set_dev_paths(trigger); - if (iio_devattr_exists(trigger, "frequency")) - read_devattr_double("frequency", &freq); - } - free(trigger); - } else - freq = -1.0f; + if (iio_channel_is_output(ch) || strncmp(iio_channel_get_id(ch), + "voltage", sizeof("voltage") - 1)) + continue; + + ret = iio_channel_attr_read(ch, "sampling_frequency", + buf, sizeof(buf)); + if (ret > 0) + break; } + if (ret < 0) + ret = iio_device_attr_read(dev, "sampling_frequency", + buf, sizeof(buf)); + if (ret < 0) { + const struct iio_device *trigger; + ret = iio_device_get_trigger(dev, &trigger); + if (!ret) + ret = iio_device_attr_read(trigger, "frequency", + buf, sizeof(buf)); + } + + if (ret > 0) + sscanf(buf, "%lf", &freq); return freq; } +static void set_lo_freq(struct iio_device *dev, const char *attr) +{ + struct extra_dev_info *info = iio_device_get_data(dev); + unsigned int i, nb_channels = iio_device_get_channels_count(dev); + + for (i = 0; i < nb_channels; i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + const char *id = iio_channel_get_id(chn); + if (iio_channel_is_output(chn) && !strcmp(id, "altvoltage0")) { + char buf[1024]; + int ret = iio_channel_attr_read(chn, + attr, buf, sizeof(buf)); + if (ret > 0) + info->lo_freq = atof(buf); + break; + } + } +} + void rx_update_labels(void) { - int i; + unsigned int i; for (i = 0; i < num_devices; i++) { - device_list[i].adc_freq = read_sampling_frequency(device_list[i].device_name); - if (device_list[i].adc_freq >= 1000000) { - sprintf(device_list[i].adc_scale, "M"); - device_list[i].adc_freq /= 1000000; - } else if(device_list[i].adc_freq >= 1000) { - sprintf(device_list[i].adc_scale, "k"); - device_list[i].adc_freq /= 1000; - } else if(device_list[i].adc_freq >= 0) { - sprintf(device_list[i].adc_scale, " "); + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *info = iio_device_get_data(dev); + const char *name = iio_device_get_name(dev); + + info->lo_freq = 0.0; + info->adc_freq = read_sampling_frequency(dev); + + if (info->adc_freq >= 1000000) { + info->adc_scale = 'M'; + info->adc_freq /= 1000000.0; + } else if (info->adc_freq >= 1000) { + info->adc_scale = 'k'; + info->adc_freq /= 1000.0; + } else if (info->adc_freq >= 0) { + info->adc_scale = ' '; } else { - sprintf(device_list[i].adc_scale, "?"); - device_list[i].adc_freq = 0; + info->adc_scale = '?'; + info->adc_freq = 0.0; } - if (strcmp(device_list[i].device_name, "cf-ad9643-core-lpc") == 0) { - set_dev_paths("adf4351-rx-lpc"); - read_devattr_double("out_altvoltage0_frequency", &device_list[i].lo_freq); - } else if (strcmp(device_list[i].device_name, "cf-ad9361-lpc") == 0) { - set_dev_paths("ad9361-phy"); - read_devattr_double("out_altvoltage0_RX_LO_frequency", &device_list[i].lo_freq); - } else { - device_list[i].lo_freq = 0; - } - if (device_list[i].lo_freq) - device_list[i].lo_freq /= 1000000.0; + if (!name) + continue; + + if (!strcmp(name, "adf4351-rx-lpc")) + set_lo_freq(dev, "frequency"); + else if (!strcmp(name, "ad9361-phy")) + set_lo_freq(dev, "RX_LO_frequency"); + + info->lo_freq /= 1000000.0; } GList *node; @@ -2195,3 +1953,12 @@ gint main (int argc, char **argv) return -1; } +struct iio_context * osc_create_context(void) +{ + char *host = getenv("OSC_REMOTE"); + if (host) + return iio_create_network_context(host); + else + return iio_create_local_context(); +} + diff --git a/osc.h b/osc.h index 116e56e1c..99eb677f2 100644 --- a/osc.h +++ b/osc.h @@ -95,4 +95,6 @@ gint create_blocking_popup(GtkMessageType type, GtkButtonsType button, const char *title, const char *str, ...); gint fru_connect(void); +struct iio_context * osc_create_context(void); + #endif diff --git a/oscplot.c b/oscplot.c index 15f233c0b..87bcd5194 100644 --- a/oscplot.c +++ b/oscplot.c @@ -16,6 +16,11 @@ #include #include #include +#include +#include +#include + +#include #include "ini/ini.h" #include "osc.h" @@ -30,10 +35,10 @@ extern void constellation_transform_function(Transform *tr, gboolean init_transf extern void cross_correlation_transform_function(Transform *tr, gboolean init_transform); extern void *find_setup_check_fct_by_devname(const char *dev_name); -extern struct _device_list *device_list; +extern struct iio_context *ctx; extern unsigned num_devices; -static int (*plugin_setup_validation_fct)(struct iio_channel_info*, int, char **) = NULL; +static int (*plugin_setup_validation_fct)(struct iio_device *, const char **) = NULL; static unsigned object_count = 0; static void create_plot (OscPlot *plot); @@ -52,8 +57,8 @@ static void treeview_expand_update(OscPlot *plot); static void treeview_icon_color_update(OscPlot *plot); static int cfg_read_handler(void *user, const char* section, const char* name, const char* value); static int device_find_by_name(const char *name); -static int enabled_channels_of_device(GtkTreeView *treeview, const char *dev_name); -static gboolean get_iter_by_name(GtkTreeView *tree, GtkTreeIter *iter, char *dev_name, char *ch_name); +static int enabled_channels_of_device(GtkTreeView *treeview, const char *name); +static gboolean get_iter_by_name(GtkTreeView *tree, GtkTreeIter *iter, const char *dev_name, char *ch_name); static void set_marker_labels (OscPlot *plot, gchar *buf, enum marker_types type); static void channel_color_icon_set_color(GdkPixbuf *pb, GdkColor *color); @@ -138,9 +143,6 @@ static GdkColor color_marker = { }; /* Helpers */ -#define GET_CHANNEL_PARENT(ch) ((struct extra_info *)(((struct iio_channel_info *)(ch))->extra_field))->device_parent -#define CHANNEL_EXTRA_FIELD(ch) ((struct extra_info *)ch->extra_field) - #define TIME_SETTINGS(obj) ((struct _time_settings *)obj->settings) #define FFT_SETTINGS(obj) ((struct _fft_settings *)obj->settings) #define CONSTELLATION_SETTINGS(obj) ((struct _constellation_settings *)obj->settings) @@ -215,7 +217,7 @@ struct _OscPlotPrivate gint deactivate_capture_btn_flag; /* A reference to the device holding the most recent created transform */ - struct _device_list *current_device; + struct extra_dev_info *current_device; /* List of transforms for this plot */ TrList *transform_list; @@ -354,9 +356,9 @@ void osc_plot_update_rx_lbl(OscPlot *plot, bool force_update) return; if (priv->active_transform_type == FFT_TRANSFORM || priv->active_transform_type == COMPLEX_FFT_TRANSFORM) { - sprintf(buf, "%sHz", priv->current_device->adc_scale); + sprintf(buf, "%cHz", priv->current_device->adc_scale); gtk_label_set_text(GTK_LABEL(priv->hor_scale), buf); - /* In FFT mode we need to scale the x-axis according to the selected sampling freequency */ + /* In FFT mode we need to scale the x-axis according to the selected sampling frequency */ for (i = 0; i < tr_list->size; i++) Transform_setup(tr_list->transforms[i]); if (priv->active_transform_type == COMPLEX_FFT_TRANSFORM) @@ -412,21 +414,22 @@ void osc_plot_save_as (OscPlot *plot, char *filename, int type) save_as(plot, filename, type); } -char * osc_plot_get_active_device (OscPlot *plot) +const char * osc_plot_get_active_device (OscPlot *plot) { OscPlotPrivate *priv = plot->priv; GtkTreeModel *model; GtkTreeIter iter; gboolean next_iter; gboolean active; - struct _device_list *device; + struct iio_device *dev; model = gtk_tree_view_get_model(GTK_TREE_VIEW(priv->channel_list_view)); next_iter = gtk_tree_model_get_iter_first(model, &iter); while (next_iter) { - gtk_tree_model_get(model, &iter, ELEMENT_REFERENCE, &device, DEVICE_ACTIVE, &active, -1); + gtk_tree_model_get(model, &iter, ELEMENT_REFERENCE, &dev, DEVICE_ACTIVE, &active, -1); if (active) - return device->device_name; + return iio_device_get_name(dev) ?: + iio_device_get_id(dev); next_iter = gtk_tree_model_iter_next(model, &iter); } @@ -511,14 +514,14 @@ static void foreach_device_iter(GtkTreeView *treeview, } } -static void foreach_channel_iter_of_device(GtkTreeView *treeview, struct _device_list *device, +static void foreach_channel_iter_of_device(GtkTreeView *treeview, const char *name, void (*tree_iter_func)(GtkTreeModel *model, GtkTreeIter *data, void *user_data), void *user_data) { GtkTreeIter iter; GtkTreeIter child_iter; GtkTreeModel *model; - gboolean next_iter; + gboolean next_iter = true; gboolean next_child_iter; char *str_device; @@ -526,61 +529,59 @@ static void foreach_channel_iter_of_device(GtkTreeView *treeview, struct _device if (!gtk_tree_model_get_iter_first(model, &iter)) return; - next_iter = true; - while (next_iter) { + do { gtk_tree_model_get(model, &iter, ELEMENT_NAME, &str_device, -1); - if (!strcmp(device->device_name, str_device)) { - g_free(str_device); + if (!strcmp(name, str_device)) break; - } - g_free(str_device); next_iter = gtk_tree_model_iter_next(model, &iter); - } + } while (next_iter); if (!next_iter) return; - gtk_tree_model_iter_children(model, &child_iter, &iter); - next_child_iter = true; + next_child_iter = gtk_tree_model_iter_children(model, &child_iter, &iter); while (next_child_iter) { tree_iter_func(model, &child_iter, user_data); next_child_iter = gtk_tree_model_iter_next(model, &child_iter); } } - static void channel_duplicate(GtkTreeModel *model, GtkTreeIter *iter, void *user_data) - { - struct iio_channel_info *channel; - struct iio_channel_info *duplicate_ch_list = user_data; - gboolean enabled; - int i; - - gtk_tree_model_get(model, iter, ELEMENT_REFERENCE, &channel, - CHANNEL_ACTIVE, &enabled, -1); - i = channel->index; - duplicate_ch_list[i].name = channel->name; - duplicate_ch_list[i].enabled = enabled; +static void set_may_be_enabled_bit(GtkTreeModel *model, + GtkTreeIter *iter, void *user_data) +{ + gboolean enabled; + struct iio_channel *chn; + struct extra_info *info; - } + gtk_tree_model_get(model, iter, ELEMENT_REFERENCE, &chn, + CHANNEL_ACTIVE, &enabled, -1); + info = iio_channel_get_data(chn); + info->may_be_enabled = enabled; +} -static gboolean check_valid_setup_of_device(OscPlot *plot, struct _device_list *device) +static gboolean check_valid_setup_of_device(OscPlot *plot, struct iio_device *dev) { OscPlotPrivate *priv = plot->priv; int plot_type; int num_enabled; + const char *name = iio_device_get_name(dev) ?: iio_device_get_id(dev); + unsigned int nb_channels = iio_device_get_channels_count(dev); GtkTreeModel *model; GtkTreeIter iter; gboolean device_enabled; + if (nb_channels < 1) + return false; + plot_type = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->plot_domain)); model = gtk_tree_view_get_model(GTK_TREE_VIEW(priv->channel_list_view)); - get_iter_by_name(GTK_TREE_VIEW(priv->channel_list_view), &iter, device->device_name, NULL); + get_iter_by_name(GTK_TREE_VIEW(priv->channel_list_view), &iter, name, NULL); gtk_tree_model_get(model, &iter, DEVICE_ACTIVE, &device_enabled, -1); if (!device_enabled && plot_type != TIME_PLOT) return true; - num_enabled = enabled_channels_of_device(GTK_TREE_VIEW(priv->channel_list_view), device->device_name); + num_enabled = enabled_channels_of_device(GTK_TREE_VIEW(priv->channel_list_view), name); /* Basic validation rules */ if (plot_type == FFT_PLOT) { @@ -607,20 +608,15 @@ static gboolean check_valid_setup_of_device(OscPlot *plot, struct _device_list * if (num_enabled != 2 || plot_type == TIME_PLOT) return true; - struct iio_channel_info *temp_channels; bool valid_comb; - char *ch_names[2]; + const char *ch_names[2]; char warning_text[100]; - plugin_setup_validation_fct = find_setup_check_fct_by_devname(device->device_name); + plugin_setup_validation_fct = find_setup_check_fct_by_devname(name); if (plugin_setup_validation_fct) { - temp_channels = (struct iio_channel_info *)malloc(sizeof(struct iio_channel_info) * device->num_channels); - /* Simulate the existing channel list, because channels that are enabled - in this window are not necessary enabled in the existing channel list. */ foreach_channel_iter_of_device(GTK_TREE_VIEW(priv->channel_list_view), - device, *channel_duplicate, temp_channels); - valid_comb = (*plugin_setup_validation_fct)(temp_channels, device->num_channels, ch_names); - free(temp_channels); + name, *set_may_be_enabled_bit, NULL); + valid_comb = (*plugin_setup_validation_fct)(dev, ch_names); if (!valid_comb) { snprintf(warning_text, sizeof(warning_text), "Combination between %s and %s is invalid", ch_names[0], ch_names[1]); @@ -634,12 +630,13 @@ static gboolean check_valid_setup_of_device(OscPlot *plot, struct _device_list * static gboolean check_valid_setup(OscPlot *plot) { + unsigned int i; OscPlotPrivate *priv = plot->priv; gboolean is_valid = false; - int i; for (i = 0; i < num_devices; i++) { - is_valid = check_valid_setup_of_device(plot, &device_list[i]); + struct iio_device *dev = iio_context_get_device(ctx, i); + is_valid = check_valid_setup_of_device(plot, dev); if (gtk_combo_box_get_active(GTK_COMBO_BOX(priv->plot_domain)) == TIME_PLOT) { if (!is_valid) continue; @@ -711,8 +708,8 @@ static void update_transform_settings(OscPlot *plot, Transform *transform, } } -static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info *ch0, - struct iio_channel_info *ch1, struct iio_channel_info *ch2, struct iio_channel_info *ch3, +static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel *ch0, + struct iio_channel *ch1, struct iio_channel *ch2, struct iio_channel *ch3, int tr_type, struct channel_settings *csettings) { OscPlotPrivate *priv = plot->priv; @@ -722,14 +719,14 @@ static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info * struct _fft_settings *fft_settings; struct _constellation_settings *constellation_settings; struct _cross_correlation_settings *xcross_settings; - struct extra_info *ch_info; + struct extra_info *ch_info = iio_channel_get_data(ch0); + struct extra_dev_info *dev_info = iio_device_get_data(ch_info->dev); transform = Transform_new(tr_type); - ch_info = ch0->extra_field; transform->channel_parent = ch0; transform->graph_color = &color_graph[0]; ch_info->shadow_of_enabled++; - priv->current_device = GET_CHANNEL_PARENT(ch0); + Transform_set_in_data_ref(transform, (gfloat **)&ch_info->data_ref); switch (tr_type) { case TIME_TRANSFORM: @@ -750,7 +747,7 @@ static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info * Transform_attach_function(transform, constellation_transform_function); constellation_settings = (struct _constellation_settings *)malloc(sizeof(struct _constellation_settings)); Transform_attach_settings(transform, constellation_settings); - ch_info = ch1->extra_field; + ch_info = iio_channel_get_data(ch1); ch_info->shadow_of_enabled++; priv->active_transform_type = CONSTELLATION_TRANSFORM; break; @@ -759,7 +756,7 @@ static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info * Transform_attach_function(transform, fft_transform_function); fft_settings = (struct _fft_settings *)malloc(sizeof(struct _fft_settings)); Transform_attach_settings(transform, fft_settings); - ch_info = ch1->extra_field; + ch_info = iio_channel_get_data(ch1); ch_info->shadow_of_enabled++; priv->active_transform_type = COMPLEX_FFT_TRANSFORM; break; @@ -770,11 +767,11 @@ static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info * Transform_attach_function(transform, cross_correlation_transform_function); xcross_settings = (struct _cross_correlation_settings *)malloc(sizeof(struct _cross_correlation_settings)); Transform_attach_settings(transform, xcross_settings); - ch_info = ch1->extra_field; + ch_info = iio_channel_get_data(ch1); ch_info->shadow_of_enabled++; - ch_info = ch2->extra_field; + ch_info = iio_channel_get_data(ch2); ch_info->shadow_of_enabled++; - ch_info = ch3->extra_field; + ch_info = iio_channel_get_data(ch3); ch_info->shadow_of_enabled++; break; default: @@ -784,6 +781,7 @@ static Transform* add_transform_to_list(OscPlot *plot, struct iio_channel_info * TrList_add_transform(list, transform); update_transform_settings(plot, transform, csettings); + priv->current_device = dev_info; return transform; } @@ -791,12 +789,12 @@ static void remove_transform_from_list(OscPlot *plot, Transform *tr) { OscPlotPrivate *priv = plot->priv; TrList *list = priv->transform_list; - struct extra_info *ch_info = tr->channel_parent->extra_field; + struct extra_info *ch_info = iio_channel_get_data(tr->channel_parent); ch_info->shadow_of_enabled--; if (tr->type_id == CONSTELLATION_TRANSFORM || tr->type_id == COMPLEX_FFT_TRANSFORM) { - ch_info = tr->channel_parent2->extra_field; + ch_info = iio_channel_get_data(tr->channel_parent2); ch_info->shadow_of_enabled--; } if (tr->has_the_marker) @@ -861,15 +859,18 @@ static void collect_parameters_from_plot(OscPlot *plot) OscPlotPrivate *priv = plot->priv; struct plot_params *prms; GSList *list; - int i; + unsigned int i; for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *info = iio_device_get_data(dev); + prms = malloc(sizeof(struct plot_params)); prms->plot_id = priv->object_id; prms->sample_count = plot_sample_count_get(plot); - list = device_list[i].plots_sample_counts; + list = info->plots_sample_counts; list = g_slist_prepend(list, prms); - device_list[i].plots_sample_counts = list; + info->plots_sample_counts = list; } } @@ -877,13 +878,15 @@ static void dispose_parameters_from_plot(OscPlot *plot) { OscPlotPrivate *priv = plot->priv; struct plot_params *prms; - GSList *list; GSList *node; GSList *del_link = NULL; - int i; + unsigned int i; for (i = 0; i < num_devices; i++) { - list = device_list[i].plots_sample_counts; + struct iio_device *dev = iio_context_get_device(ctx, i); + struct extra_dev_info *info = iio_device_get_data(dev); + GSList *list = info->plots_sample_counts; + for (node = list; node; node = g_slist_next(node)) { prms = node->data; if (prms->plot_id == priv->object_id) { @@ -893,7 +896,7 @@ static void dispose_parameters_from_plot(OscPlot *plot) } if (del_link) { list = g_slist_delete_link(list, del_link); - device_list[i].plots_sample_counts = list; + info->plots_sample_counts = list; } } } @@ -901,7 +904,8 @@ static void dispose_parameters_from_plot(OscPlot *plot) static void draw_marker_values(OscPlotPrivate *priv, Transform *tr) { struct _fft_settings *settings = tr->settings; - struct extra_info *ch_info; + struct extra_info *ch_info = iio_channel_get_data(tr->channel_parent); + struct extra_dev_info *dev_info = iio_device_get_data(ch_info->dev); struct marker_type *markers = settings->markers; GtkTextIter iter; char text[256]; @@ -911,12 +915,11 @@ static void draw_marker_values(OscPlotPrivate *priv, Transform *tr) priv->tbuf = gtk_text_buffer_new(NULL); gtk_text_view_set_buffer(GTK_TEXT_VIEW(priv->marker_label), priv->tbuf); } - ch_info = tr->channel_parent->extra_field; if (MAX_MARKERS && priv->marker_type != MARKER_OFF) { for (m = 0; m <= MAX_MARKERS && markers[m].active; m++) { - sprintf(text, "M%i: %2.2f dBFS @ %2.3f %sHz%c", - m, markers[m].y, ch_info->device_parent->lo_freq + markers[m].x, - ch_info->device_parent->adc_scale, + sprintf(text, "M%i: %2.2f dBFS @ %2.3f %cHz%c", + m, markers[m].y, dev_info->lo_freq + markers[m].x, + dev_info->adc_scale, m != MAX_MARKERS ? '\n' : '\0'); if (m == 0) { @@ -948,26 +951,25 @@ static void call_all_transform_functions(OscPlotPrivate *priv) } } -static int enabled_channels_of_device(GtkTreeView *treeview, const char *dev_name) +static int enabled_channels_of_device(GtkTreeView *treeview, const char *name) { GtkTreeIter iter; GtkTreeIter child_iter; - GtkTreeModel *model; - gboolean next_iter; gboolean next_child_iter; char *str_device; gboolean enabled; int num_enabled = 0; - model = gtk_tree_view_get_model(treeview); - if (!gtk_tree_model_get_iter_first(model, &iter)) - return 0; - - next_iter = true; + GtkTreeModel *model = gtk_tree_view_get_model(treeview); + gboolean next_iter = gtk_tree_model_get_iter_first(model, &iter); while (next_iter) { - gtk_tree_model_iter_children(model, &child_iter, &iter); + if (!gtk_tree_model_iter_children(model, &child_iter, &iter)) { + next_iter = gtk_tree_model_iter_next(model, &iter); + continue; + } + gtk_tree_model_get(model, &iter, ELEMENT_NAME, &str_device, -1); - if (!strcmp(dev_name, str_device)) { + if (!strcmp(name, str_device)) { next_child_iter = true; while (next_child_iter) { gtk_tree_model_get(model, &child_iter, CHANNEL_ACTIVE, &enabled, -1); @@ -977,7 +979,6 @@ static int enabled_channels_of_device(GtkTreeView *treeview, const char *dev_nam } } next_iter = gtk_tree_model_iter_next(model, &iter); - g_free(str_device); } return num_enabled; @@ -1002,16 +1003,17 @@ static void channels_transform_assignment(GtkTreeModel *model, gtk_tree_model_get(model, iter, ELEMENT_REFERENCE, &ch_ref, CHANNEL_ACTIVE, &enabled, CHANNEL_SETTINGS, &settings, -1); + if (!enabled) + return; switch (prm->plot_type) { case TIME_PLOT: - if (enabled) - add_transform_to_list(prm->plot, ch_ref, NULL, NULL, NULL, TIME_TRANSFORM, settings); + add_transform_to_list(prm->plot, ch_ref, NULL, NULL, NULL, TIME_TRANSFORM, settings); break; case FFT_PLOT: - if (prm->enabled_channels == 1 && enabled) { + if (prm->enabled_channels == 1) { add_transform_to_list(prm->plot, ch_ref, NULL, NULL, NULL, FFT_TRANSFORM, settings); - } else if (prm->enabled_channels == 2 && enabled) { + } else if (prm->enabled_channels == 2) { if (!prm->ch_pair_ref) prm->ch_pair_ref = ch_ref; else @@ -1019,7 +1021,7 @@ static void channels_transform_assignment(GtkTreeModel *model, } break; case XY_PLOT: - if (prm->enabled_channels == 2 && enabled) { + if (prm->enabled_channels == 2) { if (!prm->ch_pair_ref) prm->ch_pair_ref = ch_ref; else @@ -1050,7 +1052,7 @@ static void devices_transform_assignment(OscPlot *plot) GtkTreeModel *model; struct params prm; - int i; + unsigned int i; treeview = GTK_TREE_VIEW(priv->channel_list_view); model = gtk_tree_view_get_model(treeview); @@ -1063,10 +1065,13 @@ static void devices_transform_assignment(OscPlot *plot) prm.ch_pair_ref = NULL; prm.ch_3rd_ref = NULL; prm.ch_4th_ref = NULL; - for (i = 0; i < num_devices; i++){ - prm.enabled_channels = enabled_channels_of_device(treeview, device_list[i].device_name); + + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + const char *name = iio_device_get_name(dev) ?: iio_device_get_id(dev); + prm.enabled_channels = enabled_channels_of_device(treeview, name); foreach_channel_iter_of_device(GTK_TREE_VIEW(priv->channel_list_view), - &device_list[i], *channels_transform_assignment, &prm); + name, *channels_transform_assignment, &prm); } } @@ -1132,6 +1137,7 @@ static void plot_setup(OscPlot *plot) TrList *tr_list = priv->transform_list; Transform *transform; struct extra_info *ch_info; + struct extra_dev_info *dev_info; gfloat *transform_x_axis; gfloat *transform_y_axis; int max_x_axis = 0; @@ -1159,11 +1165,13 @@ static void plot_setup(OscPlot *plot) else graph = gtk_databox_lines_new(transform->y_axis_size, transform_x_axis, transform_y_axis, transform->graph_color, priv->line_thickness); - ch_info = transform->channel_parent->extra_field; + ch_info = iio_channel_get_data(transform->channel_parent); + dev_info = iio_device_get_data(ch_info->dev); + if (transform->x_axis_size > max_x_axis) max_x_axis = transform->x_axis_size; - if (ch_info->device_parent->adc_freq > max_adc_freq) - max_adc_freq = ch_info->device_parent->adc_freq; + if (dev_info->adc_freq > max_adc_freq) + max_adc_freq = dev_info->adc_freq; if (priv->active_transform_type == FFT_TRANSFORM || priv->active_transform_type == COMPLEX_FFT_TRANSFORM) add_markers(plot, transform); @@ -1192,7 +1200,7 @@ static void capture_button_clicked_cb(GtkToggleToolButton *btn, gpointer data) button_state = gtk_toggle_tool_button_get_active(btn); - if (button_state) { + if (button_state) { gtk_widget_set_tooltip_text(GTK_WIDGET(btn), "Capture / Stop"); collect_parameters_from_plot(plot); remove_all_transforms(plot); @@ -1461,6 +1469,23 @@ static void channel_color_icon_set_color(GdkPixbuf *pb, GdkColor *color) } } +static bool show_channel(struct iio_channel *chn) +{ + const char *id = iio_channel_get_id(chn); + unsigned int i, nb_attrs = iio_channel_get_attrs_count(chn); + + if (iio_channel_is_output(chn) || !strcmp(id, "timestamp")) + return false; + + for (i = 0; i < nb_attrs; i++) { + const char *attr = iio_channel_get_attr(chn, i); + if (!strcmp(attr, "en")) + return true; + } + + return false; +} + static void device_list_treeview_init(OscPlot *plot) { OscPlotPrivate *priv = plot->priv; @@ -1471,45 +1496,58 @@ static void device_list_treeview_init(OscPlot *plot) GdkPixbuf *new_icon; GdkColor *icon_color; struct channel_settings *new_settings; - int i, j; + unsigned int i, j; treestore = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + unsigned int nb_channels = iio_device_get_channels_count(dev); + const char *name = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + gtk_tree_store_append(treestore, &iter, NULL); - gtk_tree_store_set(treestore, &iter, ELEMENT_NAME, device_list[i].device_name, - IS_DEVICE, TRUE, DEVICE_ACTIVE, !i, ELEMENT_REFERENCE, &device_list[i], SENSITIVE, true, -1); - for (j = 0; j < device_list[i].num_channels; j++) { - if (strcmp("in_timestamp", device_list[i].channel_list[j].name) != 0) { - new_settings = channel_settings_new(plot); - new_icon = channel_color_icon_new(plot); - icon_color = &new_settings->graph_color; - channel_color_icon_set_color(new_icon, icon_color); - gtk_tree_store_append(treestore, &child, &iter); - gtk_tree_store_set(treestore, &child, - ELEMENT_NAME, device_list[i].channel_list[j].name, + gtk_tree_store_set(treestore, &iter, ELEMENT_NAME, name, + IS_DEVICE, TRUE, DEVICE_ACTIVE, !i, ELEMENT_REFERENCE, + dev, SENSITIVE, true, -1); + + for (j = 0; j < nb_channels; j++) { + struct iio_channel *ch = iio_device_get_channel(dev, j); + if (!show_channel(ch)) + continue; + + name = iio_channel_get_name(ch) ?: + iio_channel_get_id(ch); + new_settings = channel_settings_new(plot); + new_icon = channel_color_icon_new(plot); + icon_color = &new_settings->graph_color; + channel_color_icon_set_color(new_icon, icon_color); + gtk_tree_store_append(treestore, &child, &iter); + gtk_tree_store_set(treestore, &child, + ELEMENT_NAME, name, IS_CHANNEL, TRUE, CHANNEL_ACTIVE, FALSE, - ELEMENT_REFERENCE, &device_list[i].channel_list[j], + ELEMENT_REFERENCE, ch, CHANNEL_SETTINGS, new_settings, CHANNEL_COLOR_ICON, new_icon, SENSITIVE, true, PLOT_TYPE, TIME_PLOT, -1); - } } } + create_channel_list_view(plot); } static void saveas_device_changed_cb(GtkComboBoxText *box, OscPlot *plot) { OscPlotPrivate *priv = plot->priv; - struct _device_list *device; - struct iio_channel_info *channel; + struct iio_device *dev; GtkWidget *parent; GtkWidget *ch_checkbtn; gchar *active_device; - int i, d; + unsigned int i, nb_channels; + int d; parent = gtk_widget_get_parent(priv->saveas_channels_list); gtk_widget_destroy(priv->saveas_channels_list); @@ -1521,11 +1559,15 @@ static void saveas_device_changed_cb(GtkComboBoxText *box, OscPlot *plot) g_free(active_device); if (d < 0) return; - device = &device_list[d]; - for (i = device->num_channels - 1; i >= 0; i--) { - channel = &device->channel_list[i]; - ch_checkbtn = gtk_check_button_new_with_label(channel->name); + dev = iio_context_get_device(ctx, d); + nb_channels = iio_device_get_channels_count(dev); + + for (i = 0; i < nb_channels; i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + const char *name = iio_channel_get_name(chn) ?: + iio_channel_get_id(chn); + ch_checkbtn = gtk_check_button_new_with_label(name); gtk_box_pack_end(GTK_BOX(priv->saveas_channels_list), ch_checkbtn, FALSE, TRUE, 0); } gtk_widget_show_all(priv->saveas_channels_list); @@ -1536,7 +1578,7 @@ static void saveas_channels_list_fill(OscPlot *plot) OscPlotPrivate *priv = plot->priv; GtkWidget *ch_window; GtkWidget *vbox; - int dev; + unsigned int i; ch_window = priv->viewport_saveas_channels; vbox = gtk_vbox_new(FALSE, 10); @@ -1546,9 +1588,13 @@ static void saveas_channels_list_fill(OscPlot *plot) priv->saveas_channels_list = gtk_vbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(vbox), priv->saveas_channels_list, FALSE, TRUE, 0); - for (dev = 0; dev < num_devices; dev++) - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(priv->device_combobox), - device_list[dev].device_name); + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + const char *name = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(priv->device_combobox), name); + } + if (!num_devices) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(priv->device_combobox), "No Devices Available"); @@ -1803,15 +1849,22 @@ static void transform_csv_print(OscPlotPrivate *priv, FILE *fp, Transform *tr) gfloat *tr_data; gfloat *tr_x_axis; int i; + struct iio_channel *ch1 = tr->channel_parent, *ch2 = tr->channel_parent2; + const char *id1 = NULL, *id2 = NULL; + + if (ch1) + id1 = iio_channel_get_name(ch1) ?: iio_channel_get_id(ch1); + if (ch2) + id2 = iio_channel_get_name(ch2) ?: iio_channel_get_id(ch2); if (tr->type_id == TIME_TRANSFORM) - fprintf(fp, "X Axis(Sample Index) Y Axis(%s)\n", tr->channel_parent->name); + fprintf(fp, "X Axis(Sample Index) Y Axis(%s)\n", id1); else if (tr->type_id == FFT_TRANSFORM) - fprintf(fp, "X Axis(Frequency) Y Axis(FFT - %s)\n", tr->channel_parent->name); + fprintf(fp, "X Axis(Frequency) Y Axis(FFT - %s)\n", id1); else if (tr->type_id == COMPLEX_FFT_TRANSFORM) - fprintf(fp, "X Axis(Frequency) Y Axis(Complex FFT - %s, %s)\n", tr->channel_parent->name, tr->channel_parent2->name); + fprintf(fp, "X Axis(Frequency) Y Axis(Complex FFT - %s, %s)\n", id1, id2); else if (tr->type_id == CONSTELLATION_TRANSFORM) - fprintf(fp, "X Axis(%s) Y Axis(%s)\n", tr->channel_parent2->name, tr->channel_parent->name); + fprintf(fp, "X Axis(%s) Y Axis(%s)\n", id2, id1); tr_x_axis = Transform_get_x_axis_ref(tr); tr_data = Transform_get_y_axis_ref(tr); @@ -1847,20 +1900,21 @@ static void copy_channel_state_to_selection_channel(GtkTreeModel *model, { OscPlot *plot = user_data; OscPlotPrivate *priv = plot->priv; - struct iio_channel_info *channel; + struct iio_channel *chn; gboolean active_state; GList *ch_checkbtns = NULL; GList *node; GtkToggleButton *btn; - int index = 0; + int ch_index, index = 0; - gtk_tree_model_get(model, iter, ELEMENT_REFERENCE, &channel, CHANNEL_ACTIVE, &active_state, -1); + gtk_tree_model_get(model, iter, ELEMENT_REFERENCE, &chn, CHANNEL_ACTIVE, &active_state, -1); + ch_index = (int) iio_channel_get_index(chn); /* Get user channel selection from GUI widgets */ ch_checkbtns = gtk_container_get_children(GTK_CONTAINER(priv->saveas_channels_list)); for (node = ch_checkbtns; node; node = g_list_next(node)) { btn = (GtkToggleButton *)node->data; - if (channel->index == index) { + if (ch_index == index) { gtk_toggle_button_set_active(btn, active_state); break; } @@ -1878,12 +1932,13 @@ static void channel_selection_set_default(OscPlot *plot) device_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(priv->device_combobox)); d = device_find_by_name(device_name); + if (d >= 0) + foreach_channel_iter_of_device(GTK_TREE_VIEW(priv->channel_list_view), + device_name, *copy_channel_state_to_selection_channel, plot); g_free(device_name); - foreach_channel_iter_of_device(GTK_TREE_VIEW(priv->channel_list_view), &device_list[d], - *copy_channel_state_to_selection_channel, plot); } -static int * get_user_saveas_channel_selection(OscPlot *plot, struct _device_list *device) +static int * get_user_saveas_channel_selection(OscPlot *plot, unsigned int nb_channels) { OscPlotPrivate *priv = plot->priv; GList *ch_checkbtns = NULL; @@ -1893,7 +1948,7 @@ static int * get_user_saveas_channel_selection(OscPlot *plot, struct _device_lis int i = 0; /* Create masks for all channels */ - mask = malloc(sizeof(int) * device->num_channels); + mask = malloc(sizeof(int) * nb_channels); /* Get user channel selection from GUI widgets */ ch_checkbtns = gtk_container_get_children(GTK_CONTAINER(priv->saveas_channels_list)); @@ -1987,8 +2042,8 @@ static void save_as(OscPlot *plot, const char *filename, int type) FILE *fp; mat_t *mat; matvar_t *matvar; - struct _device_list *device; - struct iio_channel_info *channel; + struct iio_device *dev; + struct extra_dev_info *dev_info; char tmp[100]; int dims[2] = {-1, 1}; double freq; @@ -2001,6 +2056,8 @@ static void save_as(OscPlot *plot, const char *filename, int type) gchar *active_device; int *save_channels_mask; int i, j, d; + unsigned int nb_channels; + const char *dev_name; name = malloc(strlen(filename) + 5); switch(type) { @@ -2023,10 +2080,12 @@ static void save_as(OscPlot *plot, const char *filename, int type) g_free(active_device); if (d < 0) break; - device = &device_list[d]; + dev = iio_context_get_device(ctx, d); + dev_info = iio_device_get_data(dev); + nb_channels = iio_device_get_channels_count(dev); /* Find which channel need to be saved */ - save_channels_mask = get_user_saveas_channel_selection(plot, device); + save_channels_mask = get_user_saveas_channel_selection(plot, nb_channels); /* Make a VSA file header */ fprintf(fp, "InputZoom\tTRUE\n"); @@ -2034,10 +2093,10 @@ static void save_as(OscPlot *plot, const char *filename, int type) fprintf(fp, "InputRange\t1\n"); fprintf(fp, "InputRefImped\t50\n"); fprintf(fp, "XStart\t0\n"); - if (!strcmp(device->adc_scale, "M")) - freq = device->adc_freq * 1000000; - else if (!strcmp(device->adc_scale, "k")) - freq = device->adc_freq * 1000; + if (dev_info->adc_scale == 'M') + freq = dev_info->adc_freq * 1000000; + else if (dev_info->adc_scale == 'k') + freq = dev_info->adc_freq * 1000; else { printf("error in writing\n"); break; @@ -2051,12 +2110,12 @@ static void save_as(OscPlot *plot, const char *filename, int type) fprintf(fp, "Y\n"); /* Start writing the samples */ - for (i = 0; i < device->sample_count; i++) { - for (j = 0; j < device->num_channels; j++) { - channel = &device->channel_list[j]; - if (!channel->enabled || save_channels_mask[j] == 1) + for (i = 0; i < dev_info->sample_count; i++) { + for (j = 0; j < nb_channels; j++) { + struct extra_info *info = iio_channel_get_data(iio_device_get_channel(dev, j)); + if (save_channels_mask[j] == 1) continue; - fprintf(fp, "%g\t", CHANNEL_EXTRA_FIELD(channel)->data_ref[i]); + fprintf(fp, "%g\t", info->data_ref[i]); } fprintf(fp, "\n"); } @@ -2079,18 +2138,21 @@ static void save_as(OscPlot *plot, const char *filename, int type) d = device_find_by_name(active_device); g_free(active_device); if (d < 0) - break; - device = &device_list[d]; + break; + + dev = iio_context_get_device(ctx, d); + dev_info = iio_device_get_data(dev); + nb_channels = iio_device_get_channels_count(dev); /* Find which channel need to be saved */ - save_channels_mask = get_user_saveas_channel_selection(plot, device); + save_channels_mask = get_user_saveas_channel_selection(plot, nb_channels); - for (i = 0; i < device->sample_count; i++) { - for (j = 0; j < device->num_channels; j++) { - channel = &device->channel_list[j]; - if (!channel->enabled || save_channels_mask[j] == 1) + for (i = 0; i < dev_info->sample_count; i++) { + for (j = 0; j < nb_channels; j++) { + struct extra_info *info = iio_channel_get_data(iio_device_get_channel(dev, j)); + if (save_channels_mask[j] == 1) continue; - fprintf(fp, "%g, ", CHANNEL_EXTRA_FIELD(channel)->data_ref[i]); + fprintf(fp, "%g, ", info->data_ref[i]); } fprintf(fp, "\n"); } @@ -2140,20 +2202,28 @@ static void save_as(OscPlot *plot, const char *filename, int type) d = device_find_by_name(active_device); g_free(active_device); if (d < 0) - break; - device = &device_list[d]; + break; - /* Find which channel need to be saved */ - save_channels_mask = get_user_saveas_channel_selection(plot, device); + dev = iio_context_get_device(ctx, d); + dev_info = iio_device_get_data(dev); + nb_channels = iio_device_get_channels_count(dev); + dev_name = iio_device_get_name(dev) ?: + iio_device_get_id(dev); - dims[0] = device->sample_count; - for (i = 0; i < device->num_channels; i++) { - channel = &device->channel_list[i]; - if (!channel->enabled || save_channels_mask[i] == 1) + /* Find which channel need to be saved */ + save_channels_mask = get_user_saveas_channel_selection(plot, nb_channels); + + dims[0] = dev_info->sample_count; + for (i = 0; i < nb_channels; i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + const char *ch_name = iio_channel_get_name(chn) ?: + iio_channel_get_id(chn); + struct extra_info *info = iio_channel_get_data(chn); + if (save_channels_mask[i] == 1) continue; - sprintf(tmp, "%s:%s", device->device_name, channel->name); + sprintf(tmp, "%s:%s", dev_name, ch_name); matvar = Mat_VarCreate(tmp, MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, - CHANNEL_EXTRA_FIELD(channel)->data_ref, 0); + info->data_ref, 0); if (!matvar) printf("error creating matvar on channel %s\n", tmp); else { @@ -2234,7 +2304,8 @@ static void min_y_axis_cb(GtkSpinButton *btn, OscPlot *plot) gtk_databox_set_total_limits(box, min_x, max_x, max_y, min_y); } -static gboolean get_iter_by_name(GtkTreeView *tree, GtkTreeIter *iter, char *dev_name, char *ch_name) +static gboolean get_iter_by_name(GtkTreeView *tree, GtkTreeIter *iter, + const char *dev_name, char *ch_name) { GtkTreeModel *model; GtkTreeIter dev_iter; @@ -2286,8 +2357,6 @@ static void plot_profile_save(OscPlot *plot, char *filename) GtkTreeIter ch_iter; gboolean next_dev_iter; gboolean next_ch_iter; - struct _device_list *dev; - struct iio_channel_info *ch; gboolean expanded; gboolean device_active; gboolean ch_enabled; @@ -2363,24 +2432,32 @@ static void plot_profile_save(OscPlot *plot, char *filename) next_dev_iter = gtk_tree_model_get_iter_first(model, &dev_iter); while (next_dev_iter) { + struct iio_device *dev; + const char *name; + gtk_tree_model_get(model, &dev_iter, ELEMENT_REFERENCE, &dev, DEVICE_ACTIVE, &device_active, -1); + name = iio_device_get_name(dev) ?: iio_device_get_id(dev); expanded = gtk_tree_view_row_expanded(tree, gtk_tree_model_get_path(model, &dev_iter)); - fprintf(fp, "%s.expanded=%d\n", dev->device_name, (expanded) ? 1 : 0); - fprintf(fp, "%s.active=%d\n", dev->device_name, (device_active) ? 1 : 0); + fprintf(fp, "%s.expanded=%d\n", name, (expanded) ? 1 : 0); + fprintf(fp, "%s.active=%d\n", name, (device_active) ? 1 : 0); next_ch_iter = gtk_tree_model_iter_children(model, &ch_iter, &dev_iter); + while (next_ch_iter) { + struct iio_channel *ch; + const char *ch_name; gtk_tree_model_get(model, &ch_iter, ELEMENT_REFERENCE, &ch, CHANNEL_ACTIVE, &ch_enabled, CHANNEL_SETTINGS, &csettings, -1); - fprintf(fp, "%s.%s.enabled=%d\n", dev->device_name, ch->name, (ch_enabled) ? 1 : 0); - fprintf(fp, "%s.%s.color_red=%d\n", dev->device_name, ch->name, csettings->graph_color.red); - fprintf(fp, "%s.%s.color_green=%d\n", dev->device_name, ch->name, csettings->graph_color.green); - fprintf(fp, "%s.%s.color_blue=%d\n", dev->device_name, ch->name, csettings->graph_color.blue); - fprintf(fp, "%s.%s.math_apply_inverse_funct=%d\n", dev->device_name, ch->name, csettings->apply_inverse_funct); - fprintf(fp, "%s.%s.math_apply_multiply_funct=%d\n", dev->device_name, ch->name, csettings->apply_multiply_funct); - fprintf(fp, "%s.%s.math_apply_add_funct=%d\n", dev->device_name, ch->name, csettings->apply_add_funct); - fprintf(fp, "%s.%s.math_multiply_value=%f\n", dev->device_name, ch->name, csettings->multiply_value); - fprintf(fp, "%s.%s.math_add_value=%f\n", dev->device_name, ch->name, csettings->add_value); + ch_name = iio_channel_get_name(ch) ?: iio_channel_get_id(ch); + fprintf(fp, "%s.%s.enabled=%d\n", name, ch_name, (ch_enabled) ? 1 : 0); + fprintf(fp, "%s.%s.color_red=%d\n", name, ch_name, csettings->graph_color.red); + fprintf(fp, "%s.%s.color_green=%d\n", name, ch_name, csettings->graph_color.green); + fprintf(fp, "%s.%s.color_blue=%d\n", name, ch_name, csettings->graph_color.blue); + fprintf(fp, "%s.%s.math_apply_inverse_funct=%d\n", name, ch_name, csettings->apply_inverse_funct); + fprintf(fp, "%s.%s.math_apply_multiply_funct=%d\n", name, ch_name, csettings->apply_multiply_funct); + fprintf(fp, "%s.%s.math_apply_add_funct=%d\n", name, ch_name, csettings->apply_add_funct); + fprintf(fp, "%s.%s.math_multiply_value=%f\n", name, ch_name, csettings->multiply_value); + fprintf(fp, "%s.%s.math_add_value=%f\n", name, ch_name, csettings->add_value); next_ch_iter = gtk_tree_model_iter_next(model, &ch_iter); } next_dev_iter = gtk_tree_model_iter_next(model, &dev_iter); @@ -2439,23 +2516,30 @@ static int comboboxtext_set_active_by_string(GtkComboBox *combo_box, const char static int device_find_by_name(const char *name) { - int i; + unsigned int i; - for (i = 0; i < num_devices; i++) - if (strcmp(device_list[i].device_name, name) == 0) + for (i = 0; i < num_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); + const char *id = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + if (!strcmp(id, name)) return i; - + } return -1; } static int channel_find_by_name(int device_index, const char *name) { - int i; + struct iio_device *dev = iio_context_get_device(ctx, device_index); + unsigned int i, nb_channels = iio_device_get_channels_count(dev); - for (i = 0; i < device_list[device_index].num_channels; i++) - if (strcmp(device_list[device_index].channel_list[i].name, name) == 0) + for (i = 0; i < nb_channels; i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + const char *id = iio_channel_get_name(chn) ?: + iio_channel_get_id(chn); + if (!strcmp(id, name)) return i; - + } return -1; } @@ -2586,9 +2670,13 @@ static int cfg_read_handler(void *user, const char* section, const char* name, c return 0; for (i = 0; i < num_devices; i++) { - if (!strcmp(device_list[i].device_name, "cf-ad9643-core-lpc") || - !strcmp(device_list[i].device_name, "cf-ad9361-lpc")) - fprintf(fd, "%f", device_list[i].lo_freq); + struct iio_device *dev = iio_context_get_device(ctx, i); + const char *id = iio_device_get_name(dev) ?: + iio_device_get_id(dev); + if (!strcmp(id, "cf-ad9643-core-lpc") || !strcmp(id, "cf-ad9361-lpc")) { + struct extra_dev_info *info = iio_device_get_data(dev); + fprintf(fd, "%lf", info->lo_freq); + } } for (i = 0; i <= MAX_MARKERS; i++) { diff --git a/oscplot.h b/oscplot.h index 96c00091c..43020020e 100644 --- a/oscplot.h +++ b/oscplot.h @@ -47,7 +47,7 @@ void osc_plot_draw_stop (OscPlot *plot); void osc_plot_save_to_ini (OscPlot *plot, char *filename); int osc_plot_ini_read_handler (OscPlot *plot, const char *section, const char *name, const char *value); void osc_plot_save_as (OscPlot *plot, char *filename, int type); -char * osc_plot_get_active_device(OscPlot *plot); +const char * osc_plot_get_active_device(OscPlot *plot); int osc_plot_get_fft_avg (OscPlot *plot); int osc_plot_get_marker_type (OscPlot *plot); void osc_plot_set_marker_type (OscPlot *plot, int mtype); diff --git a/plugins/fmcomms2.c b/plugins/fmcomms2.c index e277a3c5d..398663790 100644 --- a/plugins/fmcomms2.c +++ b/plugins/fmcomms2.c @@ -21,6 +21,7 @@ #include #include +#include "../datatypes.h" #include "../osc.h" #include "../iio_widget.h" #include "../iio_utils.h" @@ -1148,20 +1149,29 @@ static void manage_dds_mode() * Return 1 if the channel combination is valid * Return 0 if the combination is not valid */ -int channel_combination_check(struct iio_channel_info *channels, int ch_count, char **ch_names) +int channel_combination_check(struct iio_device *dev, const char **ch_names) { bool consecutive_ch = FALSE; - int i, k = 0; + unsigned int i, k, nb_channels = iio_device_get_channels_count(dev); + struct extra_info *prev_info = NULL; - for (i = 0; i < ch_count; i++) - if (channels[i].enabled) { - ch_names[k++] = channels[i].name; - if (i > 0) - if (channels[i - 1].enabled) { + for (i = 0, k = 0; i < nb_channels; i++) { + struct iio_channel *ch = iio_device_get_channel(dev, i); + struct extra_info *info = iio_channel_get_data(ch); + + if (info->may_be_enabled) { + const char *name = iio_channel_get_name(ch) ?: iio_channel_get_id(ch); + ch_names[k++] = name; + + if (i > 0) { + struct extra_info *prev = iio_channel_get_data(iio_device_get_channel(dev, i - 1)); + if (prev->may_be_enabled) { consecutive_ch = TRUE; break; } + } } + } if (!consecutive_ch) return 0;