Beispiel #1
0
void iioc_dev_close(struct iio_device *dev)
{
	unsigned int j;
	struct extra_dev_info *dev_info = iio_device_get_data(dev);
	if (!dev_info)
		return;

	unsigned int nb_channels = iio_device_get_channels_count(dev);

	for (j = 0; j < nb_channels; j++) {
		struct iio_channel *ch = iio_device_get_channel(dev, j);
		struct extra_chn_info *chn_info = iio_channel_get_data(ch);
		if (chn_info->data_ref) {
			free(chn_info->data_ref);
			chn_info->data_ref = NULL;
		}
		if (chn_info) {
			free(chn_info);
			chn_info = NULL;
		}
	}
	if (dev_info->buffer) {
		iio_buffer_destroy(dev_info->buffer);
		dev_info->buffer = NULL;
		dev_info->buffer_size = 0;
	}
	free(dev_info);
	dev_info = NULL;
}
Beispiel #2
0
int iioc_sampling_capture(struct iio_device *adc_dev)
{
	unsigned int i;
	off_t offset = 0;
	assert(adc_dev);
	struct extra_dev_info *dev_info = iio_device_get_data(adc_dev);
	ssize_t sample_count = dev_info->sample_count;
	unsigned int nb_channels = dev_info->nb_channels;

	if (dev_info->buffer == NULL) {
		dev_info->buffer_size = sample_count;
		dev_info->buffer = iio_device_create_buffer(adc_dev,
		                   sample_count, false);
		if (!dev_info->buffer) {
			IIOC_DBG("Error: Unable to create buffer: %s\n", strerror(errno));
			return -errno;
		}
	}

	/* Reset the data offset for all channels */
	for (i = 0; i < nb_channels; i++) {
		struct iio_channel *ch = iio_device_get_channel(adc_dev, i);
		struct extra_chn_info *chn_info = iio_channel_get_data(ch);
		chn_info->offset = 0;
	}
	IIOC_DBG("Enter buffer refill loop.\n");
	while (true) {
		ssize_t ret = iio_buffer_refill(dev_info->buffer);
		if (ret < 0) {
			IIOC_DBG("Error while reading data: %s\n", strerror(-ret));
			return ret;
		}
		else {
			IIOC_DBG("Read %d bytes from buffer.\n", ret);
		}

		ret /= iio_buffer_step(dev_info->buffer);
		if (ret >= sample_count) {
			iio_buffer_foreach_sample(
			    dev_info->buffer, demux_sample, NULL);

			if (ret >= sample_count * 2) {
				printf("Decreasing buffer size\n");
				iio_buffer_destroy(dev_info->buffer);
				dev_info->buffer_size /= 2;
				dev_info->buffer = iio_device_create_buffer(adc_dev,
				                   dev_info->buffer_size, false);
			}
			break;
		}

		printf("Increasing buffer size\n");
		iio_buffer_destroy(dev_info->buffer);
		dev_info->buffer_size *= 2;
		dev_info->buffer = iio_device_create_buffer(adc_dev,
		                   dev_info->buffer_size, false);
	}

	return 0;
}
Beispiel #3
0
static ssize_t demux_sample(const struct iio_channel *chn,
                            void *sample, size_t size, void *d)
{
	struct extra_chn_info *chn_info = iio_channel_get_data(chn);
	struct extra_dev_info *dev_info = iio_device_get_data(chn_info->dev);
	const struct iio_data_format *format = iio_channel_get_data_format(chn);

	/* Prevent buffer overflow */
	if ((unsigned long)chn_info->offset == (unsigned long)dev_info->sample_count)
		return 0;

	if (size == 1) {
		int8_t val;
		iio_channel_convert(chn, &val, sample);
		if (format->is_signed)
			*(chn_info->data_ref + chn_info->offset++) = (int8_t)val;
		else
			*(chn_info->data_ref + chn_info->offset++) = (uint8_t)val;
	}
	else if (size == 2) {
		int16_t val;
		iio_channel_convert(chn, &val, sample);
		if (format->is_signed)
			*(chn_info->data_ref + chn_info->offset++) = (int16_t)val;
		else
			*(chn_info->data_ref + chn_info->offset++) = (uint16_t)val;
	}
	else {
		int32_t val;
		iio_channel_convert(chn, &val, sample);
		if (format->is_signed)
			*(chn_info->data_ref + chn_info->offset++) = (int32_t)val;
		else
			*(chn_info->data_ref + chn_info->offset++) = (uint32_t)val;
	}

	return size;
}
Beispiel #4
0
int iioc_sampling_setup(struct iio_device *adc_dev,
                        struct iio_device *trigger_dev,
                        unsigned int sampling_freq,
                        unsigned int sample_count
                       )
{
	unsigned int i;
	int ret;
	unsigned int min_timeout = 2000;
	if (!adc_dev || !trigger_dev)
		return -ENODEV;
	unsigned int nb_channels = iio_device_get_channels_count(adc_dev);
	if (nb_channels == 0) {
		IIOC_DBG("There is 0 Channel in adc_device.\n");
		return -EIO;
	}
	unsigned int sample_size = iio_device_get_sample_size(adc_dev);
	if (sample_size == 0) {
		IIOC_DBG("Sample Size is 0.\n");
		return -ENODATA;
	}
	struct extra_dev_info *dev_info = iio_device_get_data(adc_dev);
	if (dev_info->input_device == false) {
		IIOC_DBG("adc_dev is not an input device.\n");
		return -EIO;
	}
	//°ó¶¨trigger
	ret = iio_device_set_trigger(adc_dev, trigger_dev);
	if (ret)
	{
#ifdef _DEBUG
		const char *trigger_name = iio_device_get_name(trigger_dev);
		const char *adc_name = iio_device_get_name(adc_dev);
		IIOC_DBG("Can not bind the %s with %s.\n", trigger_name, adc_name);
#endif
		return -EIO;
	}
	//ɾ³ý¾Ébuffer
	if (dev_info->buffer)
		iio_buffer_destroy(dev_info->buffer);
	dev_info->buffer = NULL;

	//ÉèÖÃsample_count(buffer´óС)
	dev_info->sample_count = sample_count;
	//ʹÄÜͨµÀ£¬²¢ÎªÃ¿¸öͨµÀ·ÖÅäÄÚ´æ¿Õ¼ä
	for (i = 0; i < nb_channels; i++) {
		struct iio_channel *ch = iio_device_get_channel(adc_dev, i);
		struct extra_chn_info *chn_info = iio_channel_get_data(ch);
		if (chn_info->enabled)
			iio_channel_enable(ch);
		else
			iio_channel_disable(ch);

		if (chn_info->data_ref)
			free(chn_info->data_ref);
		chn_info->data_ref = (int16_t *)calloc(dev_info->sample_count, sizeof(int16_t));
		if (!chn_info->data_ref) {
			IIOC_DBG("Can not calloc channel data mem.\n");
			goto error_calloc_chn_data_ref;
		}
	}
	dev_info->sampling_freq = sampling_freq;
	//ÖØаó¶¨Êý¾Ý
	iio_device_set_data(adc_dev, dev_info);
	//ÉèÖó¬Ê±
	if (sampling_freq > 0) {
		/* 2 x capture time + 2s */
		unsigned int timeout = dev_info->sample_count * 1000 / sampling_freq;
		timeout += 2000;
		if (timeout > min_timeout)
			min_timeout = timeout;
	}
	if (dev_info->ctx_info->ctx)
		iio_context_set_timeout(dev_info->ctx_info->ctx, min_timeout);

	return 0;
error_calloc_chn_data_ref:
	for (i = 0; i < nb_channels; i++) {
		struct iio_channel *ch = iio_device_get_channel(adc_dev, i);
		struct extra_chn_info *chn_info = iio_channel_get_data(ch);
		if (chn_info->data_ref)
			free(chn_info->data_ref);
	}
	return -ENOMEM;
}
static GtkWidget * fmcomms2_init(GtkWidget *notebook, const char *ini_fn)
{
	GtkBuilder *builder;
	GtkWidget *dds_container;
	struct iio_channel *ch0, *ch1;

	can_update_widgets = false;

	ctx = osc_create_context();
	if (!ctx)
		return NULL;

	dev = iio_context_find_device(ctx, PHY_DEVICE);
	dds = iio_context_find_device(ctx, DDS_DEVICE);
	cap = iio_context_find_device(ctx, CAP_DEVICE);
	udc_rx = iio_context_find_device(ctx, UDC_RX_DEVICE);
	udc_tx = iio_context_find_device(ctx, UDC_TX_DEVICE);
	has_udc_driver = (udc_rx && udc_tx);

	ch0 = iio_device_find_channel(dev, "voltage0", false);
	ch1 = iio_device_find_channel(dev, "voltage1", false);

	dac_tx_manager = dac_data_manager_new(dds, NULL, ctx);
	if (!dac_tx_manager) {
		iio_context_destroy(ctx);
		return NULL;
	}

	const char *env_freq_span = getenv("OSC_UPDN_FREQ_SPAN");
	const char *env_freq_mix_sign = getenv("OSC_UPDN_FREQ_MIX_SIGN");

	if(!env_freq_span) {
		updn_freq_span = 2;
	} else {
		errno = 0;
		updn_freq_span = g_strtod(env_freq_span, NULL);
		if (errno)
			updn_freq_span = 2;
	}

	if(!env_freq_mix_sign) {
		updn_freq_mix_sign = 1;
	} else {
		if (!strncmp(env_freq_mix_sign, "-", 1))
			updn_freq_mix_sign = -1;
		else
			updn_freq_mix_sign = 1;
	}

	builder = gtk_builder_new();
	nbook = GTK_NOTEBOOK(notebook);

	if (!gtk_builder_add_from_file(builder, "fmcomms2.glade", NULL))
		gtk_builder_add_from_file(builder, OSC_GLADE_FILE_PATH "fmcomms2.glade", NULL);

	is_2rx_2tx = ch1 && iio_channel_find_attr(ch1, "hardwaregain");

	fmcomms2_panel = GTK_WIDGET(gtk_builder_get_object(builder, "fmcomms2_panel"));

	/* Global settings */

	ensm_mode = GTK_WIDGET(gtk_builder_get_object(builder, "ensm_mode"));
	ensm_mode_available = GTK_WIDGET(gtk_builder_get_object(builder, "ensm_mode_available"));
	calib_mode = GTK_WIDGET(gtk_builder_get_object(builder, "calib_mode"));
	calib_mode_available = GTK_WIDGET(gtk_builder_get_object(builder, "calib_mode_available"));
	trx_rate_governor = GTK_WIDGET(gtk_builder_get_object(builder, "trx_rate_governor"));
	trx_rate_governor_available = GTK_WIDGET(gtk_builder_get_object(builder, "trx_rate_governor_available"));
	tx_path_rates = GTK_WIDGET(gtk_builder_get_object(builder, "label_tx_path"));
	rx_path_rates = GTK_WIDGET(gtk_builder_get_object(builder, "label_rx_path"));
	filter_fir_config = GTK_WIDGET(gtk_builder_get_object(builder, "filter_fir_config"));
	enable_fir_filter_rx = GTK_WIDGET(gtk_builder_get_object(builder, "enable_fir_filter_rx"));
	fir_filter_en_tx = GTK_WIDGET(gtk_builder_get_object(builder, "fir_filter_en_tx"));
	enable_fir_filter_rx_tx = GTK_WIDGET(gtk_builder_get_object(builder, "enable_fir_filter_tx_rx"));
	disable_all_fir_filters = GTK_WIDGET(gtk_builder_get_object(builder, "disable_all_fir_filters"));
	up_down_converter = GTK_WIDGET(gtk_builder_get_object(builder, "checkbox_up_down_converter"));

	section_toggle[SECTION_GLOBAL] = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "global_settings_toggle"));
	section_setting[SECTION_GLOBAL] = GTK_WIDGET(gtk_builder_get_object(builder, "global_settings"));
	section_toggle[SECTION_TX] = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "tx_toggle"));
	section_setting[SECTION_TX] = GTK_WIDGET(gtk_builder_get_object(builder, "tx_settings"));
	section_toggle[SECTION_RX] = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "rx_toggle"));
	section_setting[SECTION_RX] = GTK_WIDGET(gtk_builder_get_object(builder, "rx_settings"));
	section_toggle[SECTION_FPGA] = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "fpga_toggle"));
	section_setting[SECTION_FPGA] = GTK_WIDGET(gtk_builder_get_object(builder, "fpga_settings"));

	/* Receive Chain */

	rf_port_select_rx = GTK_WIDGET(gtk_builder_get_object(builder, "rf_port_select_rx"));
	rx_gain_control_rx1 = GTK_WIDGET(gtk_builder_get_object(builder, "gain_control_mode_rx1"));
	rx_gain_control_rx2 = GTK_WIDGET(gtk_builder_get_object(builder, "gain_control_mode_rx2"));
	rx_gain_control_modes_rx1 = GTK_WIDGET(gtk_builder_get_object(builder, "gain_control_mode_available_rx1"));
	rx_gain_control_modes_rx2 = GTK_WIDGET(gtk_builder_get_object(builder, "gain_control_mode_available_rx2"));
	rx1_rssi = GTK_WIDGET(gtk_builder_get_object(builder, "rssi_rx1"));
	rx2_rssi = GTK_WIDGET(gtk_builder_get_object(builder, "rssi_rx2"));
	rx_fastlock_profile = GTK_WIDGET(gtk_builder_get_object(builder, "rx_fastlock_profile"));

	/* Transmit Chain */

	rf_port_select_tx = GTK_WIDGET(gtk_builder_get_object(builder, "rf_port_select_tx"));
	tx_fastlock_profile = GTK_WIDGET(gtk_builder_get_object(builder, "tx_fastlock_profile"));
	tx1_rssi = GTK_WIDGET(gtk_builder_get_object(builder, "rssi_tx1"));
	tx2_rssi = GTK_WIDGET(gtk_builder_get_object(builder, "rssi_tx2"));
	dds_container = GTK_WIDGET(gtk_builder_get_object(builder, "dds_transmit_block"));
	gtk_container_add(GTK_CONTAINER(dds_container), dac_data_manager_get_gui_container(dac_tx_manager));
	gtk_widget_show_all(dds_container);

	rx_phase_rotation[0] = GTK_WIDGET(gtk_builder_get_object(builder, "rx1_phase_rotation"));
	rx_phase_rotation[1] = GTK_WIDGET(gtk_builder_get_object(builder, "rx2_phase_rotation"));

	gtk_combo_box_set_active(GTK_COMBO_BOX(ensm_mode_available), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(trx_rate_governor_available), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(rx_gain_control_modes_rx1), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(rx_gain_control_modes_rx2), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(rf_port_select_rx), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(rf_port_select_tx), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(rx_fastlock_profile), 0);
	gtk_combo_box_set_active(GTK_COMBO_BOX(tx_fastlock_profile), 0);

	/* Set FMCOMMS2/3 max sampling freq -> 61.44MHz and FMCOMMS4 -> 122.88 */
	GtkWidget *sfreq = GTK_WIDGET(gtk_builder_get_object(builder, "sampling_freq_tx"));
	GtkAdjustment *sfreq_adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(sfreq));

	if (is_2rx_2tx)
		gtk_adjustment_set_upper(sfreq_adj, 61.44);
	else
		gtk_adjustment_set_upper(sfreq_adj, 122.88);

	/* Bind the IIO device files to the GUI widgets */

	glb_widgets = widgets;

	/* Global settings */
	iio_combo_box_init(&glb_widgets[num_glb++],
		dev, NULL, "ensm_mode", "ensm_mode_available",
		ensm_mode_available, NULL);
	iio_combo_box_init(&glb_widgets[num_glb++],
		dev, NULL, "calib_mode", "calib_mode_available",
		calib_mode_available, NULL);
	iio_combo_box_init(&glb_widgets[num_glb++],
		dev, NULL, "trx_rate_governor", "trx_rate_governor_available",
		trx_rate_governor_available, NULL);

	dcxo_coarse_num = num_glb;
	iio_spin_button_int_init_from_builder(&glb_widgets[num_glb++],
		dev, NULL, "dcxo_tune_coarse", builder, "dcxo_coarse_tune",
		0);
	dcxo_fine_num = num_glb;
	iio_spin_button_int_init_from_builder(&glb_widgets[num_glb++],
		dev, NULL, "dcxo_tune_fine", builder, "dcxo_fine_tune",
		0);

	rx_widgets = &glb_widgets[num_glb];

	/* Receive Chain */

	iio_combo_box_init(&rx_widgets[num_rx++],
		dev, ch0, "gain_control_mode",
		"gain_control_mode_available",
		rx_gain_control_modes_rx1, NULL);

	iio_combo_box_init(&rx_widgets[num_rx++],
		dev, ch0, "rf_port_select",
		"rf_port_select_available",
		rf_port_select_rx, NULL);

	if (is_2rx_2tx)
		iio_combo_box_init(&rx_widgets[num_rx++],
			dev, ch1, "gain_control_mode",
			"gain_control_mode_available",
			rx_gain_control_modes_rx2, NULL);
	rx1_gain = num_rx;
	iio_spin_button_int_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "hardwaregain", builder,
		"hardware_gain_rx1", NULL);

	if (is_2rx_2tx) {
		rx2_gain = num_rx;
		iio_spin_button_int_init_from_builder(&rx_widgets[num_rx++],
			dev, ch1, "hardwaregain", builder,
			"hardware_gain_rx2", NULL);
	}
	rx_sample_freq = num_rx;
	iio_spin_button_int_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "sampling_frequency", builder,
		"sampling_freq_rx", &mhz_scale);
	iio_spin_button_add_progress(&rx_widgets[num_rx - 1]);

	iio_spin_button_int_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "rf_bandwidth", builder, "rf_bandwidth_rx",
		&mhz_scale);
	iio_spin_button_add_progress(&rx_widgets[num_rx - 1]);
	rx_lo = num_rx;

	ch1 = iio_device_find_channel(dev, "altvoltage0", true);
	if (iio_channel_find_attr(ch1, "frequency"))
		freq_name = "frequency";
	else
		freq_name = "RX_LO_frequency";
	iio_spin_button_s64_init_from_builder(&rx_widgets[num_rx++],
		dev, ch1, freq_name, builder,
		"rx_lo_freq", &mhz_scale);
	iio_spin_button_add_progress(&rx_widgets[num_rx - 1]);

	iio_toggle_button_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "quadrature_tracking_en", builder,
		"quad", 0);
	iio_toggle_button_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "rf_dc_offset_tracking_en", builder,
		"rfdc", 0);
	iio_toggle_button_init_from_builder(&rx_widgets[num_rx++],
		dev, ch0, "bb_dc_offset_tracking_en", builder,
		"bbdc", 0);

	iio_spin_button_init_from_builder(&rx_widgets[num_rx],
		dev, ch1, "calibphase",
		builder, "rx1_phase_rotation", NULL);
	iio_spin_button_add_progress(&rx_widgets[num_rx++]);

	ch0 = iio_device_find_channel(dev, "altvoltage0", true);

	if (iio_channel_find_attr(ch0, "fastlock_store"))
		rx_fastlock_store_name = "fastlock_store";
	else
		rx_fastlock_store_name = "RX_LO_fastlock_store";
	if (iio_channel_find_attr(ch0, "fastlock_recall"))
		rx_fastlock_recall_name = "fastlock_recall";
	else
		rx_fastlock_recall_name = "RX_LO_fastlock_recall";

	/* Transmit Chain */

	tx_widgets = &rx_widgets[num_rx];

	ch0 = iio_device_find_channel(dev, "voltage0", true);
	if (is_2rx_2tx)
		ch1 = iio_device_find_channel(dev, "voltage1", true);

	tx_rssi_available = ch0 && iio_channel_find_attr(ch0, "rssi");
	if (is_2rx_2tx)
		tx_rssi_available = tx_rssi_available &&
				(ch1 && iio_channel_find_attr(ch1, "rssi"));

	iio_combo_box_init(&tx_widgets[num_tx++],
		dev, ch0, "rf_port_select",
		"rf_port_select_available",
		rf_port_select_tx, NULL);

	iio_spin_button_init_from_builder(&tx_widgets[num_tx++],
		dev, ch0, "hardwaregain", builder,
		"hardware_gain_tx1", &inv_scale);

	if (is_2rx_2tx)
		iio_spin_button_init_from_builder(&tx_widgets[num_tx++],
			dev, ch1, "hardwaregain", builder,
			"hardware_gain_tx2", &inv_scale);
	tx_sample_freq = num_tx;
	iio_spin_button_int_init_from_builder(&tx_widgets[num_tx++],
		dev, ch0, "sampling_frequency", builder,
		"sampling_freq_tx", &mhz_scale);
	iio_spin_button_add_progress(&tx_widgets[num_tx - 1]);
	iio_spin_button_int_init_from_builder(&tx_widgets[num_tx++],
		dev, ch0, "rf_bandwidth", builder,
		"rf_bandwidth_tx", &mhz_scale);
	iio_spin_button_add_progress(&tx_widgets[num_tx - 1]);

	tx_lo = num_tx;
	ch1 = iio_device_find_channel(dev, "altvoltage1", true);

	if (iio_channel_find_attr(ch1, "frequency"))
		freq_name = "frequency";
	else
		freq_name = "TX_LO_frequency";
	iio_spin_button_s64_init_from_builder(&tx_widgets[num_tx++],
		dev, ch1, freq_name, builder, "tx_lo_freq", &mhz_scale);
	iio_spin_button_add_progress(&tx_widgets[num_tx - 1]);

	ch1 = iio_device_find_channel(dev, "altvoltage1", true);

	if (ini_fn)
		load_profile(ini_fn);

	/* Update all widgets with current values */
	printf("Updating widgets...\n");
	update_widgets();
	rx_freq_info_update();
	printf("Updating FIR filter...\n");
	filter_fir_update();
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(disable_all_fir_filters), true);
	glb_settings_update_labels();
	rssi_update_labels();
	dac_data_manager_freq_widgets_range_update(dac_tx_manager,
		get_gui_tx_sampling_freq() / 2.0);
	dac_data_manager_update_iio_widgets(dac_tx_manager);

	/* Widgets bindings */
	g_builder_bind_property(builder, "rssi_tx1", "visible",
		"label_rssi_tx1", "sensitive", G_BINDING_DEFAULT);
	g_builder_bind_property(builder, "rssi_tx2", "visible",
		"label_rssi_tx2", "sensitive", G_BINDING_DEFAULT);

	/* Connect signals */

	if (iio_channel_find_attr(ch1, "fastlock_store"))
		tx_fastlock_store_name = "fastlock_store";
	else
		tx_fastlock_store_name = "TX_LO_fastlock_store";
	if (iio_channel_find_attr(ch1, "fastlock_recall"))
		tx_fastlock_recall_name = "fastlock_recall";
	else
		tx_fastlock_recall_name = "TX_LO_fastlock_recall";

	g_builder_connect_signal(builder, "rx1_phase_rotation", "value-changed",
			G_CALLBACK(rx_phase_rotation_set), (gpointer *)0);

	g_builder_connect_signal(builder, "rx2_phase_rotation", "value-changed",
			G_CALLBACK(rx_phase_rotation_set), (gpointer *)2);

	g_builder_connect_signal(builder, "sampling_freq_tx", "value-changed",
			G_CALLBACK(tx_sample_rate_changed), NULL);

	g_builder_connect_signal(builder, "fmcomms2_settings_reload", "clicked",
		G_CALLBACK(reload_button_clicked), NULL);

	g_builder_connect_signal(builder, "filter_fir_config", "file-set",
		G_CALLBACK(filter_fir_config_file_set_cb), NULL);

	g_builder_connect_signal(builder, "rx_fastlock_store", "clicked",
		G_CALLBACK(fastlock_clicked), (gpointer) 1);
	g_builder_connect_signal(builder, "tx_fastlock_store", "clicked",
		G_CALLBACK(fastlock_clicked), (gpointer) 2);
	g_builder_connect_signal(builder, "rx_fastlock_recall", "clicked",
		G_CALLBACK(fastlock_clicked), (gpointer) 3);
	g_builder_connect_signal(builder, "tx_fastlock_recall", "clicked",
		G_CALLBACK(fastlock_clicked), (gpointer) 4);

	g_signal_connect_after(section_toggle[SECTION_GLOBAL], "clicked",
		G_CALLBACK(hide_section_cb), section_setting[SECTION_GLOBAL]);

	g_signal_connect_after(section_toggle[SECTION_TX], "clicked",
		G_CALLBACK(hide_section_cb), section_setting[SECTION_TX]);

	g_signal_connect_after(section_toggle[SECTION_RX], "clicked",
		G_CALLBACK(hide_section_cb), section_setting[SECTION_RX]);

	g_signal_connect_after(section_toggle[SECTION_FPGA], "clicked",
		G_CALLBACK(hide_section_cb), section_setting[SECTION_FPGA]);

	g_signal_connect_after(ensm_mode_available, "changed",
		G_CALLBACK(glb_settings_update_labels), NULL);

	g_signal_connect_after(calib_mode_available, "changed",
		G_CALLBACK(glb_settings_update_labels), NULL);

	g_signal_connect_after(trx_rate_governor_available, "changed",
		G_CALLBACK(glb_settings_update_labels), NULL);

	g_signal_connect_after(rx_gain_control_modes_rx1, "changed",
		G_CALLBACK(glb_settings_update_labels), NULL);
	g_signal_connect_after(rx_gain_control_modes_rx2, "changed",
		G_CALLBACK(glb_settings_update_labels), NULL);

	if (tx_rssi_available)
		g_signal_connect(rf_port_select_rx, "changed",
			G_CALLBACK(rf_port_select_rx_changed_cb), NULL);

	g_signal_connect_after(enable_fir_filter_rx, "toggled",
		G_CALLBACK(filter_fir_enable), NULL);
	g_signal_connect_after(fir_filter_en_tx, "toggled",
		G_CALLBACK(filter_fir_enable), NULL);
	g_signal_connect_after(enable_fir_filter_rx_tx, "toggled",
		G_CALLBACK(filter_fir_enable), NULL);
	g_signal_connect_after(disable_all_fir_filters, "toggled",
		G_CALLBACK(filter_fir_enable), NULL);

	g_signal_connect(up_down_converter, "toggled",
		G_CALLBACK(up_down_converter_toggled_cb), NULL);

	make_widget_update_signal_based(glb_widgets, num_glb);
	make_widget_update_signal_based(rx_widgets, num_rx);
	make_widget_update_signal_based(tx_widgets, num_tx);

	iio_spin_button_set_on_complete_function(&rx_widgets[rx_sample_freq],
		sample_frequency_changed_cb, NULL);
	iio_spin_button_set_on_complete_function(&tx_widgets[tx_sample_freq],
		sample_frequency_changed_cb, NULL);
	iio_spin_button_set_on_complete_function(&rx_widgets[rx_lo],
		sample_frequency_changed_cb, NULL);
	iio_spin_button_set_on_complete_function(&tx_widgets[tx_lo],
		sample_frequency_changed_cb, NULL);

	add_ch_setup_check_fct("cf-ad9361-lpc", channel_combination_check);

	struct iio_device *adc_dev;
	struct extra_dev_info *adc_info;

	adc_dev = iio_context_find_device(get_context_from_osc(), CAP_DEVICE);
	if (adc_dev) {
		adc_info = iio_device_get_data(adc_dev);
		if (adc_info)
			adc_info->plugin_fft_corr = 20 * log10(1/sqrt(HANNING_ENBW));
	}

	block_diagram_init(builder, 2, "fmcomms2.svg", "AD_FMCOMM2S2_RevC.jpg");

	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(filter_fir_config), OSC_FILTER_FILE_PATH);
	dac_data_manager_set_buffer_chooser_current_folder(dac_tx_manager, OSC_WAVEFORM_FILE_PATH);

	if (!is_2rx_2tx) {
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "frame_rx2")));
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "frame_fpga_rx2")));
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "table_hw_gain_tx2")));
	}
	if (!tx_rssi_available) {
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "rssi_tx1")));
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "rssi_tx2")));
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "label_rssi_tx1")));
		gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(builder, "label_rssi_tx2")));
	}
	gtk_widget_set_visible(up_down_converter, has_udc_driver);

	g_timeout_add(1000, (GSourceFunc) update_display, ctx);
	can_update_widgets = true;

	return fmcomms2_panel;
}