Пример #1
0
/*
 * Waiting for a event will return a timeout after 2 to 3 seconds in order
 * to not block the application.
 */
static int rigol_ds_event_wait(const struct sr_dev_inst *sdi, char status1, char status2)
{
	char *buf;
	struct dev_context *devc;
	time_t start;

	if (!(devc = sdi->priv))
		return SR_ERR;

	start = time(NULL);

	/*
	 * Trigger status may return:
	 * "TD" or "T'D" - triggered
	 * "AUTO"        - autotriggered
	 * "RUN"         - running
	 * "WAIT"        - waiting for trigger
	 * "STOP"        - stopped
	 */

	if (devc->wait_status == 1) {
		do {
			if (time(NULL) - start >= 3) {
				sr_dbg("Timeout waiting for trigger");
				return SR_ERR_TIMEOUT;
			}

			if (sr_scpi_get_string(sdi->conn, ":TRIG:STAT?", &buf) != SR_OK)
				return SR_ERR;
		} while (buf[0] == status1 || buf[0] == status2);

		devc->wait_status = 2;
	}
	if (devc->wait_status == 2) {
		do {
			if (time(NULL) - start >= 3) {
				sr_dbg("Timeout waiting for trigger");
				return SR_ERR_TIMEOUT;
			}

			if (sr_scpi_get_string(sdi->conn, ":TRIG:STAT?", &buf) != SR_OK)
				return SR_ERR;
		} while (buf[0] != status1 && buf[0] != status2);

		rigol_ds_set_wait_event(devc, WAIT_NONE);
	}

	return SR_OK;
}
Пример #2
0
SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, const struct scpi_command *cmdtable,
		GVariant **gvar, const GVariantType *gvtype, int command, ...)
{
	struct sr_scpi_dev_inst *scpi;
	va_list args;
	double d;
	int ret;
	char *s;
	const char *cmd;

	if (!(cmd = scpi_cmd_get(cmdtable, command))) {
		/* Device does not implement this command, that's OK. */
		return SR_OK;
	}

	scpi = sdi->conn;
	va_start(args, command);
	ret = sr_scpi_send_variadic(scpi, cmd, args);
	va_end(args);
	if (ret != SR_OK)
		return ret;

	/* Straight SCPI getters to GVariant types. */
	if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_BOOLEAN)) {
		if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK)
			return ret;
		if (!g_ascii_strcasecmp(s, "ON") || !g_ascii_strcasecmp(s, "1")
				|| !g_ascii_strcasecmp(s, "YES"))
			*gvar = g_variant_new_boolean(TRUE);
		else if (!g_ascii_strcasecmp(s, "OFF") || !g_ascii_strcasecmp(s, "0")
				|| !g_ascii_strcasecmp(s, "NO"))
			*gvar = g_variant_new_boolean(FALSE);
		else
			ret = SR_ERR;
		g_free(s);
	} if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_DOUBLE)) {
		if ((ret = sr_scpi_get_double(scpi, NULL, &d)) == SR_OK)
			*gvar = g_variant_new_double(d);
	} if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_STRING)) {
		if ((ret = sr_scpi_get_string(scpi, NULL, &s)) == SR_OK)
			*gvar = g_variant_new_string(s);
	} else {
		sr_err("Unable to convert to desired GVariant type.");
		ret = SR_ERR_NA;
	}

	return ret;
}
Пример #3
0
static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
		const char *command, const char *(*array)[], int *result)
{
	char *tmp;
	unsigned int i;

	if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
		g_free(tmp);
		return SR_ERR;
	}

	for (i = 0; (*array)[i]; ++i) {
		if (!g_strcmp0(tmp, (*array)[i])) {
			*result = i;
			g_free(tmp);
			tmp = NULL;
			break;
		}
	}

	if (tmp) {
		g_free(tmp);
		return SR_ERR;
	}

	return SR_OK;
}
Пример #4
0
/**
 * Send the *IDN? SCPI command, receive the reply, parse it and store the
 * reply as a sr_scpi_hw_info structure in the supplied scpi_response pointer.
 *
 * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param scpi_response Pointer where to store the hw_info structure.
 *
 * @return SR_OK upon success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
			      struct sr_scpi_hw_info **scpi_response)
{
	int num_tokens;
	char *response;
	char *newline;
	gchar **tokens;
	struct sr_scpi_hw_info *hw_info;

	response = NULL;
	tokens = NULL;

	if (sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response) != SR_OK)
		if (!response)
			return SR_ERR;

	sr_info("Got IDN string: '%s'", response);

	/* Remove trailing newline if present. */
	if ((newline = g_strrstr(response, "\n")))
		newline[0] = '\0';

	/*
	 * The response to a '*IDN?' is specified by the SCPI spec. It contains
	 * a comma-separated list containing the manufacturer name, instrument
	 * model, serial number of the instrument and the firmware version.
	 */
	tokens = g_strsplit(response, ",", 0);

	for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);

	if (num_tokens != 4) {
		sr_dbg("IDN response not according to spec: %80.s.", response);
		g_strfreev(tokens);
		g_free(response);
		return SR_ERR;
	}
	g_free(response);

	hw_info = g_try_malloc(sizeof(struct sr_scpi_hw_info));
	if (!hw_info) {
		g_strfreev(tokens);
		return SR_ERR_MALLOC;
	}

	hw_info->manufacturer = g_strdup(tokens[0]);
	hw_info->model = g_strdup(tokens[1]);
	hw_info->serial_number = g_strdup(tokens[2]);
	hw_info->firmware_version = g_strdup(tokens[3]);

	g_strfreev(tokens);

	*scpi_response = hw_info;

	return SR_OK;
}
Пример #5
0
/**
 * Send the *IDN? SCPI command, receive the reply, parse it and store the
 * reply as a sr_scpi_hw_info structure in the supplied scpi_response pointer.
 *
 * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param scpi_response Pointer where to store the hw_info structure.
 *
 * @return SR_OK upon success, SR_ERR* on failure.
 */
SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
			      struct sr_scpi_hw_info **scpi_response)
{
	int num_tokens, ret;
	char *response;
	gchar **tokens;
	struct sr_scpi_hw_info *hw_info;

	response = NULL;
	tokens = NULL;

	ret = sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response);
	if (ret != SR_OK && !response)
		return ret;

	sr_info("Got IDN string: '%s'", response);

	/*
	 * The response to a '*IDN?' is specified by the SCPI spec. It contains
	 * a comma-separated list containing the manufacturer name, instrument
	 * model, serial number of the instrument and the firmware version.
	 */
	tokens = g_strsplit(response, ",", 0);

	for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);

	if (num_tokens < 4) {
		sr_dbg("IDN response not according to spec: %80.s.", response);
		g_strfreev(tokens);
		g_free(response);
		return SR_ERR_DATA;
	}
	g_free(response);

	hw_info = g_malloc0(sizeof(struct sr_scpi_hw_info));
	hw_info->manufacturer = g_strstrip(g_strdup(tokens[0]));
	hw_info->model = g_strstrip(g_strdup(tokens[1]));
	hw_info->serial_number = g_strstrip(g_strdup(tokens[2]));
	hw_info->firmware_version = g_strstrip(g_strdup(tokens[3]));

	g_strfreev(tokens);

	*scpi_response = hw_info;

	return SR_OK;
}
Пример #6
0
/**
 * Send a SCPI command, read the reply, parse it as comma separated list of
 * floats and store the as an result in scpi_response.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
 * @return SR_OK upon successfully parsing all values, SR_ERR upon a parsing
 *         error or upon no response. The allocated response must be freed by
 *         the caller in the case of an SR_OK as well as in the case of
 *         parsing error.
 */
SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
			       const char *command, GArray **scpi_response)
{
	int ret;
	float tmp;
	char *response;
	gchar **ptr, **tokens;
	GArray *response_array;

	ret = SR_OK;
	response = NULL;
	tokens = NULL;

	if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
		if (!response)
			return SR_ERR;

	tokens = g_strsplit(response, ",", 0);
	ptr = tokens;

	response_array = g_array_sized_new(TRUE, FALSE, sizeof(float), 256);

	while (*ptr) {
		if (sr_atof(*ptr, &tmp) == SR_OK)
			response_array = g_array_append_val(response_array,
							    tmp);
		else
			ret = SR_ERR;

		ptr++;
	}
	g_strfreev(tokens);
	g_free(response);

	if (ret == SR_ERR && response_array->len == 0) {
		g_array_free(response_array, TRUE);
		*scpi_response = NULL;
		return SR_ERR;
	}

	*scpi_response = response_array;

	return ret;
}
Пример #7
0
/* Wait for enough data becoming available in scope output buffer */
static int rigol_ds_block_wait(const struct sr_dev_inst *sdi)
{
	char *buf;
	struct dev_context *devc;
	time_t start;
	int len;

	if (!(devc = sdi->priv))
		return SR_ERR;

	if (devc->model->series->protocol == PROTOCOL_V3) {

		start = time(NULL);

		do {
			if (time(NULL) - start >= 3) {
				sr_dbg("Timeout waiting for data block");
				return SR_ERR_TIMEOUT;
			}

			/*
			 * The scope copies data really slowly from sample
			 * memory to its output buffer, so try not to bother
			 * it too much with SCPI requests but don't wait too
			 * long for short sample frame sizes.
			 */
			g_usleep(devc->analog_frame_size < (15 * 1000) ? (100 * 1000) : (1000 * 1000));

			/* "READ,nnnn" (still working) or "IDLE,nnnn" (finished) */
			if (sr_scpi_get_string(sdi->conn, ":WAV:STAT?", &buf) != SR_OK)
				return SR_ERR;

			if (parse_int(buf + 5, &len) != SR_OK)
				return SR_ERR;
		} while (buf[0] == 'R' && len < (1000 * 1000));
	}

	rigol_ds_set_wait_event(devc, WAIT_NONE);

	return SR_OK;
}
Пример #8
0
/**
 * Send a SCPI command, read the reply, parse it as a double and store the
 * result in scpi_response.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
 * @return SR_OK on success, SR_ERR* on failure.
 */
SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
			       const char *command, double *scpi_response)
{
	int ret;
	char *response;

	response = NULL;

	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;

	if (sr_atod(response, scpi_response) == SR_OK)
		ret = SR_OK;
	else
		ret = SR_ERR_DATA;

	g_free(response);

	return ret;
}
Пример #9
0
/**
 * Send a SCPI command, read the reply, parse it as a bool value and store the
 * result in scpi_response.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
 * @return SR_OK on success, SR_ERR* on failure.
 */
SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
			     const char *command, gboolean *scpi_response)
{
	int ret;
	char *response;

	response = NULL;

	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;

	if (parse_strict_bool(response, scpi_response) == SR_OK)
		ret = SR_OK;
	else
		ret = SR_ERR_DATA;

	g_free(response);

	return ret;
}
Пример #10
0
/**
 * Send a SCPI command, read the reply, parse it as a float and store the
 * result in scpi_response.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
			      const char *command, float *scpi_response)
{
	int ret;
	char *response;

	response = NULL;

	if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
		if (!response)
			return SR_ERR;

	if (sr_atof(response, scpi_response) == SR_OK)
		ret = SR_OK;
	else
		ret = SR_ERR;

	g_free(response);

	return ret;
}
Пример #11
0
SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	char *cmd;
	unsigned int i;
	int res;

	devc = sdi->priv;

	/* Analog channel state. */
	for (i = 0; i < devc->model->analog_channels; i++) {
		cmd = g_strdup_printf(":CHAN%d:DISP?", i + 1);
		res = sr_scpi_get_bool(sdi->conn, cmd, &devc->analog_channels[i]);
		g_free(cmd);
		if (res != SR_OK)
			return SR_ERR;
	}
	sr_dbg("Current analog channel state:");
	for (i = 0; i < devc->model->analog_channels; i++)
		sr_dbg("CH%d %s", i + 1, devc->analog_channels[i] ? "on" : "off");

	/* Digital channel state. */
	if (devc->model->has_digital) {
		if (sr_scpi_get_bool(sdi->conn,
				devc->model->series->protocol >= PROTOCOL_V4 ?
					":LA:STAT?" : ":LA:DISP?",
				&devc->la_enabled) != SR_OK)
			return SR_ERR;
		sr_dbg("Logic analyzer %s, current digital channel state:",
				devc->la_enabled ? "enabled" : "disabled");
		for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
			cmd = g_strdup_printf(
				devc->model->series->protocol >= PROTOCOL_V4 ?
					":LA:DIG%d:DISP?" : ":DIG%d:TURN?", i);
			res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]);
			g_free(cmd);
			if (res != SR_OK)
				return SR_ERR;
			sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "on" : "off");
		}
	}

	/* Timebase. */
	if (sr_scpi_get_float(sdi->conn, ":TIM:SCAL?", &devc->timebase) != SR_OK)
		return SR_ERR;
	sr_dbg("Current timebase %g", devc->timebase);

	/* Vertical gain. */
	for (i = 0; i < devc->model->analog_channels; i++) {
		cmd = g_strdup_printf(":CHAN%d:SCAL?", i + 1);
		res = sr_scpi_get_float(sdi->conn, cmd, &devc->vdiv[i]);
		g_free(cmd);
		if (res != SR_OK)
			return SR_ERR;
	}
	sr_dbg("Current vertical gain:");
	for (i = 0; i < devc->model->analog_channels; i++)
		sr_dbg("CH%d %g", i + 1, devc->vdiv[i]);

	/* Vertical offset. */
	for (i = 0; i < devc->model->analog_channels; i++) {
		cmd = g_strdup_printf(":CHAN%d:OFFS?", i + 1);
		res = sr_scpi_get_float(sdi->conn, cmd, &devc->vert_offset[i]);
		g_free(cmd);
		if (res != SR_OK)
			return SR_ERR;
	}
	sr_dbg("Current vertical offset:");
	for (i = 0; i < devc->model->analog_channels; i++)
		sr_dbg("CH%d %g", i + 1, devc->vert_offset[i]);

	/* Coupling. */
	for (i = 0; i < devc->model->analog_channels; i++) {
		cmd = g_strdup_printf(":CHAN%d:COUP?", i + 1);
		res = sr_scpi_get_string(sdi->conn, cmd, &devc->coupling[i]);
		g_free(cmd);
		if (res != SR_OK)
			return SR_ERR;
	}
	sr_dbg("Current coupling:");
	for (i = 0; i < devc->model->analog_channels; i++)
		sr_dbg("CH%d %s", i + 1, devc->coupling[i]);

	/* Trigger source. */
	if (sr_scpi_get_string(sdi->conn, ":TRIG:EDGE:SOUR?", &devc->trigger_source) != SR_OK)
		return SR_ERR;
	sr_dbg("Current trigger source %s", devc->trigger_source);

	/* Horizontal trigger position. */
	if (sr_scpi_get_float(sdi->conn, ":TIM:OFFS?", &devc->horiz_triggerpos) != SR_OK)
		return SR_ERR;
	sr_dbg("Current horizontal trigger position %g", devc->horiz_triggerpos);

	/* Trigger slope. */
	if (sr_scpi_get_string(sdi->conn, ":TRIG:EDGE:SLOP?", &devc->trigger_slope) != SR_OK)
		return SR_ERR;
	sr_dbg("Current trigger slope %s", devc->trigger_slope);

	return SR_OK;
}
Пример #12
0
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	const GVariantType *gvtype;
	unsigned int i;
	int cmd, ret;
	char *s;

	if (!sdi)
		return SR_ERR_ARG;

	devc = sdi->priv;

	if (cg) {
		/*
		 * These options only apply to channel groups with a single
		 * channel -- they're per-channel settings for the device.
		 */

		/*
		 * Config keys are handled below depending on whether a channel
		 * group was provided by the frontend. However some of these
		 * take a CG on one PPS but not on others. Check the device's
		 * profile for that here, and NULL out the channel group as needed.
		 */
		for (i = 0; i < devc->device->num_devopts; i++) {
			if (devc->device->devopts[i] == key) {
				cg = NULL;
				break;
			}
		}
	}

	gvtype = NULL;
	cmd = -1;
	switch (key) {
	case SR_CONF_ENABLED:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OUTPUT_ENABLED;
		break;
	case SR_CONF_VOLTAGE:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
		break;
	case SR_CONF_VOLTAGE_TARGET:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_VOLTAGE_TARGET;
		break;
	case SR_CONF_OUTPUT_FREQUENCY:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
		break;
	case SR_CONF_OUTPUT_FREQUENCY_TARGET:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_FREQUENCY_TARGET;
		break;
	case SR_CONF_CURRENT:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_MEAS_CURRENT;
		break;
	case SR_CONF_CURRENT_LIMIT:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_CURRENT_LIMIT;
		break;
	case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ENABLED;
		break;
	case SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE;
		break;
	case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD;
		break;
	case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED;
		break;
	case SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE;
		break;
	case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
		gvtype = G_VARIANT_TYPE_DOUBLE;
		cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD;
		break;
	case SR_CONF_OVER_TEMPERATURE_PROTECTION:
		gvtype = G_VARIANT_TYPE_BOOLEAN;
		cmd = SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION;
		break;
	case SR_CONF_REGULATION:
		gvtype = G_VARIANT_TYPE_STRING;
		cmd = SCPI_CMD_GET_OUTPUT_REGULATION;
	}
	if (!gvtype)
		return SR_ERR_NA;

	if (cg)
		select_channel(sdi, cg->channels->data);
	ret = scpi_cmd_resp(sdi, devc->device->commands, data, gvtype, cmd);

	if (cmd == SCPI_CMD_GET_OUTPUT_REGULATION) {
		/*
		 * The Rigol DP800 series return CV/CC/UR, Philips PM2800
		 * return VOLT/CURR. We always return a GVariant string in
		 * the Rigol notation.
		 */
		if ((ret = sr_scpi_get_string(sdi->conn, NULL, &s)) != SR_OK)
			return ret;
		if (!strcmp(s, "CV") || !strcmp(s, "VOLT")) {
			*data = g_variant_new_string("CV");
		} else if (!strcmp(s, "CC") || !strcmp(s, "CURR")) {
			*data = g_variant_new_string("CC");
		} else if (!strcmp(s, "UR")) {
			*data = g_variant_new_string("UR");
		} else {
			sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
			ret = SR_ERR_DATA;
		}
		g_free(s);
	}

	return ret;
}
Пример #13
0
/* Start capturing a new frameset */
SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	gchar *trig_mode;
	unsigned int num_channels, i, j;

	if (!(devc = sdi->priv))
		return SR_ERR;

	sr_dbg("Starting data capture for frameset %" PRIu64 " of %" PRIu64,
	       devc->num_frames + 1, devc->limit_frames);

	switch (devc->model->series->protocol) {
	case PROTOCOL_V1:
		rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
		break;
	case PROTOCOL_V2:
		if (devc->data_source == DATA_SOURCE_LIVE) {
			if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE NORMAL") != SR_OK)
				return SR_ERR;
			rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
		} else {
			if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
				return SR_ERR;
			if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE RAW") != SR_OK)
				return SR_ERR;
			if (sr_scpi_get_string(sdi->conn, ":TRIG:MODE?", &trig_mode) != SR_OK)
				return SR_ERR;
			if (rigol_ds_config_set(sdi, ":TRIG:%s:SWE SING", trig_mode) != SR_OK)
				return SR_ERR;
			if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
				return SR_ERR;
			rigol_ds_set_wait_event(devc, WAIT_STOP);
		}
		break;
	case PROTOCOL_V3:
	case PROTOCOL_V4:
		if (rigol_ds_config_set(sdi, ":WAV:FORM BYTE") != SR_OK)
			return SR_ERR;
		if (devc->data_source == DATA_SOURCE_LIVE) {
			if (rigol_ds_config_set(sdi, ":WAV:MODE NORM") != SR_OK)
				return SR_ERR;
			devc->analog_frame_size = devc->model->series->live_samples;
			devc->digital_frame_size = devc->model->series->live_samples;
			rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
		} else {
			if (devc->model->series->protocol == PROTOCOL_V3) {
				if (rigol_ds_config_set(sdi, ":WAV:MODE RAW") != SR_OK)
					return SR_ERR;
			} else if (devc->model->series->protocol == PROTOCOL_V4) {
				num_channels = 0;

				/* Channels 3 and 4 are multiplexed with D0-7 and D8-15 */
				for (i = 0; i < devc->model->analog_channels; i++) {
					if (devc->analog_channels[i]) {
						num_channels++;
					} else if (i >= 2 && devc->model->has_digital) {
						for (j = 0; j < 8; j++) {
							if (devc->digital_channels[8 * (i - 2) + j]) {
								num_channels++;
								break;
							}
						}
					}
				}

				devc->analog_frame_size = devc->digital_frame_size =
					num_channels == 1 ?
						devc->model->series->buffer_samples :
							num_channels == 2 ?
								devc->model->series->buffer_samples / 2 :
								devc->model->series->buffer_samples / 4;
			}

			if (rigol_ds_config_set(sdi, ":SING") != SR_OK)
				return SR_ERR;
			rigol_ds_set_wait_event(devc, WAIT_STOP);
		}
		break;
	}

	return SR_OK;
}
Пример #14
0
static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
				    const struct scope_config *config,
				    struct scope_state *state)
{
	unsigned int i, j;
	char command[MAX_COMMAND_SIZE];
	char *tmp_str;

