示例#1
0
/**
 * @brief Convert raw data (from the driver) to double-typed samples
 *
 * @param[in] chan Channel descriptor
 * @param[in] rng Range descriptor
 * @param[out] dst Ouput buffer
 * @param[in] src Input buffer
 * @param[in] cnt Count of conversion to perform
 *
 * @return the count of conversion performed, otherwise a negative
 * error code:
 *
 * - -EINVAL is returned if some argument is missing or wrong;
 *    chan, rng and the pointers should be checked; check also the
 *    kernel log ("dmesg"); WARNING: a4l_fill_desc() should be called
 *    before using a4l_rawtod()
 *
 */
int a4l_rawtod(a4l_chinfo_t * chan,
	       a4l_rnginfo_t * rng, double *dst, void *src, int cnt)
{
	int size, i = 0, j = 0;
	lsampl_t tmp;

	/* Temporary values used for conversion
	   (phys = a * src + b) */
	double a, b;
	/* Temporary data accessor */
	lsampl_t(*datax_get) (void *);

	/* Basic checking */
	if (rng == NULL || chan == NULL)
		return -EINVAL;

	/* Find out the size in memory */
	size = a4l_sizeof_chan(chan);

	/* Get the suitable accessor */
	switch (a4l_sizeof_chan(chan)) {
	case 4:
		datax_get = data32_get;
		break;
	case 2:
		datax_get = data16_get;
		break;
	case 1:
		datax_get = data8_get;
		break;
	default:
		return -EINVAL;
	};

	/* Computes the translation factor and the constant only once */
	a = ((double)(rng->max - rng->min)) /
		(((1ULL << chan->nb_bits) - 1) * A4L_RNG_FACTOR);
	b = ((double)rng->min) / A4L_RNG_FACTOR;

	while (j < cnt) {

		/* Properly retrieve the data */
		tmp = datax_get(src + i);

		/* Perform the conversion */
		dst[j] = a * tmp + b;

		/* Update the counters */
		i += size;
		j++;
	}

	return j;
}
示例#2
0
static int dump_text(a4l_desc_t *dsc, unsigned char *buf, int size)
{
	int err = 0, width, tmp_size = 0;
	char *fmt;
	a4l_chinfo_t *chan;

	/* Retrieve the subdevice data size */
	err = a4l_get_chinfo(dsc, idx_subd, idx_chan, &chan);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: info for channel %d "
			"on subdevice %d not available (err=%d)\n",
			idx_chan, idx_subd, err);
		goto out;
	}

	width = a4l_sizeof_chan(chan);
	if (width < 0) {
		fprintf(stderr,
			"insn_read: incoherent info for channel %d\n",
			idx_chan);
		err = width;
		goto out;
	}

	switch(width) {
	case 1:
		fmt = "0x%02x\n";
		break;
	case 2:
		fmt = "0x%04x\n";
		break;
	case 4:
	default:
		fmt = "0x%08x\n";
		break;
	}

	while (size - tmp_size > 0) {
		unsigned long values[64];
		int i, tmp_cnt = ((size - tmp_size) / width > 64) ?
			64 : ((size - tmp_size) / width);

		err = a4l_rawtoul(chan, values, buf + tmp_size, tmp_cnt);
		if (err < 0)
			goto out;

		for (i = 0; i < tmp_cnt; i++)
			fprintf(stdout, fmt, values[i]);

		tmp_size += tmp_cnt * width;
	}

