static int write_each_attr(struct iio_device *dev, bool is_debug, ssize_t (*cb)(struct iio_device *dev, const char *attr, void *buf, size_t len, void *d), void *data) { char *buf, *ptr; unsigned int i, count; size_t len = 0x100000; int ret; /* We need a big buffer here; 1 MiB should be enough */ buf = malloc(len); if (!buf) return -ENOMEM; ptr = buf; if (is_debug) count = iio_device_get_debug_attrs_count(dev); else count = iio_device_get_attrs_count(dev); for (i = 0; i < count; i++) { const char *attr; if (is_debug) attr = iio_device_get_debug_attr(dev, i); else attr = iio_device_get_attr(dev, i); ret = (int) cb(dev, attr, ptr + 4, len - 4, data); if (ret < 0) goto err_free_buf; *(int32_t *) ptr = (int32_t) htonl((uint32_t) ret); ptr += 4; len -= 4; if (ret > 0) { if (ret & 0x3) ret = ((ret >> 2) + 1) << 2; ptr += ret; len -= ret; } } if (is_debug) ret = (int) iio_device_debug_attr_write_raw(dev, NULL, buf, ptr - buf); else ret = (int) iio_device_attr_write_raw(dev, NULL, buf, ptr - buf); err_free_buf: free(buf); return ret < 0 ? ret : 0; }
static int load_fir_filter(const char *file_name) { bool rx = false, tx = false; int ret = -1; FILE *f = fopen(file_name, "r"); if (f) { char *buf; ssize_t len; char line[80]; while (fgets(line, 80, f) != NULL && line[0] == '#'); if (!strncmp(line, "RX", strlen("RX"))) rx = true; else if (!strncmp(line, "TX", strlen("TX"))) tx = true; if (fgets(line, 80, f) != NULL) { if (!strncmp(line, "TX", strlen("TX"))) tx = true; else if (!strncmp(line, "RX", strlen("RX"))) rx = true; } fseek(f, 0, SEEK_END); len = ftell(f); buf = malloc(len); fseek(f, 0, SEEK_SET); len = fread(buf, 1, len, f); fclose(f); ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len); free(buf); } if (ret < 0) { fprintf(stderr, "FIR filter config failed\n"); GtkWidget *toplevel = gtk_widget_get_toplevel(fmcomms2_panel); if (!gtk_widget_is_toplevel(toplevel)) toplevel = NULL; GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(toplevel), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "\nFailed to configure the FIR filter using the selected file."); gtk_window_set_title(GTK_WINDOW(dialog), "FIR Filter Configuration Failed"); if (gtk_dialog_run(GTK_DIALOG(dialog))) gtk_widget_destroy(dialog); } else { strcpy(last_fir_filter, file_name); gtk_widget_hide(fir_filter_en_tx); gtk_widget_hide(enable_fir_filter_rx); gtk_widget_hide(enable_fir_filter_rx_tx); gtk_widget_show(disable_all_fir_filters); if (rx && tx) gtk_widget_show(enable_fir_filter_rx_tx); else if (rx) gtk_widget_show(enable_fir_filter_rx); else if (tx) gtk_widget_show(fir_filter_en_tx); else gtk_widget_hide(disable_all_fir_filters); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON (disable_all_fir_filters), true); } return ret; }
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; }
ssize_t iio_device_attr_write(const struct iio_device *dev, const char *attr, const char *src) { return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1); }