Ejemplo n.º 1
0
/**
 * Close the USB port and reset the sequencer logic.
 *
 * @param devc The struct containing private per-device-instance data.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments.
 */
static int close_usb_reset_sequencer(struct dev_context *devc)
{
	/* Magic sequence of bytes for resetting the sequencer logic. */
	uint8_t buf[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
	int ret;

	/* Note: Caller checked that devc and devc->ftdic != NULL. */

	if (devc->ftdic->usb_dev) {
		/* Reset the sequencer logic, then wait 100ms. */
		sr_dbg("Resetting sequencer logic.");
		(void) cv_write(devc, buf, 8); /* Ignore errors. */
		g_usleep(100 * 1000);

		/* Purge FTDI buffers, then reset and close the FTDI device. */
		sr_dbg("Purging buffers, resetting+closing FTDI device.");

		/* Log errors, but ignore them (i.e., don't abort). */
		if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0)
			sr_err("Failed to purge FTDI buffers (%d): %s.",
			       ret, ftdi_get_error_string(devc->ftdic));
		if ((ret = ftdi_usb_reset(devc->ftdic)) < 0)
			sr_err("Failed to reset FTDI device (%d): %s.",
			       ret, ftdi_get_error_string(devc->ftdic));
		if ((ret = ftdi_usb_close(devc->ftdic)) < 0)
			sr_err("Failed to close FTDI device (%d): %s.",
			       ret, ftdi_get_error_string(devc->ftdic));
	}

	/* Close USB device, deinitialize and free the FTDI context. */
	ftdi_free(devc->ftdic);
	devc->ftdic = NULL;

	return SR_OK;
}
Ejemplo n.º 2
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	uint8_t buf[8];
	int bytes_to_write, bytes_written;

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

	if (!(devc = sdi->priv)) {
		sr_err("sdi->priv was NULL.");
		return SR_ERR_BUG;
	}

	if (!devc->ftdic) {
		sr_err("devc->ftdic was NULL.");
		return SR_ERR_BUG;
	}

	devc->divcount = cv_samplerate_to_divcount(sdi, devc->cur_samplerate);
	if (devc->divcount == 0xff) {
		sr_err("Invalid divcount/samplerate.");
		return SR_ERR;
	}

	if (cv_convert_trigger(sdi) != SR_OK) {
		sr_err("Failed to configure trigger.");
		return SR_ERR;
	}

	/* Fill acquisition parameters into buf[]. */
	if (devc->prof->model == CHRONOVU_LA8) {
		buf[0] = devc->divcount;
		buf[1] = 0xff; /* This byte must always be 0xff. */
		buf[2] = devc->trigger_pattern & 0xff;
		buf[3] = devc->trigger_mask & 0xff;
		bytes_to_write = 4;
	} else {
		buf[0] = devc->divcount;
		buf[1] = 0xff; /* This byte must always be 0xff. */
		buf[2] = (devc->trigger_pattern & 0xff00) >> 8;  /* LSB */
		buf[3] = (devc->trigger_pattern & 0x00ff) >> 0;  /* MSB */
		buf[4] = (devc->trigger_mask & 0xff00) >> 8;     /* LSB */
		buf[5] = (devc->trigger_mask & 0x00ff) >> 0;     /* MSB */
		buf[6] = (devc->trigger_edgemask & 0xff00) >> 8; /* LSB */
		buf[7] = (devc->trigger_edgemask & 0x00ff) >> 0; /* MSB */
		bytes_to_write = 8;
	}

	/* Start acquisition. */
	bytes_written = cv_write(devc, buf, bytes_to_write);

	if (bytes_written < 0 || bytes_written != bytes_to_write) {
		sr_err("Acquisition failed to start.");
		return SR_ERR;
	}

	sr_dbg("Hardware acquisition started successfully.");

	devc->cb_data = cb_data;

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

	/* Time when we should be done (for detecting trigger timeouts). */
	devc->done = (devc->divcount + 1) * devc->prof->trigger_constant +
			g_get_monotonic_time() + (10 * G_TIME_SPAN_SECOND);
	devc->block_counter = 0;
	devc->trigger_found = 0;

	/* Hook up a dummy handler to receive data from the device. */
	sr_session_source_add(sdi->session, -1, G_IO_IN, 0, receive_data, (void *)sdi);

	return SR_OK;
}