out:
	return err;
}
示例#3
0
static int dump_converted(a4l_desc_t *dsc, unsigned char *buf, int size)
{
	int err = 0, width, tmp_size = 0;
	a4l_chinfo_t *chan;
	a4l_rnginfo_t *rng;

	/* Retrieve the channel info */
	err = a4l_get_chinfo(dsc, idx_subd, idx_chan, &chan);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: info for channel %d "
			"on subdevice %d not available (err=%d)\n",
			idx_chan, idx_subd, err);
		goto out;
	}

	/* Retrieve the range info */
	err = a4l_get_rnginfo(dsc, idx_subd, idx_chan, idx_rng, &rng);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: failed to recover range descriptor\n");
		goto out;
	}

	width = a4l_sizeof_chan(chan);
	if (width < 0) {
		fprintf(stderr,
			"insn_read: incoherent info for channel %d\n",
			idx_chan);
		err = width;
		goto out;
	}

	fprintf(stdout, "Non Calibrated values: \n");
	while (size - tmp_size > 0) {
		double values[64];
		int i, tmp_cnt = ((size - tmp_size) / width > 64) ?
			64 : ((size - tmp_size) / width);

		err = a4l_rawtod(chan, rng, values, buf + tmp_size, tmp_cnt);
		if (err < 0)
			goto out;

		for (i = 0; i < tmp_cnt; i++) {
			fprintf(stdout, "%F\n", values[i]);
		}

		tmp_size += tmp_cnt * width;
	}

out:
	return err;
}
示例#4
0
/**
 * @brief Convert double-typed samples to raw data (for the driver)
 *
 * @param[in] chan Channel descriptor
 * @param[in] rng Range descriptor
 * @param[out] dst Ouput buffer
 * @param[in] src Input buffer
 * @param[in] cnt Count of conversion to perform
 *
 * @return the count of conversion performed, otherwise a negative
 * error code:
 *
 * - -EINVAL is returned if some argument is missing or wrong;
 *    chan, rng and the pointers should be checked; check also the
 *    kernel log ("dmesg"); WARNING: a4l_fill_desc() should be called
 *    before using a4l_dtoraw()
 *
 */
int a4l_dtoraw(a4l_chinfo_t * chan,
	       a4l_rnginfo_t * rng, void *dst, double *src, int cnt)
{
	int size, i = 0, j = 0;

	/* Temporary values used for conversion
	   (dst = a * phys - b) */
	double a, b;
	/* Temporary data accessor */
	void (*datax_set) (void *, lsampl_t);

	/* Basic checking */
	if (rng == NULL || chan == NULL)
		return -EINVAL;

	/* Find out the size in memory */
	size = a4l_sizeof_chan(chan);

	/* Select the suitable accessor */
	switch (size) {
	case 4:
		datax_set = data32_set;
		break;
	case 2:
		datax_set = data16_set;
		break;
	case 1:
		datax_set = data8_set;
		break;
	default:
		return -EINVAL;
	};

	/* Computes the translation factor and the constant only once */
	a = (((double)A4L_RNG_FACTOR) / (rng->max - rng->min)) *
		((1ULL << chan->nb_bits) - 1);
	b = ((double)(rng->min) / (rng->max - rng->min)) *
		((1ULL << chan->nb_bits) - 1);

	while (j < cnt) {

		/* Performs the conversion */
		datax_set(dst + i, (lsampl_t) (a * src[j] - b));

		/* Updates the counters */
		i += size;
		j++;
	}

	return j;
}
示例#5
0
/**
 * @brief Pack unsigned long values into raw data (for the driver)
 *
 * This function takes as input a table of unsigned long values and
 * gather them according to the channel width. It is a convenience
 * routine which performs no conversion, just formatting.
 *
 * @param[in] chan Channel descriptor
 * @param[in] rng Range descriptor
 * @param[out] dst Ouput buffer
 * @param[in] src Input buffer
 * @param[in] cnt Count of transfer to copy
 *
 * @return the count of copy performed, otherwise a negative error
 * code:
 *
 * - -EINVAL is returned if some argument is missing or wrong;
 *    chan, rng and the pointers should be checked; check also the
 *    kernel log ("dmesg"); WARNING: a4l_fill_desc() should be called
 *    before using a4l_ultoraw()
 *
 */
