static void init_device_list(void) { unsigned int i, num = iio_context_get_devices_count(ctx); GtkTreeIter iter; gtk_list_store_clear(device_list_store); for (i = 0; i < num; i++) { struct iio_device *dev = iio_context_get_device(ctx, i); unsigned int j, nch = iio_device_get_channels_count(dev); const char *id; bool found_valid_chan = false; for (j = 0; !found_valid_chan && j < nch; j++) { struct iio_channel *chn = iio_device_get_channel(dev, j); found_valid_chan = is_valid_dmm_channel(chn); } if (!found_valid_chan) continue; id = iio_device_get_name(dev); if (!id) id = iio_device_get_id(dev); gtk_list_store_append(device_list_store, &iter); gtk_list_store_set(device_list_store, &iter, 0, id, 1, 0, -1); } gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(GTK_TREE_MODEL(device_list_store)), 0, GTK_SORT_ASCENDING); }
static ssize_t update_from_ini_chn_cb(struct iio_channel *chn, const char *attr, void *buf, size_t len, void *d) { struct load_store_params *params = (struct load_store_params *) d; const char *dev_name = iio_device_get_name(params->dev); size_t name_len = dev_name ? strlen(dev_name) : 0; bool is_hardwaregain = !strncmp(attr, "hardwaregain", len); attr = iio_channel_attr_get_filename(chn, attr); if (attr_in_whitelist(attr, dev_name, name_len, false, params->whitelist, params->list_len)) { ssize_t ret = read_from_ini(params, dev_name, name_len, attr, buf, len); /* Dirty workaround that strips the "dB" suffix of * hardwaregain value. Fix me when possible. */ if (is_hardwaregain) { char *tmp = strstr((char *) buf, " dB"); if (tmp) *tmp = '\0'; } return ret; } return 0; }
static void rx_phase_rotation(struct iio_device *dev, gdouble val) { struct iio_channel *out0, *out1; gdouble phase; unsigned offset; DBG("%s %f\n", iio_device_get_name(dev), val); phase = val * 2 * M_PI / 360.0; /* Set both RX1 and RX2 */ for (offset = 0; offset <= 2; offset += 2) { if (offset == 2) { out0 = iio_device_find_channel(dev, "voltage2", false); out1 = iio_device_find_channel(dev, "voltage3", false); } else { out0 = iio_device_find_channel(dev, "voltage0", false); out1 = iio_device_find_channel(dev, "voltage1", false); } if (out1 && out0) { iio_channel_attr_write_double(out0, "calibscale", (double) cos(phase)); iio_channel_attr_write_double(out0, "calibphase", (double) (-1 * sin(phase))); iio_channel_attr_write_double(out1, "calibscale", (double) cos(phase)); iio_channel_attr_write_double(out1, "calibphase", (double) sin(phase)); } } }
bool iio_device_is_trigger(const struct iio_device *dev) { /* A trigger has a name, an id which starts by "trigger", * and zero channels. */ unsigned int nb = iio_device_get_channels_count(dev); const char *name = iio_device_get_name(dev), *id = iio_device_get_id(dev); return ((nb == 0) && !!name && !strncmp(id, "trigger", sizeof("trigger") - 1)); }
static int save_to_ini_dev_cb(struct iio_device *dev, const char *attr, const char *val, size_t len, void *d) { struct load_store_params *params = (struct load_store_params *) d; const char *dev_name = iio_device_get_name(dev); size_t name_len = dev_name ? strlen(dev_name) : 0; if (attr_in_whitelist(attr, dev_name, name_len, params->is_debug, params->whitelist, params->list_len)) write_to_ini(params, dev_name, name_len, attr, val, len); return 0; }
int iiod_client_get_trigger(struct iiod_client *client, int desc, const struct iio_device *dev, const struct iio_device **trigger) { const struct iio_context *ctx = iio_device_get_context(dev); unsigned int i, nb_devices = iio_context_get_devices_count(ctx); char buf[1024]; unsigned int name_len; int ret; snprintf(buf, sizeof(buf), "GETTRIG %s\r\n", iio_device_get_id(dev)); iio_mutex_lock(client->lock); ret = iiod_client_exec_command(client, desc, buf); if (ret == 0) *trigger = NULL; if (ret <= 0) goto out_unlock; if ((unsigned int) ret > sizeof(buf) - 1) { ret = -EIO; goto out_unlock; } name_len = ret; ret = (int) iiod_client_read_all(client, desc, buf, name_len + 1); if (ret < 0) goto out_unlock; ret = -ENXIO; for (i = 0; i < nb_devices; i++) { struct iio_device *cur = iio_context_get_device(ctx, i); if (iio_device_is_trigger(cur)) { const char *name = iio_device_get_name(cur); if (!name) continue; if (!strncmp(name, buf, name_len)) { *trigger = cur; ret = 0; goto out_unlock; } } } out_unlock: iio_mutex_unlock(client->lock); return ret; }
static struct iio_device * get_device(const char *id) { unsigned int i, nb = iio_context_get_devices_count(ctx); for (i = 0; i < nb; i++) { struct iio_device *dev = iio_context_get_device(ctx, i); const char *name = iio_device_get_name(dev); if (!strcmp(id, iio_device_get_id(dev)) || (name && !strcmp(name, id))) return dev; } return NULL; }
static ssize_t update_from_ini_dev_cb(struct iio_device *dev, const char *attr, void *buf, size_t len, void *d) { struct load_store_params *params = (struct load_store_params *) d; const char *dev_name = iio_device_get_name(dev); size_t name_len = dev_name ? strlen(dev_name) : 0; if (attr_in_whitelist(attr, dev_name, name_len, params->is_debug, params->whitelist, params->list_len)) return read_from_ini(params, dev_name, name_len, attr, buf, len); return 0; }
static int save_to_ini_chn_cb(struct iio_channel *chn, const char *attr, const char *val, size_t len, void *d) { struct load_store_params *params = (struct load_store_params *) d; const char *dev_name = iio_device_get_name(params->dev); size_t name_len = dev_name ? strlen(dev_name) : 0; attr = iio_channel_attr_get_filename(chn, attr); if (attr_in_whitelist(attr, dev_name, name_len, false, params->whitelist, params->list_len)) write_to_ini(params, dev_name, name_len, attr, val, len); return 0; }
static void trx_phase_rotation(struct iio_device *dev, gdouble val) { struct iio_channel *out0, *out1; gdouble phase, vcos, vsin; unsigned offset; bool output = (dev == dev_dds_slave) || (dev == dev_dds_master); DBG("%s %f\n", iio_device_get_name(dev), val); phase = val * 2 * M_PI / 360.0; vcos = cos(phase); vsin = sin(phase); if (output) { gdouble corr; corr = 1.0 / fmax(fabs(sin(phase) + cos(phase)), fabs(cos(phase) - sin(phase))); vcos *= corr; vsin *= corr; } /* Set both RX1 and RX2 */ for (offset = 0; offset <= 2; offset += 2) { if (offset == 2) { out0 = iio_device_find_channel(dev, "voltage2", output); out1 = iio_device_find_channel(dev, "voltage3", output); } else { out0 = iio_device_find_channel(dev, "voltage0", output); out1 = iio_device_find_channel(dev, "voltage1", output); } if (out1 && out0) { iio_channel_attr_write_double(out0, "calibscale", (double) vcos); iio_channel_attr_write_double(out0, "calibphase", (double) (-1.0 * vsin)); iio_channel_attr_write_double(out1, "calibscale", (double) vcos); iio_channel_attr_write_double(out1, "calibphase", (double) vsin); } } }
static struct iio_device * get_device(const struct iio_context *ctx, const char *id) { unsigned int i, nb_devices = iio_context_get_devices_count(ctx); struct iio_device *device; for (i = 0; i < nb_devices; i++) { const char *name; device = iio_context_get_device(ctx, i); name = iio_device_get_name(device); if (name && !strcmp(name, id)) break; if (!strcmp(id, iio_device_get_id(device))) break; } if (i < nb_devices) return device; fprintf(stderr, "Device %s not found\n", id); return NULL; }
static bool connect_fillin(Dialogs *data) { GtkTextBuffer *buf; GtkTextIter iter; char text[256]; unsigned int num; size_t i; struct iio_context *ctx; const char *desc; #ifdef FRU_FILES char eprom_names[128]; unsigned char *raw_input_data = NULL; FILE *efp, *fp; struct stat st; /* flushes all open output streams */ fflush(NULL); #if DEBUG fp = popen("find ./ -name \"fru*.bin\"", "r"); #else fp = popen("find /sys -name eeprom 2>/dev/null", "r"); #endif if(fp == NULL) { fprintf(stderr, "can't execute find\n"); return false; } buf = gtk_text_buffer_new(NULL); gtk_text_buffer_get_iter_at_offset(buf, &iter, 0); num = 0; while(fgets(eprom_names, sizeof(eprom_names), fp) != NULL) { num++; /* strip trailing new lines */ if (eprom_names[strlen(eprom_names) - 1] == '\n') eprom_names[strlen(eprom_names) - 1] = '\0'; /* FRU EEPROMS are exactly 256 */ if(stat(eprom_names, &st) !=0) continue; if(st.st_size != 256) { printf("skipping %s (size == %d)\n", eprom_names, (int)st.st_size); continue; } i = 0; if (!is_eeprom_fru(eprom_names, buf, &iter)) { /* Wasn't a FRU file, but is it a blank, writeable EEPROM? */ efp = fopen(eprom_names, "w+"); if (efp) { i = fread(text, 1, 256, efp); if (i == 256) { for (i = 0; i < 256; i++) { if (!(text[i] == 0x00 || ((unsigned char) text[i]) == 0xFF)) { i = 0; break; } } } fclose(efp); /* dump the info into it */ if (i == 256) { if (write_fru(eprom_names)) if(!is_eeprom_fru(eprom_names, buf, &iter)) i = 0; } } else { int errsv = errno; printf("Can't open %s in %s\n%s\n", eprom_names, __func__, strerror(errsv)); } if (i == 0) { sprintf(text, "No FRU information in %s\n", eprom_names); gtk_text_buffer_insert(buf, &iter, text, -1); } } free (raw_input_data); } pclose(fp); if (!num) { sprintf(text, "No eeprom files found in /sys/\n"); gtk_text_buffer_insert(buf, &iter, text, -1); } gtk_text_view_set_buffer(GTK_TEXT_VIEW(data->connect_fru), buf); g_object_unref(buf); #endif ctx = get_context(data); desc = ctx ? iio_context_get_description(ctx) : ""; buf = gtk_text_buffer_new(NULL); gtk_text_buffer_get_iter_at_offset(buf, &iter, 0); gtk_text_buffer_insert(buf, &iter, desc, -1); gtk_text_view_set_buffer(GTK_TEXT_VIEW(data->ctx_info), buf); g_object_unref(buf); buf = gtk_text_buffer_new(NULL); gtk_text_buffer_get_iter_at_offset(buf, &iter, 0); num = ctx ? iio_context_get_devices_count(ctx) : 0; if (num > 0) { for (i = 0; i < num; i++) { struct iio_device *dev = iio_context_get_device(ctx, i); sprintf(text, "%s\n", iio_device_get_name(dev)); gtk_text_buffer_insert(buf, &iter, text, -1); } } else { sprintf(text, "No iio devices found\n"); gtk_text_buffer_insert(buf, &iter, text, -1); } gtk_text_view_set_buffer(GTK_TEXT_VIEW(data->connect_iio), buf); g_object_unref(buf); if (ctx) iio_context_destroy(ctx); return !!ctx; }
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; }
int main(int argc, char **argv) { unsigned int buffer_size = 1024 * 1024; int c, option_index = 0, arg_index = 0; unsigned int n_tx = 0, n_rx = 0; static struct iio_context *ctx; unsigned int i, nb_channels; struct iio_buffer *buffer; pthread_t monitor_thread; const char *device_name; struct iio_device *dev; char unit; int ret; while ((c = getopt_long(argc, argv, "+hs:", options, &option_index)) != -1) { switch (c) { case 'h': usage(argv); return EXIT_SUCCESS; case 's': arg_index += 2; ret = sscanf(argv[arg_index], "%u%c", &buffer_size, &unit); if (ret == 0) return EXIT_FAILURE; if (ret == 2) { if (unit == 'k') buffer_size *= 1024; else if (unit == 'M') buffer_size *= 1024 * 1024; } break; case '?': return EXIT_FAILURE; } } if (arg_index + 1 >= argc) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(argv); return EXIT_FAILURE; } #ifndef _WIN32 set_handler(SIGHUP, &quit_all); #endif set_handler(SIGINT, &quit_all); set_handler(SIGSEGV, &quit_all); set_handler(SIGTERM, &quit_all); ctx = iio_create_default_context(); if (!ctx) { fprintf(stderr, "Unable to create IIO context\n"); return EXIT_FAILURE; } device_name = argv[arg_index + 1]; dev = get_device(ctx, device_name); if (!dev) { iio_context_destroy(ctx); return EXIT_FAILURE; } nb_channels = iio_device_get_channels_count(dev); for (i = 0; i < nb_channels; i++) { struct iio_channel *ch = iio_device_get_channel(dev, i); if (!iio_channel_is_scan_element(ch)) continue; iio_channel_enable(ch); if (iio_channel_is_output(ch)) n_tx++; else n_rx++; } if (n_tx >= n_rx) device_is_tx = true; else device_is_tx = false; printf("Monitoring %s for underflows/overflows\n", iio_device_get_name(dev)); buffer = iio_device_create_buffer(dev, buffer_size, false); if (!buffer) { fprintf(stderr, "Unable to allocate buffer\n"); iio_context_destroy(ctx); return EXIT_FAILURE; } ret = pthread_create(&monitor_thread, NULL, monitor_thread_fn, (void *)device_name); if (ret) { fprintf(stderr, "Failed to create monitor thread: %s\n", strerror(-ret)); } while (app_running) { if (device_is_tx) { ret = iio_buffer_push(buffer); if (ret < 0) { fprintf(stderr, "Unable to push buffer: %s\n", strerror(-ret)); app_running = false; break; } } else { ret = iio_buffer_refill(buffer); if (ret < 0) { fprintf(stderr, "Unable to refill buffer: %s\n", strerror(-ret)); app_running = false; break; } } } iio_buffer_destroy(buffer); iio_context_destroy(ctx); pthread_join(monitor_thread, NULL); return 0; }
int main(int argc, char **argv) { struct iio_context *ctx; int c, option_index = 0, arg_index = 0; enum backend backend = LOCAL; unsigned int major, minor; char git_tag[8]; int ret; while ((c = getopt_long(argc, argv, "+hn:x:", options, &option_index)) != -1) { switch (c) { case 'h': usage(); return EXIT_SUCCESS; case 'n': if (backend != LOCAL) { ERROR("-x and -n are mutually exclusive\n"); return EXIT_FAILURE; } backend = NETWORK; arg_index += 2; break; case 'x': if (backend != LOCAL) { ERROR("-x and -n are mutually exclusive\n"); return EXIT_FAILURE; } backend = XML; arg_index += 2; break; case '?': return EXIT_FAILURE; } } if (arg_index >= argc) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(); return EXIT_FAILURE; } iio_library_get_version(&major, &minor, git_tag); INFO("Library version: %u.%u (git tag: %s)\n", major, minor, git_tag); if (backend == XML) ctx = iio_create_xml_context(argv[arg_index]); else if (backend == NETWORK) ctx = iio_create_network_context(argv[arg_index]); else ctx = iio_create_local_context(); if (!ctx) { ERROR("Unable to create IIO context\n"); return EXIT_FAILURE; } INFO("IIO context created with %s backend.\n", iio_context_get_name(ctx)); ret = iio_context_get_version(ctx, &major, &minor, git_tag); if (!ret) INFO("Backend version: %u.%u (git tag: %s)\n", major, minor, git_tag); else ERROR("Unable to get backend version: %i\n", ret); unsigned int nb_devices = iio_context_get_devices_count(ctx); INFO("IIO context has %u devices:\n", nb_devices); unsigned int i; for (i = 0; i < nb_devices; i++) { const struct iio_device *dev = iio_context_get_device(ctx, i); const char *name = iio_device_get_name(dev); INFO("\t%s: %s\n", iio_device_get_id(dev), name ? name : "" ); unsigned int nb_channels = iio_device_get_channels_count(dev); INFO("\t\t%u channels found:\n", nb_channels); unsigned int j; for (j = 0; j < nb_channels; j++) { struct iio_channel *ch = iio_device_get_channel(dev, j); const char *type_name; if (iio_channel_is_output(ch)) type_name = "output"; else type_name = "input"; name = iio_channel_get_name(ch); INFO("\t\t\t%s: %s (%s)\n", iio_channel_get_id(ch), name ? name : "", type_name); unsigned int nb_attrs = iio_channel_get_attrs_count(ch); if (!nb_attrs) continue; INFO("\t\t\t%u channel-specific attributes found:\n", nb_attrs); unsigned int k; for (k = 0; k < nb_attrs; k++) { const char *attr = iio_channel_get_attr(ch, k); char buf[1024]; ret = (int) iio_channel_attr_read(ch, attr, buf, 1024); if (ret > 0) INFO("\t\t\t\tattr %u: %s" " value: %s\n", k, attr, buf); else if (ret == -ENOSYS) INFO("\t\t\t\tattr %u: %s\n", k, attr); else ERROR("Unable to read attribute %s\n", attr); } } unsigned int nb_attrs = iio_device_get_attrs_count(dev); if (!nb_attrs) continue; INFO("\t\t%u device-specific attributes found:\n", nb_attrs); for (j = 0; j < nb_attrs; j++) { const char *attr = iio_device_get_attr(dev, j); char buf[1024]; ret = (int) iio_device_attr_read(dev, attr, buf, 1024); if (ret > 0) INFO("\t\t\t\tattr %u: %s value: %s\n", j, attr, buf); else if (ret == -ENOSYS) INFO("\t\t\t\tattr %u: %s\n", j, attr); else ERROR("Unable to read attribute: %s\n", attr); } } iio_context_destroy(ctx); return EXIT_SUCCESS; }