SR_PRIV int cv_convert_trigger(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_trigger *trigger;
	struct sr_trigger_stage *stage;
	struct sr_trigger_match *match;
	const GSList *l, *m;
	uint16_t channel_bit;

	devc = sdi->priv;
	devc->trigger_pattern = 0x0000; /* Default to "low" trigger. */
	devc->trigger_mask = 0x0000; /* Default to "don't care". */
	devc->trigger_edgemask = 0x0000; /* Default to "state triggered". */

	if (!(trigger = sr_session_trigger_get(sdi->session)))
		return SR_OK;

	if (g_slist_length(trigger->stages) > 1) {
		sr_err("This device only supports 1 trigger stage.");
		return SR_ERR;
	}

	for (l = trigger->stages; l; l = l->next) {
		stage = l->data;
		for (m = stage->matches; m; m = m->next) {
			match = m->data;
			if (!match->channel->enabled)
				/* Ignore disabled channels with a trigger. */
				continue;
			if (devc->prof->model == CHRONOVU_LA8 &&
					(match->match == SR_TRIGGER_RISING
					|| match->match == SR_TRIGGER_FALLING)) {
				sr_err("This model supports only simple triggers.");
				return SR_ERR;
			}
			channel_bit = (1 << (match->channel->index));

			/* state: 1 == high, edge: 1 == rising edge. */
			if (match->match == SR_TRIGGER_ONE
					|| match->match == SR_TRIGGER_RISING)
				devc->trigger_pattern |= channel_bit;

			/* LA16 (but not LA8) supports edge triggering. */
			if ((devc->prof->model == CHRONOVU_LA16)) {
				if (match->match == SR_TRIGGER_RISING
						|| match->match == SR_TRIGGER_FALLING)
						devc->trigger_edgemask |= channel_bit;
			}
		}
	}

	sr_dbg("Trigger pattern/mask/edgemask = 0x%04x / 0x%04x / 0x%04x.",
			devc->trigger_pattern, devc->trigger_mask,
			devc->trigger_edgemask);

	return SR_OK;
}
示例#2
0
END_TEST

START_TEST(test_session_trigger_get_null)
{
	struct sr_trigger *t;

	/* NULL session, must not segfault. */
	t = sr_session_trigger_get(NULL);
	fail_unless(t == NULL);
}
示例#3
0
END_TEST

START_TEST(test_session_trigger_set_get_null)
{
	int ret;
	struct sr_session *sess;
	struct sr_trigger *t;

	sr_session_new(srtest_ctx, &sess);

	/* Adding a NULL trigger is allowed. */
	ret = sr_session_trigger_set(sess, NULL);
	fail_unless(ret == SR_OK);
	t = sr_session_trigger_get(sess);
	fail_unless(t == NULL);

	sr_session_destroy(sess);
}
示例#4
0
END_TEST