	for (i = 0; i < config->analog_channels; i++) {
		g_snprintf(command, sizeof(command),
			   (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
			   i + 1);

		if (sr_scpi_get_bool(scpi, command,
				     &state->analog_channels[i].state) != SR_OK)
			return SR_ERR;

		g_snprintf(command, sizeof(command),
			   (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
			   i + 1);

		if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
			return SR_ERR;

		if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
				&j) != SR_OK) {
			g_free(tmp_str);
			sr_err("Could not determine array index for vertical div scale.");
			return SR_ERR;
		}

		g_free(tmp_str);
		state->analog_channels[i].vdiv = j;

		g_snprintf(command, sizeof(command),
			   (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
			   i + 1);

		if (sr_scpi_get_float(scpi, command,
				     &state->analog_channels[i].vertical_offset) != SR_OK)
			return SR_ERR;

		g_snprintf(command, sizeof(command),
			   (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
			   i + 1);

		if (scope_state_get_array_option(scpi, command, config->coupling_options,
					 &state->analog_channels[i].coupling) != SR_OK)
			return SR_ERR;

		g_snprintf(command, sizeof(command),
			   (*config->scpi_dialect)[SCPI_CMD_GET_PROBE_UNIT],
			   i + 1);

		if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
			return SR_ERR;

		if (tmp_str[0] == 'A')
			state->analog_channels[i].probe_unit = 'A';
		else
			state->analog_channels[i].probe_unit = 'V';
		g_free(tmp_str);
	}

	return SR_OK;
}
Пример #15
0
SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct scope_state *state;
	const struct scope_config *config;
	float tmp_float;
	unsigned int i;
	char *tmp_str;

	devc = sdi->priv;
	config = devc->model_config;
	state = devc->model_state;

	sr_info("Fetching scope state");

	if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
		return SR_ERR;

	if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
		return SR_ERR;

	if (sr_scpi_get_float(sdi->conn,
			(*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
			&tmp_float) != SR_OK)
		return SR_ERR;

	if (sr_scpi_get_string(sdi->conn,
			(*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
			&tmp_str) != SR_OK)
		return SR_ERR;

	if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
			&i) != SR_OK) {
		g_free(tmp_str);
		sr_err("Could not determine array index for time base.");
		return SR_ERR;
	}
	g_free(tmp_str);

	state->timebase = i;

	if (sr_scpi_get_float(sdi->conn,
			(*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
			&tmp_float) != SR_OK)
		return SR_ERR;
	state->horiz_triggerpos = tmp_float /
		(((double) (*config->timebases)[state->timebase][0] /
		  (*config->timebases)[state->timebase][1]) * config->num_xdivs);
	state->horiz_triggerpos -= 0.5;
	state->horiz_triggerpos *= -1;

	if (scope_state_get_array_option(sdi->conn,
			(*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
			config->trigger_sources, &state->trigger_source) != SR_OK)
		return SR_ERR;

	if (scope_state_get_array_option(sdi->conn,
		(*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
		config->trigger_slopes, &state->trigger_slope) != SR_OK)
		return SR_ERR;

	if (hmo_update_sample_rate(sdi) != SR_OK)
		return SR_ERR;

	sr_info("Fetching finished.");

	scope_state_dump(config, state);

	return SR_OK;
}
Пример #16
0
SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, GVariant **gvar,
		const GVariantType *gvtype, int command, ...)
{
	struct sr_scpi_dev_inst *scpi;
	va_list args;
	double d;
	int ret;
	char *s;
	const char *cmd;

	if (!(cmd = scpi_cmd_get(sdi, command))) {
		/* Device does not implement this command, that's OK. */
		return SR_OK_CONTINUE;
	}

	scpi = sdi->conn;
	va_start(args, command);
	ret = sr_scpi_send_variadic(scpi, cmd, args);
	va_end(args);
	if (ret != SR_OK)
		return ret;

	/* Non-standard data type responses. */
	if (command == SCPI_CMD_GET_OUTPUT_REGULATION) {
		/*
		 * The Rigol DP800 series return CV/CC/UR, Philips PM2800
		 * return VOLT/CURR. We always return a GVariant string in
		 * the Rigol notation.
		 */
		if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK)
			return ret;
		if (!strcmp(s, "CV") || !strcmp(s, "VOLT")) {
			*gvar = g_variant_new_string("CV");
		} else if (!strcmp(s, "CC") || !strcmp(s, "CURR")) {
			*gvar = g_variant_new_string("CC");
		} else if (!strcmp(s, "UR")) {
			*gvar = g_variant_new_string("UR");
		} else {
			sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
			ret = SR_ERR_DATA;
		}
		g_free(s);
	} else {
		/* Straight SCPI getters to GVariant types. */
		if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_BOOLEAN)) {
			if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK)
				return ret;
			if (!strcasecmp(s, "ON") || !strcasecmp(s, "1") || !strcasecmp(s, "YES"))
				*gvar = g_variant_new_boolean(TRUE);
			else if (!strcasecmp(s, "OFF") || !strcasecmp(s, "0") || !strcasecmp(s, "NO"))
				*gvar = g_variant_new_boolean(FALSE);
			else
				ret = SR_ERR;
			g_free(s);
		} if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_DOUBLE)) {
			if ((ret = sr_scpi_get_double(scpi, NULL, &d)) == SR_OK)
				*gvar = g_variant_new_double(d);
		} if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_STRING)) {
			if ((ret = sr_scpi_get_string(scpi, NULL, &s)) == SR_OK)
				*gvar = g_variant_new_string(s);
		}
	}

	return ret;
}
Пример #17
0
SR_PRIV int gwinstek_gds_800_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct sr_scpi_dev_inst *scpi;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog_old analog;
	char command[32];
	char *response;
	float volts_per_division;
	int num_samples, i;
	float samples[MAX_SAMPLES];
	uint32_t sample_rate;
	char *end_ptr;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	scpi = sdi->conn;

	if (!(revents == G_IO_IN || revents == 0))
		return TRUE;

	switch (devc->state) {
	case START_ACQUISITION:
		if (sr_scpi_send(scpi, ":TRIG:MOD 3") != SR_OK) {
			sr_err("Failed to set trigger mode to SINGLE.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}
		if (sr_scpi_send(scpi, ":STOP") != SR_OK) {
			sr_err("Failed to put the trigger system into STOP state.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}
		if (sr_scpi_send(scpi, ":RUN") != SR_OK) {
			sr_err("Failed to put the trigger system into RUN state.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}

		devc->cur_acq_channel = 0;
		devc->state = START_TRANSFER_OF_CHANNEL_DATA;
		break;
	case START_TRANSFER_OF_CHANNEL_DATA:
		if (((struct sr_channel *)g_slist_nth_data(sdi->channels, devc->cur_acq_channel))->enabled) {
			if (sr_scpi_send(scpi, ":ACQ%d:MEM?", devc->cur_acq_channel+1) != SR_OK) {
				sr_err("Failed to acquire memory.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			if (sr_scpi_read_begin(scpi) != SR_OK) {
				sr_err("Could not begin reading SCPI response.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			devc->state = WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE;
			devc->cur_rcv_buffer_position = 0;
		} else {
			/* All channels acquired. */
			if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) {
				sr_spew("All channels acquired.");

				if (devc->cur_acq_frame == devc->frame_limit - 1) {
					/* All frames accquired. */
					sr_spew("All frames acquired.");
					
					sdi->driver->dev_acquisition_stop(sdi);
					return TRUE;
				} else {
					/* Start acquiring next frame. */
					if (devc->df_started) {
						packet.type = SR_DF_FRAME_END;
						sr_session_send(sdi, &packet);
						
						packet.type = SR_DF_FRAME_BEGIN;
						sr_session_send(sdi, &packet);
					}

					devc->cur_acq_frame++;
					devc->state = START_ACQUISITION;
				}
			} else {
				/* Start acquiring next channel. */
				devc->cur_acq_channel++;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK) {
			if (devc->rcv_buffer[0] == '#')
				devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE;
		}
		break;
	case WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK) {
			if (devc->rcv_buffer[0] != '4' &&
				devc->rcv_buffer[0] != '5' &&
				devc->rcv_buffer[0] != '6') {
				sr_err("Data size digits is not 4, 5 or 6 but "
				       "'%c'.", devc->rcv_buffer[0]);
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			} else {
				devc->data_size_digits = devc->rcv_buffer[0] - '0';
				devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE:
		if (read_data(sdi, scpi, devc, devc->data_size_digits) == SR_OK) {
			devc->rcv_buffer[devc->data_size_digits] = 0;
			if (sr_atoi(devc->rcv_buffer, &devc->data_size) != SR_OK) {
				sr_err("Could not parse data size '%s'", devc->rcv_buffer);
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			} else
				devc->state = WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE;
		}
		break;
	case WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE:
		if (read_data(sdi, scpi, devc, sizeof(float)) == SR_OK) {
			/*
			 * Contrary to the documentation, this field is
			 * transfered with most significant byte first!
			 */
			sample_rate = RB32(devc->rcv_buffer);
			memcpy(&devc->sample_rate, &sample_rate, sizeof(float));
			devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE;

			if (!devc->df_started) {
				std_session_send_df_header(sdi);

				packet.type = SR_DF_FRAME_BEGIN;
				sr_session_send(sdi, &packet);

				devc->df_started = TRUE;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK)
			devc->state = WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE;
		break;
	case WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE:
		if (read_data(sdi, scpi, devc, 3) == SR_OK)
			devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE;
		break;
	case WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE:
		if (read_data(sdi, scpi, devc, devc->data_size - 8) == SR_OK) {
			/* Fetch data needed for conversion from device. */
			snprintf(command, sizeof(command), ":CHAN%d:SCAL?",
					devc->cur_acq_channel + 1);
			if (sr_scpi_get_string(scpi, command, &response) != SR_OK) {
				sr_err("Failed to get volts per division.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			volts_per_division = g_ascii_strtod(response, &end_ptr);
			if (!strcmp(end_ptr, "mV"))
				volts_per_division *= 1.e-3;
			g_free(response);

			num_samples = (devc->data_size - 8) / 2;
			sr_spew("Received %d number of samples from channel "
				"%d.", num_samples, devc->cur_acq_channel + 1);

			/* Convert data. */
			for (i = 0; i < num_samples; i++)
				samples[i] = ((float) ((int16_t) (RB16(&devc->rcv_buffer[i*2])))) / 256. * VERTICAL_DIVISIONS * volts_per_division;

			/* Fill frame. */
			analog.channels = g_slist_append(NULL, g_slist_nth_data(sdi->channels, devc->cur_acq_channel));
			analog.num_samples = num_samples;
			analog.data = samples;
			analog.mq = SR_MQ_VOLTAGE;
			analog.unit = SR_UNIT_VOLT;
			analog.mqflags = 0;
			packet.type = SR_DF_ANALOG_OLD;
			packet.payload = &analog;
			sr_session_send(sdi, &packet);
			g_slist_free(analog.channels);

			/* All channels acquired. */
			if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) {
				sr_spew("All channels acquired.");

				if (devc->cur_acq_frame == devc->frame_limit - 1) {
					/* All frames acquired. */
					sr_spew("All frames acquired.");
					sdi->driver->dev_acquisition_stop(sdi);
					return TRUE;
				} else {
					/* Start acquiring next frame. */
					if (devc->df_started) {
						packet.type = SR_DF_FRAME_END;
						sr_session_send(sdi, &packet);
						
						packet.type = SR_DF_FRAME_BEGIN;
						sr_session_send(sdi, &packet);
					}
					devc->cur_acq_frame++;
					devc->state = START_ACQUISITION;
				}
			} else {
				/* Start acquiring next channel. */
				devc->state = START_TRANSFER_OF_CHANNEL_DATA;
				devc->cur_acq_channel++;
				return TRUE;
			}
		}
		break;
	}

	return TRUE;
}