int a4l_ultoraw(a4l_chinfo_t * chan, void *dst, unsigned long *src, int cnt)
{
	int size, i = 0, j = 0;

	/* Temporary data accessor */
	void (*datax_set) (void *, lsampl_t);

	/* Basic checking */
	if (chan == NULL)
		return -EINVAL;

	/* Find out the size in memory */
	size = a4l_sizeof_chan(chan);

	/* Select the suitable accessor */
	switch (size) {
	case 4:
		datax_set = data32_set;
		break;
	case 2:
		datax_set = data16_set;
		break;
	case 1:
		datax_set = data8_set;
		break;
	default:
		return -EINVAL;
	};

	while (j < cnt) {

		/* Perform the copy */
		datax_set(dst + i, (lsampl_t)src[j]);

		/* Update the counters */
		i += size;
		j++;
	}

	return j;
}
示例#6
0
/**
 * @brief Unpack raw data (from the driver) into unsigned long values
 *
 * This function takes as input driver-specific data and scatters each
 * element into an entry of an unsigned long table. It is a
 * convenience routine which performs no conversion, just copy.
 *
 * @param[in] chan Channel descriptor
 * @param[in] rng Range descriptor
 * @param[out] dst Ouput buffer
 * @param[in] src Input buffer
 * @param[in] cnt Count of transfer to copy
 *
 * @return the count of copy performed, otherwise a negative error
 * code:
 *
 * - -EINVAL is returned if some argument is missing or wrong;
 *    chan, rng and the pointers should be checked; check also the
 *    kernel log ("dmesg"); WARNING: a4l_fill_desc() should be called
 *    before using a4l_ultoraw()
 *
 */
