/* Check for a valid two channels combination (ch0->ch1, ch2->ch3, ...) * * struct iio_channel_info *chanels - list of channels of a device * int ch_count - number of channel in the list * char* ch_name - output parameter: stores references to the enabled * channels. * Return 1 if the channel combination is valid * Return 0 if the combination is not valid */ int channel_combination_check(struct iio_device *dev, const char **ch_names) { bool consecutive_ch = FALSE; unsigned int i, k, nb_channels = iio_device_get_channels_count(dev); for (i = 0, k = 0; i < nb_channels; i++) { struct iio_channel *ch = iio_device_get_channel(dev, i); struct extra_info *info = iio_channel_get_data(ch); if (info->may_be_enabled) { const char *name = iio_channel_get_name(ch) ?: iio_channel_get_id(ch); ch_names[k++] = name; if (i > 0) { struct extra_info *prev = iio_channel_get_data(iio_device_get_channel(dev, i - 1)); if (prev->may_be_enabled) { consecutive_ch = TRUE; break; } } } } if (!consecutive_ch) return 0; if (!(i & 0x1)) return 0; return 1; }
struct iio_device *iioc_dev_open(struct extra_ctx_info *ctx_info, const char *dev_name) { unsigned int j, k; //Ñ°ÕÒÉ豸 struct iio_device *dev = iio_context_find_device(ctx_info->ctx, dev_name); if (!dev) { IIOC_DBG("No such device(%s).\n", dev_name); return NULL; } IIOC_DBG("Open device - %s.\n", dev_name); //·ÖÅädev_info¿Õ¼ä struct extra_dev_info *dev_info = (struct extra_dev_info *)calloc(1, sizeof(*dev_info)); if (!dev_info) { IIOC_DBG("Can not calloc memory for struct extra_dev_info.\n"); return NULL; } unsigned int nb_channels = iio_device_get_channels_count(dev); unsigned int nb_attrs = iio_device_get_attrs_count(dev); dev_info->input_device = is_input_device(dev); dev_info->nb_channels = nb_channels; dev_info->nb_attrs = nb_attrs; dev_info->ctx_info = ctx_info; iio_device_set_data(dev, dev_info); for (j = 0; j < nb_channels; j++) { struct iio_channel *ch = iio_device_get_channel(dev, j); #ifdef _DEBUG const char *ch_id = iio_channel_get_id(ch); const char *ch_name = iio_channel_get_name(ch); IIOC_DBG("\tCH%d: %s - %s.\n", j, ch_id, ch_name); #endif struct extra_chn_info *chn_info = (struct extra_chn_info *)calloc(1, sizeof(*chn_info)); if (!chn_info) { goto error_calloc_chn_info; } chn_info->dev = dev; iio_channel_set_data(ch, chn_info); } #ifdef _DEBUG for (k = 0; k < nb_attrs; k++) { const char *attr_name = iio_device_get_attr(dev, k); IIOC_DBG("\t>> Attr%d: %s.\n", k, attr_name); } #endif return dev; error_calloc_chn_info: for (k = 0; k < nb_channels; k++) { struct iio_channel *ch = iio_device_get_channel(dev, k); struct extra_chn_info *chn_info = iio_channel_get_data(ch); if (chn_info) free(chn_info); } IIOC_DBG("Can not calloc memory for struct extra_chn_info.\n"); return NULL; }
int iioc_channel_enable(const struct iio_device *dev, const unsigned int *enable, unsigned int nb_en_channels) { unsigned int i, nb_channels; if (!dev) { IIOC_DBG("No such device.\n"); return -ENODEV; } if (!enable) { return -EINVAL; } unsigned int nb_dev_channels = iio_device_get_channels_count(dev); if (nb_en_channels < nb_dev_channels) nb_channels = nb_en_channels; else nb_channels = nb_dev_channels; for (i = 0; i < nb_channels; i++) { struct iio_channel *ch = iio_device_get_channel(dev, i); struct extra_chn_info *chn_info = iio_channel_get_data(ch); if (enable[i]) { chn_info->enabled = true; iio_channel_enable(ch); } else { chn_info->enabled = false; iio_channel_disable(ch); } } return 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; }
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; }
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 void iio_channels_change_shadow_of_enabled(struct iio_device *dev, bool increment) { struct iio_channel *chn; struct extra_info *info; unsigned i; for (i = 0; i < iio_device_get_channels_count(dev); i++) { chn = iio_device_get_channel(dev, i); info = iio_channel_get_data(chn); if (increment) info->shadow_of_enabled++; else info->shadow_of_enabled--; } }
void iio_update_widgets_of_device(struct iio_widget *widgets, unsigned int num_widgets, struct iio_device *dev) { unsigned int i; struct update_widgets_params params = { .widgets = widgets, .nb = num_widgets, }; iio_device_attr_read_all(dev, __cb_dev_update, ¶ms); for (i = 0; i < iio_device_get_channels_count(dev); i++) iio_channel_attr_read_all(iio_device_get_channel(dev, i), __cb_chn_update, ¶ms); }
static struct iio_channel * get_channel(const struct iio_device *dev, const char *id) { unsigned int i, nb = iio_device_get_channels_count(dev); for (i = 0; i < nb; i++) { struct iio_channel *chn = iio_device_get_channel(dev, i); const char *name = iio_channel_get_name(chn); if (iio_channel_is_output(chn)) continue; if (!strcmp(id, iio_channel_get_id(chn)) || (name && !strcmp(name, id))) return chn; } return NULL; }
/* * Check if a device has scan elements and if it is an output device (type = 0) * or an input device (type = 1). */ static bool device_type_get(const struct iio_device *dev, int type) { struct iio_channel *ch; int nb_channels, i; if (!dev) return false; nb_channels = iio_device_get_channels_count(dev); for (i = 0; i < nb_channels; i++) { ch = iio_device_get_channel(dev, i); if (iio_channel_is_scan_element(ch) && (type ? !iio_channel_is_output(ch) : iio_channel_is_output(ch))) return true; } return false; }
short *iioc_chn_get_data(const struct iio_device *dev, unsigned int chn, unsigned int *data_size) { assert(dev); struct iio_channel *ch = iio_device_get_channel(dev, chn); if (!ch) { IIOC_DBG("CH%d is not found.\n", chn); return NULL; } struct extra_chn_info *chn_info = iio_channel_get_data(ch); if (!chn_info) { IIOC_DBG("struct extra_chn_info point is NULL.\n"); return NULL; } if (!chn_info->enabled) { IIOC_DBG("CH%d is not enabled.\n", chn); return NULL; } *data_size = chn_info->offset; return chn_info->data_ref; }
static bool dmm_identify(const struct osc_plugin *plugin) { /* Use the OSC's IIO context just to detect the devices */ struct iio_context *osc_ctx = get_context_from_osc(); unsigned int i, num; bool ret = false; num = iio_context_get_devices_count(osc_ctx); for (i = 0; !ret && i < num; i++) { struct iio_device *dev = iio_context_get_device(osc_ctx, i); unsigned int j, nch = iio_device_get_channels_count(dev); for (j = 0; !ret && j < nch; j++) { struct iio_channel *chn = iio_device_get_channel(dev, j); if (is_valid_dmm_channel(chn)) ret = true; } } return ret; }
int main(int argc, char **argv) { unsigned int i, nb_channels; unsigned int buffer_size = SAMPLES_PER_READ; const char *arg_uri = NULL; const char *arg_ip = NULL; int c, option_index = 0; struct iio_device *dev; size_t sample_size; int timeout = -1; bool scan_for_context = false; while ((c = getopt_long(argc, argv, "+hn:u:t:b:s:T:a", options, &option_index)) != -1) { switch (c) { case 'h': usage(); return EXIT_SUCCESS; case 'n': arg_ip = optarg; break; case 'u': arg_uri = optarg; break; case 'a': scan_for_context = true; break; case 't': trigger_name = optarg; break; case 'b': buffer_size = atoi(optarg); break; case 's': num_samples = atoi(optarg); break; case 'T': timeout = atoi(optarg); break; case '?': return EXIT_FAILURE; } } if (argc == optind) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(); return EXIT_FAILURE; } setup_sig_handler(); if (scan_for_context) ctx = scan(); else if (arg_uri) ctx = iio_create_context_from_uri(arg_uri); else if (arg_ip) ctx = iio_create_network_context(arg_ip); else ctx = iio_create_default_context(); if (!ctx) { fprintf(stderr, "Unable to create IIO context\n"); return EXIT_FAILURE; } if (timeout >= 0) iio_context_set_timeout(ctx, timeout); dev = iio_context_find_device(ctx, argv[optind]); if (!dev) { fprintf(stderr, "Device %s not found\n", argv[optind]); iio_context_destroy(ctx); return EXIT_FAILURE; } if (trigger_name) { struct iio_device *trigger = iio_context_find_device( ctx, trigger_name); if (!trigger) { fprintf(stderr, "Trigger %s not found\n", trigger_name); iio_context_destroy(ctx); return EXIT_FAILURE; } if (!iio_device_is_trigger(trigger)) { fprintf(stderr, "Specified device is not a trigger\n"); iio_context_destroy(ctx); return EXIT_FAILURE; } /* * Fixed rate for now. Try new ABI first, * fail gracefully to remain compatible. */ if (iio_device_attr_write_longlong(trigger, "sampling_frequency", DEFAULT_FREQ_HZ) < 0) iio_device_attr_write_longlong(trigger, "frequency", DEFAULT_FREQ_HZ); iio_device_set_trigger(dev, trigger); } nb_channels = iio_device_get_channels_count(dev); if (argc == optind + 1) { /* Enable all channels */ for (i = 0; i < nb_channels; i++) iio_channel_enable(iio_device_get_channel(dev, i)); } else { for (i = 0; i < nb_channels; i++) { unsigned int j; struct iio_channel *ch = iio_device_get_channel(dev, i); for (j = optind + 1; j < (unsigned int) argc; j++) { const char *n = iio_channel_get_name(ch); if (!strcmp(argv[j], iio_channel_get_id(ch)) || (n && !strcmp(n, argv[j]))) iio_channel_enable(ch); } } } sample_size = iio_device_get_sample_size(dev); buffer = iio_device_create_buffer(dev, buffer_size, false); if (!buffer) { char buf[256]; iio_strerror(errno, buf, sizeof(buf)); fprintf(stderr, "Unable to allocate buffer: %s\n", buf); iio_context_destroy(ctx); return EXIT_FAILURE; } while (app_running) { int ret = iio_buffer_refill(buffer); if (ret < 0) { if (app_running) { char buf[256]; iio_strerror(-ret, buf, sizeof(buf)); fprintf(stderr, "Unable to refill buffer: %s\n", buf); } break; } /* If there are only the samples we requested, we don't need to * demux */ if (iio_buffer_step(buffer) == sample_size) { void *start = iio_buffer_start(buffer); size_t read_len, len = (intptr_t) iio_buffer_end(buffer) - (intptr_t) start; if (num_samples && len > num_samples * sample_size) len = num_samples * sample_size; for (read_len = len; len; ) { size_t nb = fwrite(start, 1, len, stdout); if (!nb) goto err_destroy_buffer; len -= nb; start = (void *)((intptr_t) start + nb); } if (num_samples) { num_samples -= read_len / sample_size; if (!num_samples) quit_all(EXIT_SUCCESS); } } else { iio_buffer_foreach_sample(buffer, print_sample, NULL); } } err_destroy_buffer: iio_buffer_destroy(buffer); iio_context_destroy(ctx); return exit_code; }
void update_from_ini(const char *ini_file, const char *driver_name, struct iio_device *dev, const char * const *whitelist, size_t list_len) { bool found = false; const char *name; size_t nlen; unsigned int i; struct INI *ini = ini_open(ini_file); struct load_store_params params = { .dev = dev, .whitelist = whitelist, .list_len = list_len, .is_debug = false, .ini = ini, }; if (!ini) { fprintf(stderr, "ERROR: Cannot open INI file %s\n", ini_file); return; } while (!found && ini_next_section(ini, &name, &nlen) > 0) found = !strncmp(name, driver_name, nlen); if (!found) { fprintf(stderr, "error parsing %s file: Could not find %s\n", ini_file, driver_name); ini_close(ini); return; } params.section_top = name + nlen + 1; for (i = 0; i < iio_device_get_channels_count(dev); i++) iio_channel_attr_write_all(iio_device_get_channel(dev, i), update_from_ini_chn_cb, ¶ms); if (iio_device_get_attrs_count(dev)) iio_device_attr_write_all(dev, update_from_ini_dev_cb, ¶ms); params.is_debug = true; iio_device_debug_attr_write_all(dev, update_from_ini_dev_cb, ¶ms); ini_close(ini); } char * read_token_from_ini(const char *ini_file, const char *driver_name, const char *token) { char *dup; const char *name, *key, *value; size_t nlen, klen, vlen, tlen = strlen(token); bool found = false; struct INI *ini = ini_open(ini_file); if (!ini) return NULL; while (!found && ini_next_section(ini, &name, &nlen) > 0) found = !strncmp(name, driver_name, nlen); if (!found) return NULL; found = false; while (!found && ini_read_pair(ini, &key, &klen, &value, &vlen) > 0) found = (tlen == klen) && !strncmp(token, key, klen); if (!found) return NULL; dup = malloc(vlen + 1); snprintf(dup, vlen + 1, "%.*s", (int) vlen, value); ini_close(ini); return dup; }
int main(int argc, char **argv) { unsigned int i, nb_channels; unsigned int buffer_size = SAMPLES_PER_READ; int c, option_index = 0, arg_index = 0, ip_index = 0; struct iio_device *dev; size_t sample_size; while ((c = getopt_long(argc, argv, "+hn:t:b:s:", options, &option_index)) != -1) { switch (c) { case 'h': usage(); return EXIT_SUCCESS; case 'n': arg_index += 2; ip_index = arg_index; break; case 't': arg_index += 2; trigger_name = argv[arg_index]; break; case 'b': arg_index += 2; buffer_size = atoi(argv[arg_index]); break; case 's': arg_index += 2; num_samples = atoi(argv[arg_index]); break; case '?': return EXIT_FAILURE; } } if (arg_index + 1 >= argc) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(); return EXIT_FAILURE; } if (ip_index) ctx = iio_create_network_context(argv[ip_index]); else ctx = iio_create_default_context(); if (!ctx) { fprintf(stderr, "Unable to create IIO context\n"); 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); dev = get_device(ctx, argv[arg_index + 1]); if (!dev) { iio_context_destroy(ctx); return EXIT_FAILURE; } if (trigger_name) { struct iio_device *trigger = get_device(ctx, trigger_name); if (!trigger) { iio_context_destroy(ctx); return EXIT_FAILURE; } if (!iio_device_is_trigger(trigger)) { fprintf(stderr, "Specified device is not a trigger\n"); iio_context_destroy(ctx); return EXIT_FAILURE; } /* Fixed rate for now */ iio_device_attr_write_longlong(trigger, "frequency", 100); iio_device_set_trigger(dev, trigger); } nb_channels = iio_device_get_channels_count(dev); if (argc == arg_index + 2) { /* Enable all channels */ for (i = 0; i < nb_channels; i++) iio_channel_enable(iio_device_get_channel(dev, i)); } else { for (i = 0; i < nb_channels; i++) { unsigned int j; struct iio_channel *ch = iio_device_get_channel(dev, i); for (j = arg_index + 2; j < argc; j++) { const char *n = iio_channel_get_name(ch); if (!strcmp(argv[j], iio_channel_get_id(ch)) || (n && !strcmp(n, argv[j]))) iio_channel_enable(ch); } } } sample_size = iio_device_get_sample_size(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; } while (app_running) { int ret = iio_buffer_refill(buffer); if (ret < 0) { fprintf(stderr, "Unable to refill buffer: %s\n", strerror(-ret)); break; } /* If there are only the samples we requested, we don't need to * demux */ if (iio_buffer_step(buffer) == sample_size) { void *start = iio_buffer_start(buffer); ptrdiff_t len = (intptr_t) iio_buffer_end(buffer) - (intptr_t) start; size_t read_len; if (num_samples && len > num_samples * sample_size) len = num_samples * sample_size; for (read_len = len; len; ) { ssize_t nb = fwrite(start, 1, len, stdout); if (nb < 0) { fprintf(stderr, "Unable to write data!\n"); goto err_destroy_buffer; } len -= nb; start = (void *)((intptr_t) start + nb); } if (num_samples) { num_samples -= read_len / sample_size; if (!num_samples) quit_all(EXIT_SUCCESS); } } else { iio_buffer_foreach_sample(buffer, print_sample, NULL); } } err_destroy_buffer: iio_buffer_destroy(buffer); iio_context_destroy(ctx); return exit_code; }
static void build_channel_list(void) { GtkTreeIter iter, iter2, iter3; unsigned int enabled; char *device, *device2; gboolean first = FALSE, iter3_valid = FALSE, loop, loop2, all = FALSE; char dev_ch[256]; loop = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (device_list_store), &iter); gtk_list_store_clear(channel_list_store); while (loop) { gtk_tree_model_get(GTK_TREE_MODEL (device_list_store), &iter, 0, &device, 1, &enabled, -1); if (enabled) { struct iio_device *dev; unsigned int i, nb_channels; all = true; /* is it already in the list? */ loop2 = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (channel_list_store), &iter2); if (loop2) { first = TRUE; iter3 = iter2; iter3_valid = TRUE; } while (loop2) { gtk_tree_model_get(GTK_TREE_MODEL (channel_list_store), &iter2, 2, &device2, -1); if (!strcmp(device, device2)) break; if (strcmp(device, device2) >= 0) { first = FALSE; iter3 = iter2; } g_free(device2); loop2 = gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter2); } /* it is, so skip the rest */ if (loop2) { loop = gtk_tree_model_iter_next(GTK_TREE_MODEL (device_list_store), &iter); continue; } dev = get_device(device); if (!dev) continue; nb_channels = iio_device_get_channels_count(dev); for (i = 0; i < nb_channels; i++) { struct iio_channel *chn = iio_device_get_channel(dev, i); const char *name, *id, *devid; /* Must be input */ if (!is_valid_dmm_channel(chn)) continue; /* find the name */ devid = iio_device_get_id(dev); name = iio_channel_get_name(chn); id = iio_channel_get_id(chn); if (!name) name = id; if (iter3_valid) { if (first) { gtk_list_store_insert_before(channel_list_store, &iter2, &iter3); first = FALSE; } else if(gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter3)) gtk_list_store_insert_before(channel_list_store, &iter2, &iter3); else gtk_list_store_append(channel_list_store, &iter2); } else { gtk_list_store_append(channel_list_store, &iter2); iter3_valid = TRUE; } snprintf(dev_ch, sizeof(dev_ch), "%s:%s", device, name); gtk_list_store_set(channel_list_store, &iter2, 0, dev_ch, /* device & channel name */ 1, 0, /* On/Off */ 2, devid, /* device ID */ 3, id, /* channel ID */ -1); iter3 = iter2; } } else { loop2 = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (channel_list_store), &iter2); while (loop2) { gtk_tree_model_get(GTK_TREE_MODEL (channel_list_store), &iter2, 2, &device2, -1); if (!strcmp(device, device2)) { loop2 = gtk_list_store_remove(channel_list_store, &iter2); continue; } loop2 = gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter2); } } loop = gtk_tree_model_iter_next(GTK_TREE_MODEL (device_list_store), &iter); } gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(GTK_TREE_MODEL(channel_list_store)), 0, GTK_SORT_ASCENDING); if (all) gtk_widget_show(select_all_channels); else gtk_widget_hide(select_all_channels); }
void save_to_ini(FILE *f, const char *driver_name, struct iio_device *dev, const char * const *whitelist, size_t list_len) { unsigned int i; struct load_store_params params = { .dev = dev, .whitelist = whitelist, .list_len = list_len, .is_debug = false, .f = f, }; if (driver_name) { fwrite("\n[", 1, 2, f); fwrite(driver_name, 1, strlen(driver_name), f); fwrite("]\n", 1, 2, f); } for (i = 0; i < iio_device_get_channels_count(dev); i++) iio_channel_attr_read_all(iio_device_get_channel(dev, i), save_to_ini_chn_cb, ¶ms); iio_device_attr_read_all(dev, save_to_ini_dev_cb, ¶ms); params.is_debug = true; iio_device_debug_attr_read_all(dev, save_to_ini_dev_cb, ¶ms); } int foreach_in_ini(const char *ini_file, int (*cb)(int, const char *, const char *, const char *)) { int ret = 0; const char *name, *key, *value; size_t nlen, klen, vlen; struct INI *ini = ini_open(ini_file); if (!ini) return -1; while (ini_next_section(ini, &name, &nlen) > 0) { char *n = malloc(nlen + 1); if (!n) goto err_ini_close; snprintf(n, nlen + 1, "%.*s", (int) nlen, name); while (ini_read_pair(ini, &key, &klen, &value, &vlen) > 0) { int line = ini_get_line_number(ini, key); char *v, *k = malloc(klen + 1); if (!k) { free(n); goto err_ini_close; } v = malloc(vlen + 1); if (!v) { free(k); free(n); goto err_ini_close; } snprintf(k, klen + 1, "%.*s", (int) klen, key); snprintf(v, vlen + 1, "%.*s", (int) vlen, value); ret = cb(line, n, k, v); /* only needed when debugging - this should be done in each section if (ret < 0) { fprintf(stderr, "issue in '%s' file: Section:'%s' key:'%s' value:'%s'\n", ini_file, n, k, v); } */ free(k); free(v); if (ret < 0) { free(n); goto err_ini_close; } if (ret > 0) { ret = 0; break; } } free(n); } err_ini_close: ini_close(ini); return ret; }
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 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 void disable_all_channels(struct iio_device *dev) { unsigned int i, nb_channels = iio_device_get_channels_count(dev); for (i = 0; i < nb_channels; i++) iio_channel_disable(iio_device_get_channel(dev, i)); }
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; }