START_TEST(test_session_trigger_set_get)
{
	int ret;
	struct sr_session *sess;
	struct sr_trigger *t1, *t2;

	sr_session_new(srtest_ctx, &sess);
	t1 = sr_trigger_new("T1");

	/* Set a trigger and see if getting it works OK. */
	ret = sr_session_trigger_set(sess, t1);
	fail_unless(ret == SR_OK);
	t2 = sr_session_trigger_get(sess);
	fail_unless(t2 != NULL);
	fail_unless(t1 == t2);
	fail_unless(g_slist_length(t1->stages) == g_slist_length(t2->stages));
	fail_unless(!strcmp(t1->name, t2->name));

	sr_session_destroy(sess);
}
示例#5
0
static int start_transfers(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct sr_trigger *trigger;
	struct libusb_transfer *transfer;
	unsigned int i, num_transfers;
	int timeout, ret;
	unsigned char *buf;
	size_t size;

	devc = sdi->priv;
	usb = sdi->conn;

	devc->sent_samples = 0;
	devc->acq_aborted = FALSE;
	devc->empty_transfer_count = 0;

	if ((trigger = sr_session_trigger_get(sdi->session))) {
		int pre_trigger_samples = 0;
		if (devc->limit_samples > 0)
			pre_trigger_samples = (devc->capture_ratio * devc->limit_samples) / 100;
		devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
		if (!devc->stl)
			return SR_ERR_MALLOC;
		devc->trigger_fired = FALSE;
	} else
		devc->trigger_fired = TRUE;

	num_transfers = get_number_of_transfers(devc);

	size = get_buffer_size(devc);
	devc->submitted_transfers = 0;

	devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
	if (!devc->transfers) {
		sr_err("USB transfers malloc failed.");
		return SR_ERR_MALLOC;
	}

	timeout = get_timeout(devc);
	devc->num_transfers = num_transfers;
	for (i = 0; i < num_transfers; i++) {
		if (!(buf = g_try_malloc(size))) {
			sr_err("USB transfer buffer malloc failed.");
			return SR_ERR_MALLOC;
		}
		transfer = libusb_alloc_transfer(0);
		libusb_fill_bulk_transfer(transfer, usb->devhdl,
				2 | LIBUSB_ENDPOINT_IN, buf, size,
				receive_transfer, (void *)sdi, timeout);
		sr_info("submitting transfer: %d", i);
		if ((ret = libusb_submit_transfer(transfer)) != 0) {
			sr_err("Failed to submit transfer: %s.",
			       libusb_error_name(ret));
			libusb_free_transfer(transfer);
			g_free(buf);
			fx2lafw_abort_acquisition(devc);
			return SR_ERR;
		}
		devc->transfers[i] = transfer;
		devc->submitted_transfers++;
	}

	/*
	 * If this device has analog channels and at least one of them is
	 * enabled, use mso_send_data_proc() to properly handle the analog
	 * data. Otherwise use la_send_data_proc().
	 */
	if (g_slist_length(devc->enabled_analog_channels) > 0)
		devc->send_data_proc = mso_send_data_proc;
	else
		devc->send_data_proc = la_send_data_proc;

	std_session_send_df_header(sdi);

	return SR_OK;
}
示例#6
0
文件: api.c 项目: anatol/libsigrok
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	struct sr_dev_driver *di = sdi->driver;
	struct dev_context *devc;
	struct drv_context *drvc;
	struct sr_usb_dev_inst *usb;
	struct sr_trigger *trigger;
	struct libusb_transfer *transfer;
	unsigned int i, timeout, num_transfers;
	int ret;
	unsigned char *buf;
	size_t size, convsize;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	drvc = di->priv;
	devc = sdi->priv;
	usb = sdi->conn;

	/* Configures devc->cur_channels. */
	if (configure_channels(sdi) != SR_OK) {
		sr_err("Failed to configure channels.");
		return SR_ERR;
	}

	devc->cb_data = cb_data;
	devc->sent_samples = 0;
	devc->empty_transfer_count = 0;
	devc->cur_channel = 0;
	memset(devc->channel_data, 0, sizeof(devc->channel_data));

	if ((trigger = sr_session_trigger_get(sdi->session))) {
		int pre_trigger_samples = 0;
		if (devc->limit_samples > 0)
			pre_trigger_samples = devc->capture_ratio * devc->limit_samples/100;
		devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
		if (!devc->stl)
			return SR_ERR_MALLOC;
		devc->trigger_fired = FALSE;
	} else
		devc->trigger_fired = TRUE;

	timeout = get_timeout(devc);
	num_transfers = get_number_of_transfers(devc);
	size = get_buffer_size(devc);
	convsize = (size / devc->num_channels + 2) * 16;
	devc->submitted_transfers = 0;

	devc->convbuffer_size = convsize;
	if (!(devc->convbuffer = g_try_malloc(convsize))) {
		sr_err("Conversion buffer malloc failed.");
		return SR_ERR_MALLOC;
	}

	devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
	if (!devc->transfers) {
		sr_err("USB transfers malloc failed.");
		g_free(devc->convbuffer);
		return SR_ERR_MALLOC;
	}

	if ((ret = logic16_setup_acquisition(sdi, devc->cur_samplerate,
					     devc->cur_channels)) != SR_OK) {
		g_free(devc->transfers);
		g_free(devc->convbuffer);
		return ret;
	}

	devc->num_transfers = num_transfers;
	for (i = 0; i < num_transfers; i++) {
		if (!(buf = g_try_malloc(size))) {
			sr_err("USB transfer buffer malloc failed.");
			if (devc->submitted_transfers)
				abort_acquisition(devc);
			else {
				g_free(devc->transfers);
				g_free(devc->convbuffer);
			}
			return SR_ERR_MALLOC;
		}
		transfer = libusb_alloc_transfer(0);
		libusb_fill_bulk_transfer(transfer, usb->devhdl,
				2 | LIBUSB_ENDPOINT_IN, buf, size,
				logic16_receive_transfer, (void *)sdi, timeout);
		if ((ret = libusb_submit_transfer(transfer)) != 0) {
			sr_err("Failed to submit transfer: %s.",
			       libusb_error_name(ret));
			libusb_free_transfer(transfer);
			g_free(buf);
			abort_acquisition(devc);
			return SR_ERR;
		}
		devc->transfers[i] = transfer;
		devc->submitted_transfers++;
	}

	devc->ctx = drvc->sr_ctx;

	usb_source_add(sdi->session, devc->ctx, timeout, receive_data, (void *)sdi);

	/* Send header packet to the session bus. */
	std_session_send_df_header(cb_data, LOG_PREFIX);

	if ((ret = logic16_start_acquisition(sdi)) != SR_OK) {
		abort_acquisition(devc);
		return ret;
	}

	return SR_OK;
}
示例#7
0
文件: api.c 项目: DeeJay/libsigrok
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	struct drv_context *drvc;
	struct sr_usb_dev_inst *usb;
	struct sr_trigger *trigger;
	struct libusb_transfer *transfer;
	unsigned int i, timeout, num_transfers;
	int ret;
	unsigned char *buf;
	size_t size;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	drvc = di->priv;
	devc = sdi->priv;
	usb = sdi->conn;

	devc->cb_data = cb_data;
	devc->sent_samples = 0;
	devc->acq_aborted = FALSE;
	devc->empty_transfer_count = 0;

	if ((trigger = sr_session_trigger_get())) {
		devc->stl = soft_trigger_logic_new(sdi, trigger);
		devc->trigger_fired = FALSE;
	} else
		devc->trigger_fired = TRUE;

	timeout = fx2lafw_get_timeout(devc);
	num_transfers = fx2lafw_get_number_of_transfers(devc);
	size = fx2lafw_get_buffer_size(devc);
	devc->submitted_transfers = 0;

	devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
	if (!devc->transfers) {
		sr_err("USB transfers malloc failed.");
		return SR_ERR_MALLOC;
	}

	devc->num_transfers = num_transfers;
	for (i = 0; i < num_transfers; i++) {
		if (!(buf = g_try_malloc(size))) {
			sr_err("USB transfer buffer malloc failed.");
			return SR_ERR_MALLOC;
		}
		transfer = libusb_alloc_transfer(0);
		libusb_fill_bulk_transfer(transfer, usb->devhdl,
				2 | LIBUSB_ENDPOINT_IN, buf, size,
				fx2lafw_receive_transfer, (void *)sdi, timeout);
		if ((ret = libusb_submit_transfer(transfer)) != 0) {
			sr_err("Failed to submit transfer: %s.",
			       libusb_error_name(ret));
			libusb_free_transfer(transfer);
			g_free(buf);
			fx2lafw_abort_acquisition(devc);
			return SR_ERR;
		}
		devc->transfers[i] = transfer;
		devc->submitted_transfers++;
	}

	devc->ctx = drvc->sr_ctx;

	usb_source_add(devc->ctx, timeout, receive_data, NULL);

	/* Send header packet to the session bus. */
	std_session_send_df_header(cb_data, LOG_PREFIX);

	if ((ret = fx2lafw_command_start_acquisition(sdi)) != SR_OK) {
		fx2lafw_abort_acquisition(devc);
		return ret;
	}

	return SR_OK;
}