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 size_t write_fru(char *eeprom) { gint result; const char *serial, *file; char *ser_num, *filename; time_t frutime; FILE *fp = NULL; size_t i; time_t tmp; struct tm *tmp2; char buf[256]; int j, n; struct dirent **namelist; GtkListStore *store; n = scandir(FRU_FILES, &namelist, 0, alphasort); /* No fru files, don't bother */ if (n < 0) { printf("didn't find FRU_Files in %s at %s(%s)\n", FRU_FILES, __FILE__, __func__); return 0; } g_object_set(dialogs.serial_num, "secondary_text", eeprom, NULL); filename = g_malloc(PATH_MAX); ser_num = malloc(128); memset(ser_num, 0, 128); fp = fopen(".serialnum", "r"); if (fp) { i = fread(ser_num, 1, 128, fp); if (!ferror(fp) && (i == 128 || feof(fp))) gtk_entry_set_text(GTK_ENTRY(serial_num), (const gchar*)&ser_num[1]); fclose(fp); } store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(fru_file_list))); gtk_list_store_clear(store); for (j = 0; j < n; j++) { if (namelist[j]->d_type == DT_REG && str_endswith(namelist[j]->d_name, ".bin")) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fru_file_list), namelist[j]->d_name); free(namelist[j]); } free(namelist); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fru_file_list), "Other..."); gtk_combo_box_set_active(GTK_COMBO_BOX(fru_file_list), ser_num[0]); free(ser_num); frutime = mins_since_jan_1_1996(); tmp = min2date(frutime); tmp2 = gmtime(&tmp); strftime(buf, sizeof(buf), "%a %b %d %H:%M %Y", tmp2); gtk_entry_set_text(GTK_ENTRY(fru_date), buf); get_serial_and_file: result = gtk_dialog_run(GTK_DIALOG(dialogs.serial_num)); i = 0; switch (result) { case GTK_RESPONSE_OK: serial = gtk_entry_get_text(GTK_ENTRY(serial_num)); if (strlen(serial) == 0) { create_blocking_popup(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "", "Serial number required"); goto get_serial_and_file; } file = gtk_combo_box_get_active_text(GTK_COMBO_BOX(fru_file_list)); if (strncmp(file, "Other...", 8) != 0) { snprintf(filename, PATH_MAX, FRU_FILES "%s", file); } else { /* manually choose fru file */ GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new("Select FRU file", GTK_WINDOW(dialogs.serial_num), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); } gtk_widget_destroy(dialog); } if (filename) { fflush(NULL); sprintf(buf, "fru-dump -i %s -o %s -s %s -d %d 2>&1", filename, eeprom, serial, (unsigned int)frutime); #if DEBUG printf("%s\n", buf); #else fp = popen(buf, "r"); #endif if (!fp) { printf("can't execute \"%s\"\n", buf); } else { i = 0; while(fgets(buf, sizeof(buf), fp) != NULL) { /* fru-dump not installed */ if (strstr(buf, "not found")) printf("no fru-tools installed\n"); if (strstr(buf, "wrote") && strstr(buf, "bytes to") && strstr(buf, eeprom)) i = 1; } pclose(fp); } fp = fopen(".serialnum", "w"); if (fp) { fprintf(fp, "%c%s", gtk_combo_box_get_active(GTK_COMBO_BOX(fru_file_list)), serial); fclose(fp); } } break; case GTK_RESPONSE_DELETE_EVENT: break; default: printf("unknown response %d in %s\n", result, __func__); break; } gtk_widget_hide(GTK_WIDGET(dialogs.serial_num)); g_free(filename); return i; }
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); }
G_MODULE_EXPORT void save_as(const char *filename, int type) { FILE *fp; unsigned int i, j; double freq, k; mat_t *mat; matvar_t *matvar; int dims[2]; char tmp[20]; GdkPixbuf *pixbuf; GError *err=NULL; GdkColormap *cmap; gint width, height; gboolean ret = true; char *name; gdouble *tmp_data; name = malloc(strlen(filename) + 5); switch(type) { /* Response Codes encoded in glade file */ case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_CANCEL: break; case SAVE_VSA: /* Allow saving data when only in Time Domanin */ if ((gtk_combo_box_get_active(GTK_COMBO_BOX(plot_domain)) != TIME_PLOT) && (gtk_combo_box_get_active(GTK_COMBO_BOX(plot_domain)) != XY_PLOT)) { create_blocking_popup(GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "Invalid Plot Type", "Please make sure to set the Plot Type to \"Time Domanin\" before saving data."); return; } /* Save as Agilent VSA formatted file */ if (!strncasecmp(&filename[strlen(filename)-4], ".txt", 4)) strcpy(name, filename); else sprintf(name, "%s.txt", filename); fp = fopen(name, "w"); if (!fp) break; fprintf(fp, "InputZoom\tTRUE\n"); fprintf(fp, "InputCenter\t0\n"); fprintf(fp, "InputRange\t1\n"); fprintf(fp, "InputRefImped\t50\n"); fprintf(fp, "XStart\t0\n"); if (!strcmp(adc_scale, "M")) freq = adc_freq * 1000000; else if (!strcmp(adc_scale, "k")) freq = adc_freq * 1000; else { printf("error in writing\n"); break; } fprintf(fp, "XDelta\t%-.17f\n", 1.0/freq); fprintf(fp, "XDomain\t2\n"); fprintf(fp, "XUnit\tSec\n"); fprintf(fp, "YUnit\tV\n"); fprintf(fp, "FreqValidMax\t%e\n", freq / 2); fprintf(fp, "FreqValidMin\t-%e\n", freq / 2); fprintf(fp, "Y\n"); for (j = 0; j < num_samples; j++) { for (i = 0; i < num_active_channels ; i++) { fprintf(fp, "%g", channel_data[i][j]); if (i < (num_active_channels - 1)) fprintf(fp, "\t"); } fprintf(fp, "\n"); } fprintf(fp, "\n"); fclose(fp); break; case SAVE_MAT: /* Allow saving data when only in Time Domanin */ if (gtk_combo_box_get_active(GTK_COMBO_BOX(plot_domain)) != TIME_PLOT) { create_blocking_popup(GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "Invalid Plot Type", "Please make sure to set the Plot Type to \"Time Domanin\" before saving data."); return; } /* Matlab file * http://na-wiki.csc.kth.se/mediawiki/index.php/MatIO */ if (!strncasecmp(&filename[strlen(filename)-4], ".mat", 4)) strcpy(name, filename); else sprintf(name, "%s.mat", filename); dims[1] = 1; dims[0] = num_samples; mat = Mat_Open(name, MAT_ACC_RDWR); if(mat) { for (i = 0; i < num_active_channels; i++) { sprintf(tmp, "in_voltage%d", i); if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(save_mat_scale))) { matvar = Mat_VarCreate(tmp, MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, channel_data[i], 0); } else { tmp_data = g_new(gdouble, num_samples); if (channels[i].is_signed) k = channels[i].bits_used - 1; else k = channels[i].bits_used; for (j = 0; j < num_samples; j++) { tmp_data[j] = (gdouble)channel_data[i][j] / (pow(2.0, k)); } matvar = Mat_VarCreate(tmp, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, tmp_data, 0); g_free(tmp_data); } if (!matvar) printf("error creating matvar on channel %i\n", i); else { Mat_VarWrite(mat, matvar, 0); Mat_VarFree(matvar); } } Mat_Close(mat); } break; case SAVE_CSV: /* Allow saving data when only in Time Domanin */ if (gtk_combo_box_get_active(GTK_COMBO_BOX(plot_domain)) != TIME_PLOT) { create_blocking_popup(GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "Invalid Plot Type", "Please make sure to set the Plot Type to \"Time Domanin\" before saving data."); return; } /* save comma seperated valus (csv) */ if (!strncasecmp(&filename[strlen(filename)-4], ".csv", 4)) strcpy(name, filename); else sprintf(name, "%s.csv", filename); fp = fopen(name, "w"); if (!fp) break; for (j = 0; j < num_samples; j++) { for (i = 0; i < num_active_channels ; i++) { fprintf(fp, "%g", channel_data[i][j]); if (i < (num_active_channels - 1)) fprintf(fp, ", "); } fprintf(fp, "\n"); } fprintf(fp, "\n"); fclose(fp); break; case SAVE_PNG: /* save_png */ if (!strncasecmp(&filename[strlen(filename)-4], ".png", 4)) strcpy(name, filename); else sprintf(name, "%s.png", filename); cmap = gdk_window_get_colormap( GDK_DRAWABLE(gtk_widget_get_window(capture_graph))); gdk_drawable_get_size(GDK_DRAWABLE(gtk_widget_get_window(capture_graph)), &width, &height); pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(gtk_widget_get_window(capture_graph)), cmap, 0, 0, 0, 0, width, height); if (pixbuf) ret = gdk_pixbuf_save(pixbuf, name, "png", &err, NULL); if (!pixbuf || !ret) printf("error creating %s\n", name); break; default: printf("ret : %i\n", ret); } free(name); }