static void mcs_cb (GtkWidget *widget, gpointer data) { unsigned step; struct iio_channel *tx_sample_master, *tx_sample_slave; long long tx_sample_master_freq, tx_sample_slave_freq; char temp[40], ensm_mode[40]; unsigned tmp; static int fix_slave_tune = 1; tx_sample_master = iio_device_find_channel(dev, "voltage0", true); tx_sample_slave = iio_device_find_channel(dev_slave, "voltage0", true); iio_channel_attr_read_longlong(tx_sample_master, "sampling_frequency", &tx_sample_master_freq); iio_channel_attr_read_longlong(tx_sample_slave, "sampling_frequency", &tx_sample_slave_freq); if (tx_sample_master_freq != tx_sample_slave_freq) { printf("tx_sample_master_freq != tx_sample_slave_freq\nUpdating...\n"); iio_channel_attr_write_longlong(tx_sample_slave, "sampling_frequency", tx_sample_master_freq); } if (fix_slave_tune) { iio_device_reg_read(dev, 0x6, &tmp); iio_device_reg_write(dev_slave, 0x6, tmp); iio_device_reg_read(dev, 0x7, &tmp); iio_device_reg_write(dev_slave, 0x7, tmp); fix_slave_tune = 0; } iio_device_attr_read(dev, "ensm_mode", ensm_mode, sizeof(ensm_mode)); /* Move the parts int ALERT for MCS */ iio_device_attr_write(dev, "ensm_mode", "alert"); iio_device_attr_write(dev_slave, "ensm_mode", "alert"); for (step = 1; step <= 5; step++) { sprintf(temp, "%d", step); /* Don't change the order here - the master controls the SYNC GPIO */ iio_device_debug_attr_write(dev_slave, "multichip_sync", temp); iio_device_debug_attr_write(dev, "multichip_sync", temp); sleep(0.1); } iio_device_attr_write(dev, "ensm_mode", ensm_mode); iio_device_attr_write(dev_slave, "ensm_mode", ensm_mode); #if 0 iio_device_debug_attr_write(dev, "multichip_sync", "6"); iio_device_debug_attr_write(dev_slave, "multichip_sync", "6"); #endif }
static void calibrate (gpointer button) { GtkProgressBar *calib_progress; double rx_phase_lpc, rx_phase_hpc, tx_phase_hpc; long long cal_tone, cal_freq; int ret, samples; if (!cf_ad9361_lpc || !cf_ad9361_hpc) { printf("could not find capture cores\n"); ret = -ENODEV; auto_calibrate = -1; goto calibrate_fail; } if (!dev_dds_master || !dev_dds_slave) { printf("could not find dds cores\n"); ret = -ENODEV; auto_calibrate = -1; goto calibrate_fail; } calib_progress = GTK_PROGRESS_BAR(gtk_builder_get_object(builder, "progress_calibration")); set_calibration_progress(calib_progress, 0.00); mcs_cb(NULL, NULL); /* * set some logical defaults / assumptions */ ret = default_dds(get_cal_tone(), CAL_SCALE); if (ret < 0) { printf("could not set dds cores\n"); auto_calibrate = -1; goto calibrate_fail; } iio_channel_attr_read_longlong(dds_out[0][0], "frequency", &cal_tone); iio_channel_attr_read_longlong(dds_out[0][0], "sampling_frequency", &cal_freq); samples = get_cal_samples(cal_tone, cal_freq); DBG("cal_tone %u cal_freq %u samples %d", cal_tone, cal_freq, samples); gdk_threads_enter(); osc_plot_set_sample_count(plot_xcorr_4ch, samples); osc_plot_draw_start(plot_xcorr_4ch); gdk_threads_leave(); iio_device_attr_write(dev, "in_voltage_quadrature_tracking_en", "0"); iio_device_attr_write(dev_slave, "in_voltage_quadrature_tracking_en", "0"); trx_phase_rotation(cf_ad9361_lpc, 0.0); trx_phase_rotation(cf_ad9361_hpc, 0.0); set_calibration_progress(calib_progress, 0.16); /* * Calibrate RX: * 1 TX1B_B (HPC) -> RX1C_B (HPC) : BIST_LOOPBACK on A */ osc_plot_xcorr_revert(plot_xcorr_4ch, true); __cal_switch_ports_enable_cb(1); rx_phase_hpc = tune_trx_phase_offset(cf_ad9361_hpc, &ret, cal_freq, cal_tone, 1.0, 0.01, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase\n"); auto_calibrate = -1; goto calibrate_fail; } set_calibration_progress(calib_progress, 0.40); DBG("rx_phase_hpc %f", rx_phase_hpc); /* * Calibrate RX: * 3 TX1B_B (HPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B */ osc_plot_xcorr_revert(plot_xcorr_4ch, false); trx_phase_rotation(cf_ad9361_hpc, 0.0); __cal_switch_ports_enable_cb(3); rx_phase_lpc = tune_trx_phase_offset(cf_ad9361_lpc, &ret, cal_freq, cal_tone, 1.0, 0.01, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase\n"); auto_calibrate = -1; goto calibrate_fail; } set_calibration_progress(calib_progress, 0.64); DBG("rx_phase_lpc %f", rx_phase_lpc); /* * Calibrate TX: * 4 TX1B_A (LPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B */ osc_plot_xcorr_revert(plot_xcorr_4ch, false); trx_phase_rotation(cf_ad9361_hpc, 0.0); __cal_switch_ports_enable_cb(4); tx_phase_hpc = tune_trx_phase_offset(dev_dds_slave, &ret, cal_freq, cal_tone, -1.0 , 0.001, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase\n"); auto_calibrate = -1; goto calibrate_fail; } set_calibration_progress(calib_progress, 0.88); DBG("tx_phase_hpc %f", tx_phase_hpc); trx_phase_rotation(cf_ad9361_hpc, rx_phase_hpc); gtk_range_set_value(GTK_RANGE(GTK_WIDGET(gtk_builder_get_object(builder, "tx_phase"))), scale_phase_0_360(tx_phase_hpc)); ret = 0; set_calibration_progress(calib_progress, 1.0); calibrate_fail: osc_plot_xcorr_revert(plot_xcorr_4ch, false); __cal_switch_ports_enable_cb(0); iio_device_attr_write(dev, "in_voltage_quadrature_tracking_en", "1"); iio_device_attr_write(dev_slave, "in_voltage_quadrature_tracking_en", "1"); gdk_threads_enter(); reload_settings(); create_blocking_popup(GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "FMCOMMS5", "Calibration finished %s", ret ? "with Error" : "Successfully"); auto_calibrate = 1; osc_plot_destroy(plot_xcorr_4ch); if (button) gtk_widget_show(GTK_WIDGET(button)); gdk_threads_leave(); g_thread_exit(NULL); }
static GtkWidget * daq2_init(GtkWidget *notebook, const char *ini_fn) { GtkBuilder *builder; GtkWidget *daq2_panel; GtkWidget *dds_container; GtkTextBuffer *adc_buff, *dac_buff; struct iio_channel *ch0, *ch1; ctx = osc_create_context(); if (!ctx) return NULL; dac = iio_context_find_device(ctx, DAC_DEVICE); adc = iio_context_find_device(ctx, ADC_DEVICE); dac_tx_manager = dac_data_manager_new(dac, NULL, ctx); if (!dac_tx_manager) { osc_destroy_context(ctx); return NULL; } builder = gtk_builder_new(); if (!gtk_builder_add_from_file(builder, "daq2.glade", NULL)) gtk_builder_add_from_file(builder, OSC_GLADE_FILE_PATH "daq2.glade", NULL); daq2_panel = GTK_WIDGET(gtk_builder_get_object(builder, "daq2_panel")); 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); if (ini_fn) load_profile(ini_fn); /* Bind the IIO device files to the GUI widgets */ char attr_val[256]; long long val; double tx_sampling_freq; /* Rx Widgets */ ch0 = iio_device_find_channel(adc, "voltage0", false); ch1 = iio_device_find_channel(adc, "voltage1", false); if (iio_channel_attr_read_longlong(ch0, "sampling_frequency", &val) == 0) snprintf(attr_val, sizeof(attr_val), "%.2f", (double)(val / 1000000ul)); else snprintf(attr_val, sizeof(attr_val), "%s", "error"); adc_buff = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(adc_buff, attr_val, -1); gtk_text_view_set_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(builder, "text_view_adc_freq")), adc_buff); iio_combo_box_init_from_builder(&rx_widgets[num_rx++], adc, ch0, "test_mode", "test_mode_available", builder, "ch0_test_mode", NULL); iio_combo_box_init_from_builder(&rx_widgets[num_rx++], adc, ch1, "test_mode", "test_mode_available", builder, "ch1_test_mode", NULL); /* Tx Widgets */ ch0 = iio_device_find_channel(dac, "altvoltage0", true); if (iio_channel_attr_read_longlong(ch0, "sampling_frequency", &val) == 0) { tx_sampling_freq = (double)(val / 1000000ul); snprintf(attr_val, sizeof(attr_val), "%.2f", tx_sampling_freq); } else { snprintf(attr_val, sizeof(attr_val), "%s", "error"); tx_sampling_freq = 0; } dac_buff = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(dac_buff, attr_val, -1); gtk_text_view_set_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(builder, "text_view_dac_freq")), dac_buff); make_widget_update_signal_based(rx_widgets, num_rx); make_widget_update_signal_based(tx_widgets, num_tx); dac_data_manager_freq_widgets_range_update(dac_tx_manager, tx_sampling_freq / 2); tx_update_values(); rx_update_values(); dac_data_manager_update_iio_widgets(dac_tx_manager); dac_data_manager_set_buffer_chooser_current_folder(dac_tx_manager, OSC_WAVEFORM_FILE_PATH); block_diagram_init(builder, 4, "AD9680_11752-001.svg", "AD9144_11675-002.svg", "AD9523_09278-020.svg", "AD-FMCDAQ2-EBZ.jpg"); can_update_widgets = true; return daq2_panel; }
static void calibrate (gpointer button) { GtkProgressBar *calib_progress = NULL; double rx_phase_lpc, rx_phase_hpc, tx_phase_hpc; struct iio_channel *in0, *in0_slave; long long cal_tone, cal_freq; int ret, samples; in0 = iio_device_find_channel(dev, "voltage0", false); in0_slave = iio_device_find_channel(dev_slave, "voltage0", false); if (!in0 || !in0_slave) { printf("could not find channels\n"); ret = -ENODEV; goto calibrate_fail; } if (!cf_ad9361_lpc || !cf_ad9361_hpc) { printf("could not find capture cores\n"); ret = -ENODEV; goto calibrate_fail; } if (!dev_dds_master || !dev_dds_slave) { printf("could not find dds cores\n"); ret = -ENODEV; goto calibrate_fail; } calib_progress = GTK_PROGRESS_BAR(gtk_builder_get_object(builder, "progress_calibration")); set_calibration_progress(calib_progress, 0.00); mcs_cb(NULL, NULL); /* * set some logical defaults / assumptions */ ret = default_dds(get_cal_tone(), CAL_SCALE); if (ret < 0) { printf("could not set dds cores\n"); goto calibrate_fail; } iio_channel_attr_read_longlong(dds_out[0][0], "frequency", &cal_tone); iio_channel_attr_read_longlong(dds_out[0][0], "sampling_frequency", &cal_freq); samples = get_cal_samples(cal_tone, cal_freq); DBG("cal_tone %lld cal_freq %lld samples %d", cal_tone, cal_freq, samples); gdk_threads_enter(); osc_plot_set_sample_count(plot_xcorr_4ch, samples); osc_plot_draw_start(plot_xcorr_4ch); gdk_threads_leave(); /* Turn off quadrature tracking while the sync is going on */ iio_channel_attr_write(in0, "quadrature_tracking_en", "0"); iio_channel_attr_write(in0_slave, "quadrature_tracking_en", "0"); /* reset any Tx rotation to zero */ trx_phase_rotation(cf_ad9361_lpc, 0.0); trx_phase_rotation(cf_ad9361_hpc, 0.0); set_calibration_progress(calib_progress, 0.16); /* * Calibrate RX: * 1 TX1B_B (HPC) -> RX1C_B (HPC) : BIST_LOOPBACK on A */ osc_plot_xcorr_revert(plot_xcorr_4ch, true); __cal_switch_ports_enable_cb(1); rx_phase_hpc = tune_trx_phase_offset(cf_ad9361_hpc, &ret, cal_freq, cal_tone, 1.0, 0.01, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase : %s:%i\n", __func__, __LINE__); goto calibrate_fail; } set_calibration_progress(calib_progress, 0.40); DBG("rx_phase_hpc %f", rx_phase_hpc); /* * Calibrate RX: * 3 TX1B_B (HPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B */ osc_plot_xcorr_revert(plot_xcorr_4ch, false); trx_phase_rotation(cf_ad9361_hpc, 0.0); __cal_switch_ports_enable_cb(3); rx_phase_lpc = tune_trx_phase_offset(cf_ad9361_lpc, &ret, cal_freq, cal_tone, 1.0, 0.01, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase : %s:%i\n", __func__, __LINE__); goto calibrate_fail; } set_calibration_progress(calib_progress, 0.64); (void) rx_phase_lpc; /* Avoid compiler warnings */ DBG("rx_phase_lpc %f", rx_phase_lpc); /* * Calibrate TX: * 4 TX1B_A (LPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B */ osc_plot_xcorr_revert(plot_xcorr_4ch, false); trx_phase_rotation(cf_ad9361_hpc, 0.0); __cal_switch_ports_enable_cb(4); tx_phase_hpc = tune_trx_phase_offset(dev_dds_slave, &ret, cal_freq, cal_tone, -1.0 , 0.001, trx_phase_rotation); if (ret < 0) { printf("Failed to tune phase : %s:%i\n", __func__, __LINE__); goto calibrate_fail; } set_calibration_progress(calib_progress, 0.88); DBG("tx_phase_hpc %f", tx_phase_hpc); trx_phase_rotation(cf_ad9361_hpc, rx_phase_hpc); gtk_range_set_value(GTK_RANGE(GTK_WIDGET(gtk_builder_get_object(builder, "tx_phase"))), scale_phase_0_360(tx_phase_hpc)); ret = 0; set_calibration_progress(calib_progress, 1.0); calibrate_fail: osc_plot_xcorr_revert(plot_xcorr_4ch, false); __cal_switch_ports_enable_cb(0); if (in0 && in0_slave) { iio_channel_attr_write(in0, "quadrature_tracking_en", "1"); iio_channel_attr_write(in0_slave, "quadrature_tracking_en", "1"); } gdk_threads_enter(); reload_settings(); if (ret) { create_blocking_popup(GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "FMCOMMS5", "Calibration failed"); auto_calibrate = -1; } else { /* set completed flag for testing */ auto_calibrate = 1; } osc_plot_destroy(plot_xcorr_4ch); if (button) gtk_widget_show(GTK_WIDGET(button)); gdk_threads_leave(); /* reset progress bar */ gtk_progress_bar_set_fraction(calib_progress, 0.0); gtk_progress_bar_set_text(calib_progress, "Calibration Progress"); /* Disable the channels that were enabled at the beginning of the calibration */ struct iio_device *iio_dev; iio_dev = iio_context_find_device(get_context_from_osc(), CAP_DEVICE_ALT); if (iio_dev && cap_device_channels_enabled) { iio_channels_change_shadow_of_enabled(iio_dev, false); cap_device_channels_enabled = false; } g_thread_exit(NULL); }
int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate) { struct iio_channel *chan; long long current_rate; int dec, taps, ret, i, enable, len = 0; int16_t *fir; char *buf; if (rate <= 20000000UL) { dec = 4; taps = 128; fir = fir_128_4; } else if (rate <= 40000000UL) { dec = 2; fir = fir_128_2; taps = 128; } else if (rate <= 53333333UL) { dec = 2; fir = fir_96_2; taps = 96; } else { dec = 2; fir = fir_64_2; taps = 64; } chan = iio_device_find_channel(dev, "voltage0", true); if (chan == NULL) return -ENODEV; ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", ¤t_rate); if (ret < 0) return ret; ret = ad9361_get_trx_fir_enable(dev, &enable); if (ret < 0) return ret; if (enable) { if (current_rate <= (25000000 / 12)) iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000); ret = ad9361_set_trx_fir_enable(dev, false); if (ret < 0) return ret; } buf = malloc(FIR_BUF_SIZE); if (!buf) return -ENOMEM; len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN -6 DEC %d\n", dec); len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN 0 INT %d\n", dec); for (i = 0; i < taps; i++) len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", fir[i], fir[i]); len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n"); ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len); free (buf); if (ret < 0) return ret; if (rate <= (25000000 / 12)) { ret = ad9361_set_trx_fir_enable(dev, true); if (ret < 0) return ret; ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate); if (ret < 0) return ret; } else { ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate); if (ret < 0) return ret; ret = ad9361_set_trx_fir_enable(dev, true); if (ret < 0) return ret; } return 0; }