int a4l_rawtoul(a4l_chinfo_t * chan, unsigned long *dst, void *src, int cnt)
{
	int size, i = 0, j = 0;

	/* Temporary data accessor */
	lsampl_t(*datax_get) (void *);

	/* Basic checking */
	if (chan == NULL)
		return -EINVAL;

	/* Find out the size in memory */
	size = a4l_sizeof_chan(chan);

	/* Get the suitable accessor */
	switch (size) {
	case 4:
		datax_get = data32_get;
		break;
	case 2:
		datax_get = data16_get;
		break;
	case 1:
		datax_get = data8_get;
		break;
	default:
		return -EINVAL;
	};

	while (j < cnt) {

		/* Properly copy the data */
		dst[j] = (unsigned long)datax_get(src + i);

		/* Update the counters */
		i += size;
		j++;
	}

	return j;
}
示例#7
0
int main(int argc, char *argv[])
{
	int ret = 0, len, ofs;
	unsigned int i, scan_size = 0, cnt = 0;
	unsigned long buf_size;
	void *map = NULL;
	a4l_desc_t dsc = { .sbdata = NULL };

	int (*dump_function) (a4l_desc_t *, a4l_cmd_t*, unsigned char *, int) =
		dump_text;

	/* Compute arguments */
	while ((ret = getopt_long(argc,
				  argv,
				  "vrd:s:S:c:mwk:h", 
				  cmd_read_opts, NULL)) >= 0) {
		switch (ret) {
		case 'v':
			verbose = 1;
			break;
		case 'r':
			real_time = 1;
			break;
		case 'd':
			filename = optarg;
			break;
		case 's':
			cmd.idx_subd = strtoul(optarg, NULL, 0);
			break;
		case 'S':
			cmd.stop_arg = strtoul(optarg, NULL, 0);
			break;
		case 'c':
			str_chans = optarg;
			break;
		case 'm':
			use_mmap = 1;
			break;
		case 'w':
			dump_function = dump_raw;
			break;
		case 'k':
			wake_count = strtoul(optarg, NULL, 0);
			break;
		case 'h':
		default:
			do_print_usage();
			return 0;
		}
	}

	if (isatty(STDOUT_FILENO) && dump_function == dump_raw) {
		fprintf(stderr,
			"cmd_read: cannot dump raw data on a terminal\n\n");
		return -EINVAL;
	}

	/* Recover the channels to compute */
	do {
		cmd.nb_chan++;
		len = strlen(str_chans);
		ofs = strcspn(str_chans, ",");
		if (sscanf(str_chans, "%u", &chans[cmd.nb_chan - 1]) == 0) {
			fprintf(stderr, "cmd_read: bad channel argument\n");
			return -EINVAL;
		}
		str_chans += ofs + 1;
	} while (len != ofs);

	/* Update the command structure */
	cmd.scan_end_arg = cmd.nb_chan;
	cmd.stop_src = cmd.stop_arg != 0 ? TRIG_COUNT : TRIG_NONE;

	if (real_time != 0) {

		if (verbose != 0)
			printf("cmd_read: switching to real-time mode\n");

		/* Prevent any memory-swapping for this program */
		ret = mlockall(MCL_CURRENT | MCL_FUTURE);
		if (ret < 0) {
			ret = errno;
			fprintf(stderr, "cmd_read: mlockall failed (ret=%d)\n",
				ret);
			goto out_main;
		}

		/* Turn the current process into an RT task */
		ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);
		if (ret < 0) {
			fprintf(stderr,
				"cmd_read: rt_task_shadow failed (ret=%d)\n",
				ret);
			goto out_main;
		}
	}

	/* Open the device */
	ret = a4l_open(&dsc, filename);
	if (ret < 0) {
		fprintf(stderr, "cmd_read: a4l_open %s failed (ret=%d)\n",
			filename, ret);
		return ret;
	}

	if (verbose != 0) {
		printf("cmd_read: device %s opened (fd=%d)\n",
		       filename, dsc.fd);
		printf("cmd_read: basic descriptor retrieved\n");
		printf("\t subdevices count = %d\n", dsc.nb_subd);
		printf("\t read subdevice index = %d\n", dsc.idx_read_subd);
		printf("\t write subdevice index = %d\n", dsc.idx_write_subd);
	}

	/* Allocate a buffer so as to get more info (subd, chan, rng) */
	dsc.sbdata = malloc(dsc.sbsize);
	if (dsc.sbdata == NULL) {
		fprintf(stderr, "cmd_read: malloc failed \n");
		return -ENOMEM;
	}

	/* Get this data */
	ret = a4l_fill_desc(&dsc);
	if (ret < 0) {
		fprintf(stderr,
			"cmd_read: a4l_fill_desc failed (ret=%d)\n", ret);
		goto out_main;
	}

	if (verbose != 0)
		printf("cmd_read: complex descriptor retrieved\n");

	/* Get the size of a single acquisition */
	for (i = 0; i < cmd.nb_chan; i++) {
		a4l_chinfo_t *info;

		ret = a4l_get_chinfo(&dsc,
				     cmd.idx_subd, cmd.chan_descs[i], &info);
		if (ret < 0) {
			fprintf(stderr,
				"cmd_read: a4l_get_chinfo failed (ret=%d)\n",
				ret);
			goto out_main;
		}

		if (verbose != 0) {
			printf("cmd_read: channel %x\n", cmd.chan_descs[i]);
			printf("\t ranges count = %d\n", info->nb_rng);
			printf("\t bit width = %d (bits)\n", info->nb_bits);
		}

		scan_size += a4l_sizeof_chan(info);
	}

	if (verbose != 0) {
		printf("cmd_read: scan size = %u\n", scan_size);
		if (cmd.stop_arg != 0)
			printf("cmd_read: size to read = %u\n",
			       scan_size * cmd.stop_arg);
	}

	/* Cancel any former command which might be in progress */
	a4l_snd_cancel(&dsc, cmd.idx_subd);

	if (use_mmap != 0) {

		/* Get the buffer size to map */
		ret = a4l_get_bufsize(&dsc, cmd.idx_subd, &buf_size);
		if (ret < 0) {
			fprintf(stderr,
				"cmd_read: a4l_get_bufsize() failed (ret=%d)\n",
				ret);
			goto out_main;
		}

		if (verbose != 0)
			printf("cmd_read: buffer size = %lu bytes\n", buf_size);

		/* Map the analog input subdevice buffer */
		ret = a4l_mmap(&dsc, cmd.idx_subd, buf_size, &map);
		if (ret < 0) {
			fprintf(stderr,
				"cmd_read: a4l_mmap() failed (ret=%d)\n",
				ret);
			goto out_main;
		}

		if (verbose != 0)
			printf
				("cmd_read: mmap performed successfully (map=0x%p)\n",
				 map);
	}

	ret = a4l_set_wakesize(&dsc, wake_count);
	if (ret < 0) {
		fprintf(stderr,
			"cmd_read: a4l_set_wakesize failed (ret=%d)\n", ret);
		goto out_main;
	}

	if (verbose != 0)
		printf("cmd_read: wake size successfully set (%lu)\n", 
		       wake_count);

	/* Send the command to the input device */
	ret = a4l_snd_command(&dsc, &cmd);
	if (ret < 0) {
		fprintf(stderr,
			"cmd_read: a4l_snd_command failed (ret=%d)\n", ret);
		goto out_main;
	}

	if (verbose != 0)
		printf("cmd_read: command successfully sent\n");

	if (use_mmap == 0) {

		/* Fetch data */
		do {
			/* Perform the read operation */
			ret = a4l_async_read(&dsc, buf, BUF_SIZE, A4L_INFINITE);
			if (ret < 0) {
				fprintf(stderr,
					"cmd_read: a4l_read failed (ret=%d)\n",
					ret);
				goto out_main;
			}

			/* Display the results */
			if (dump_function(&dsc, &cmd, buf, ret) < 0) {
				ret = -EIO;
				goto out_main;
			}

			/* Update the counter */
			cnt += ret;

		} while (ret > 0);

	} else {
		unsigned long front = 0;

		/* Fetch data without any memcpy */
		do {

			/* Retrieve and update the buffer's state
			   (In input case, we recover how many bytes are available
			   to read) */
			ret = a4l_mark_bufrw(&dsc, cmd.idx_subd, front, &front);
			if (ret == -ENOENT)
				break;
			else if (ret < 0) {
				fprintf(stderr,
					"cmd_read: a4l_mark_bufrw() failed (ret=%d)\n",
					ret);
				goto out_main;
			}

			/* If there is nothing to read, wait for an event
			   (Note that a4l_poll() also retrieves the data amount
			   to read; in our case it is useless as we have to update
			   the data read counter) */
			if (front == 0) {
				ret = a4l_poll(&dsc, cmd.idx_subd, A4L_INFINITE);
				if (ret == 0)
					break;
				else if (ret < 0) {
					fprintf(stderr,
						"cmd_read: a4l_poll() failed (ret=%d)\n",
						ret);
					goto out_main;
				}
			}

			/* Display the results */
			if (dump_function(&dsc,
					  &cmd,
					  &((unsigned char *)map)[cnt % buf_size],
					  front) < 0) {
				ret = -EIO;
				goto out_main;
			}

			/* Update the counter */
			cnt += front;

		} while (1);
	}

	if (verbose != 0)
		printf("cmd_read: %d bytes successfully received\n", cnt);

	ret = 0;

out_main:

	if (use_mmap != 0)
		/* Clean the pages table */
		munmap(map, buf_size);

	/* Free the buffer used as device descriptor */
	if (dsc.sbdata != NULL)
		free(dsc.sbdata);

	/* Release the file descriptor */
	a4l_close(&dsc);

	return ret;
}
示例#8
0
int dump_text(a4l_desc_t *dsc, a4l_cmd_t *cmd, unsigned char *buf, int size)
{
	static int cur_chan;

	int i, err = 0, tmp_size = 0;
	char *fmts[MAX_NB_CHAN];
	a4l_chinfo_t *chans[MAX_NB_CHAN];

	for (i = 0; i < cmd->nb_chan; i++) {
		int width;

		err = a4l_get_chinfo(dsc,
				     cmd->idx_subd,
				     cmd->chan_descs[i], &chans[i]);
		if (err < 0) {
			fprintf(stderr,
				"cmd_read: a4l_get_chinfo failed (ret=%d)\n",
				err);
			goto out;
		}

		width = a4l_sizeof_chan(chans[i]);
		if (width < 0) {
			fprintf(stderr,
				"cmd_read: incoherent info for channel %d\n",
				cmd->chan_descs[i]);
			err = width;
			goto out;
		}

		switch(width) {
		case 1:
			fmts[i] = "0x%02x ";
			break;
		case 2:
			fmts[i] = "0x%04x ";
			break;
		case 4:
		default:
			fmts[i] = "0x%08x ";
			break;
		}
	}

	while (tmp_size < size) {
		unsigned long value;

		err = a4l_rawtoul(chans[cur_chan], &value, buf + tmp_size, 1);
		if (err < 0)
			goto out;

		fprintf(stdout, fmts[cur_chan], value);

		/* We assume a4l_sizeof_chan() cannot return because
		   we already called it on the very same channel
		   descriptor */
		tmp_size += a4l_sizeof_chan(chans[cur_chan]);

		if(++cur_chan == cmd->nb_chan) {
			fprintf(stdout, "\n");
			cur_chan = 0;
		}
	}

	fflush(stdout);

out:
	return err;
}
示例#9
0
int main(int argc, char *argv[])
{
	int err = 0;
	unsigned int cnt = 0;
	a4l_desc_t dsc = { .sbdata = NULL };
	a4l_sbinfo_t *sbinfo;
	a4l_chinfo_t *chinfo;
	a4l_rnginfo_t *rnginfo;

	int (*dump_function) (a4l_desc_t *, unsigned char *, int) = dump_text;

	/* Compute arguments */
	while ((err = getopt_long(argc,
				  argv,
				  "vrd:s:S:c:R:y:wh", insn_read_opts,
				  NULL)) >= 0) {
		switch (err) {
		case 'v':
			verbose = 1;
			break;
		case 'd':
			filename = optarg;
			break;
		case 's':
			idx_subd = strtoul(optarg, NULL, 0);
			break;
		case 'S':
			scan_size = strtoul(optarg, NULL, 0);
			break;
		case 'c':
			idx_chan = strtoul(optarg, NULL, 0);
			break;
		case 'R':
			idx_rng = strtoul(optarg, NULL, 0);
			dump_function = dump_converted;
			break;
		case 'w':
			dump_function = dump_raw;
			break;
		case 'y':
			dump_function = dump_calibrated;
			calibration_file = optarg;
			break;
		case 'h':
		default:
			do_print_usage();
			return 0;
		}
	}

	if (isatty(STDOUT_FILENO) && dump_function == dump_raw) {
		fprintf(stderr,
			"insn_read: cannot dump raw data on a terminal\n\n");
		return -EINVAL;
	}

	/* Open the device */
	err = a4l_open(&dsc, filename);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: a4l_open %s failed (err=%d)\n",
			filename, err);
		return err;
	}

	if (verbose != 0) {
		printf("insn_read: device %s opened (fd=%d)\n", filename,
		       dsc.fd);
		printf("insn_read: basic descriptor retrieved\n");
		printf("\t subdevices count = %d\n", dsc.nb_subd);
		printf("\t read subdevice index = %d\n", dsc.idx_read_subd);
		printf("\t write subdevice index = %d\n", dsc.idx_write_subd);
	}

	/* Allocate a buffer so as to get more info (subd, chan, rng) */
	dsc.sbdata = malloc(dsc.sbsize);
	if (dsc.sbdata == NULL) {
		err = -ENOMEM;
		fprintf(stderr, "insn_read: info buffer allocation failed\n");
		goto out_insn_read;
	}

	/* Get this data */
	err = a4l_fill_desc(&dsc);
	if (err < 0) {
		fprintf(stderr, "insn_read: a4l_fill_desc failed (err=%d)\n",
			err);
		goto out_insn_read;
	}

	if (verbose != 0)
		printf("insn_read: complex descriptor retrieved\n");

	/* If no subdevice index was set, look for an analog input
	   subdevice */
	if (idx_subd == -1)
		idx_subd = dsc.idx_read_subd;

	if (idx_subd == -1) {
		fprintf(stderr,
			"insn_read: no analog input subdevice available\n");
		err = -EINVAL;
		goto  out_insn_read;
	}

	if (verbose != 0)
		printf("insn_read: selected subdevice index = %d\n", idx_subd);

	/* We must check that the subdevice is really an AI one
	   (in case, the subdevice index was set with the option -s) */
	err = a4l_get_subdinfo(&dsc, idx_subd, &sbinfo);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: get_sbinfo(%d) failed (err = %d)\n",
			idx_subd, err);
		err = -EINVAL;
		goto out_insn_read;
	}

	if ((sbinfo->flags & A4L_SUBD_TYPES) != A4L_SUBD_AI) {
		fprintf(stderr,
			"insn_read: wrong subdevice selected "
			"(not an analog input)\n");
		err = -EINVAL;
		goto out_insn_read;
	}

	if (idx_rng >= 0) {

		err = a4l_get_rnginfo(&dsc,
				      idx_subd, idx_chan, idx_rng, &rnginfo);
		if (err < 0) {
			fprintf(stderr,
				"insn_read: failed to recover range descriptor\n");
			goto out_insn_read;
		}

		if (verbose != 0) {
			printf("insn_read: range descriptor retrieved\n");
			printf("\t min = %ld\n", rnginfo->min);
			printf("\t max = %ld\n", rnginfo->max);
		}
	}

	/* Retrieve the subdevice data size */
	err = a4l_get_chinfo(&dsc, idx_subd, idx_chan, &chinfo);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: info for channel %d on subdevice %d not available (err=%d)\n",
			idx_chan, idx_subd, err);
		goto out_insn_read;
	}

	/* Set the data size to read */
	scan_size *= a4l_sizeof_chan(chinfo);

	if (verbose != 0) {
		printf("insn_read: channel width is %u bits\n",
		       chinfo->nb_bits);
		printf("insn_read: global scan size is %u\n", scan_size);
	}

	while (cnt < scan_size) {
		int tmp = (scan_size - cnt) < BUF_SIZE ?
			(scan_size - cnt) : BUF_SIZE;

		/* Perform the synchronous read */
		err = a4l_sync_read(&dsc,
				    idx_subd, CHAN(idx_chan), 0, buf, tmp);

		if (err < 0) {
			fprintf(stderr,
				"insn_read: a4l_sync_read failed (err=%d)\n",
				err);
			goto out_insn_read;
		}

		/* Dump the read data */
		tmp = dump_function(&dsc, buf, err);
		if (tmp < 0) {
			err = tmp;
			goto out_insn_read;
		}

		/* Update the count */
		cnt += err;
	}

	if (verbose != 0)
		printf("insn_read: %u bytes successfully received\n", cnt);

	err = 0;

out_insn_read:

	/* Free the information buffer */
	if (dsc.sbdata != NULL)
		free(dsc.sbdata);

	/* Release the file descriptor */
	a4l_close(&dsc);

	return err;
}
示例#10
0
static int dump_calibrated(a4l_desc_t *dsc, unsigned char *buf, int size)
{
	struct a4l_calibration_data cal_info;
	struct a4l_polynomial converter;
	int err = 0, width, tmp_size = 0;
	a4l_chinfo_t *chan;
	a4l_rnginfo_t *rng;


	/* Retrieve the channel info */
	err = a4l_get_chinfo(dsc, idx_subd, idx_chan, &chan);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: info for channel %d "
			"on subdevice %d not available (err=%d)\n",
			idx_chan, idx_subd, err);
		goto out;
	}

	/* Retrieve the range info */
	err = a4l_get_rnginfo(dsc, idx_subd, idx_chan, idx_rng, &rng);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: failed to recover range descriptor\n");
		goto out;
	}

	width = a4l_sizeof_chan(chan);
	if (width < 0) {
		fprintf(stderr,
			"insn_read: incoherent info for channel %d\n",
			idx_chan);
		err = width;
		goto out;
	}

	err = a4l_read_calibration_file(calibration_file, &cal_info);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: error reading the calibration file \n");
		goto out;
	}

	err = a4l_get_softcal_converter(&converter, idx_subd, idx_chan, idx_rng,
		                        &cal_info);
	if (err < 0) {
		fprintf(stderr,
			"insn_read: failed to get the softcal converter  \n");
		goto out;
	}

	fprintf(stdout, "Calibrated values: \n");
	while (size - tmp_size > 0) {
		double values[64];
		int i, tmp_cnt = ((size - tmp_size) / width > 64) ?
			64 : ((size - tmp_size) / width);

		err = a4l_rawtodcal(chan, values, buf + tmp_size, tmp_cnt,
			            &converter);
		if (err < 0)
			goto out;

		for (i = 0; i < tmp_cnt; i++)
			fprintf(stdout, "%F\n", values[i]);

		tmp_size += tmp_cnt * width;
	}

out:
	return err;
}