Ejemplo n.º 1
1
static int dev_open(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_scpi_dev_inst *scpi;
	GVariant *beeper;

	if (sdi->status != SR_ST_INACTIVE)
		return SR_ERR;

	scpi = sdi->conn;
	if (sr_scpi_open(scpi) < 0)
		return SR_ERR;

	sdi->status = SR_ST_ACTIVE;

	devc = sdi->priv;
	scpi_cmd(sdi, devc->device->commands, SCPI_CMD_REMOTE);
	devc = sdi->priv;
	devc->beeper_was_set = FALSE;
	if (scpi_cmd_resp(sdi, devc->device->commands, &beeper,
			G_VARIANT_TYPE_BOOLEAN, SCPI_CMD_BEEPER) == SR_OK) {
		if (g_variant_get_boolean(beeper)) {
			devc->beeper_was_set = TRUE;
			scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_DISABLE);
		}
		g_variant_unref(beeper);
	}

	return SR_OK;
}
Ejemplo n.º 2
0
SR_PRIV int select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch)
{
	struct dev_context *devc;
	struct pps_channel *cur_pch, *new_pch;
	int ret;

	if (g_slist_length(sdi->channels) == 1)
		return SR_OK;

	devc = sdi->priv;
	if (ch == devc->cur_channel)
		return SR_OK;

	new_pch = ch->priv;
	if (devc->cur_channel) {
		cur_pch = devc->cur_channel->priv;
		if (cur_pch->hw_output_idx == new_pch->hw_output_idx) {
			/* Same underlying output channel. */
			devc->cur_channel = ch;
			return SR_OK;
		}
	}

	if ((ret = scpi_cmd(sdi, SCPI_CMD_SELECT_CHANNEL, new_pch->hwname)) == SR_OK)
		devc->cur_channel = ch;

	return ret;
}
Ejemplo n.º 3
0
static int dev_close(struct sr_dev_inst *sdi)
{
	struct sr_scpi_dev_inst *scpi;
	struct dev_context *devc;

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

	devc = sdi->priv;
	scpi = sdi->conn;
	if (scpi) {
		if (devc->beeper_was_set)
			scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_ENABLE);
		scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
		sr_scpi_close(scpi);
		sdi->status = SR_ST_INACTIVE;
	}

	return SR_OK;
}
Ejemplo n.º 4
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	struct sr_scpi_dev_inst *scpi;
	struct sr_channel *ch;
	struct pps_channel *pch;
	int cmd, ret;

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

	devc = sdi->priv;
	scpi = sdi->conn;
	devc->cb_data = cb_data;

	if ((ret = sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 10,
			scpi_pps_receive_data, (void *)sdi)) != SR_OK)
		return ret;
	std_session_send_df_header(sdi, LOG_PREFIX);

	/* Prime the pipe with the first channel's fetch. */
	ch = sr_next_enabled_channel(sdi, NULL);
	pch = ch->priv;
	if ((ret = select_channel(sdi, ch)) < 0)
		return ret;
	if (pch->mq == SR_MQ_VOLTAGE)
		cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
	else if (pch->mq == SR_MQ_FREQUENCY)
		cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
	else if (pch->mq == SR_MQ_CURRENT)
		cmd = SCPI_CMD_GET_MEAS_CURRENT;
	else if (pch->mq == SR_MQ_POWER)
		cmd = SCPI_CMD_GET_MEAS_POWER;
	else
		return SR_ERR;
	scpi_cmd(sdi, devc->device->commands, cmd, pch->hwname);

	return SR_OK;
}
Ejemplo n.º 5
0
static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
{
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_scpi_hw_info *hw_info;
	struct sr_channel_group *cg;
	struct sr_channel *ch;
	const struct scpi_pps *device;
	struct pps_channel *pch;
	struct channel_spec *channels;
	struct channel_group_spec *channel_groups, *cgs;
	struct pps_channel_group *pcg;
	GRegex *model_re;
	GMatchInfo *model_mi;
	GSList *l;
	uint64_t mask;
	unsigned int num_channels, num_channel_groups, ch_num, ch_idx, i, j;
	int ret;
	const char *vendor;
	char ch_name[16];

	if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
		sr_info("Couldn't get IDN response.");
		return NULL;
	}

	device = NULL;
	for (i = 0; i < num_pps_profiles; i++) {
		vendor = sr_vendor_alias(hw_info->manufacturer);
		if (g_ascii_strcasecmp(vendor, pps_profiles[i].vendor))
			continue;
		model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL);
		if (g_regex_match(model_re, hw_info->model, 0, &model_mi))
			device = &pps_profiles[i];
		g_match_info_unref(model_mi);
		g_regex_unref(model_re);
		if (device)
			break;
	}
	if (!device) {
		sr_scpi_hw_info_free(hw_info);
		return NULL;
	}

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(vendor);
	sdi->model = g_strdup(hw_info->model);
	sdi->version = g_strdup(hw_info->firmware_version);
	sdi->conn = scpi;
	sdi->driver = &scpi_pps_driver_info;
	sdi->inst_type = SR_INST_SCPI;
	sdi->serial_num = g_strdup(hw_info->serial_number);

	devc = g_malloc0(sizeof(struct dev_context));
	devc->device = device;
	sdi->priv = devc;

	if (device->num_channels) {
		/* Static channels and groups. */
		channels = (struct channel_spec *)device->channels;
		num_channels = device->num_channels;
		channel_groups = (struct channel_group_spec *)device->channel_groups;
		num_channel_groups = device->num_channel_groups;
	} else {
		/* Channels and groups need to be probed. */
		ret = device->probe_channels(sdi, hw_info, &channels, &num_channels,
				&channel_groups, &num_channel_groups);
		if (ret != SR_OK) {
			sr_err("Failed to probe for channels.");
			return NULL;
		}
		/*
		 * Since these were dynamically allocated, we'll need to free them
		 * later.
		 */
		devc->channels = channels;
		devc->channel_groups = channel_groups;
	}

	ch_idx = 0;
	for (ch_num = 0; ch_num < num_channels; ch_num++) {
		/* Create one channel per measurable output unit. */
		for (i = 0; i < ARRAY_SIZE(pci); i++) {
			if (!scpi_cmd_get(devc->device->commands, pci[i].command))
				continue;
			g_snprintf(ch_name, 16, "%s%s", pci[i].prefix,
					channels[ch_num].name);
			ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE,
					ch_name);
			pch = g_malloc0(sizeof(struct pps_channel));
			pch->hw_output_idx = ch_num;
			pch->hwname = channels[ch_num].name;
			pch->mq = pci[i].mq;
			ch->priv = pch;
		}
	}

	for (i = 0; i < num_channel_groups; i++) {
		cgs = &channel_groups[i];
		cg = g_malloc0(sizeof(struct sr_channel_group));
		cg->name = g_strdup(cgs->name);
		for (j = 0, mask = 1; j < 64; j++, mask <<= 1) {
			if (cgs->channel_index_mask & mask) {
				for (l = sdi->channels; l; l = l->next) {
					ch = l->data;
					pch = ch->priv;
					if (pch->hw_output_idx == j)
						cg->channels = g_slist_append(cg->channels, ch);
				}
			}
		}
		pcg = g_malloc0(sizeof(struct pps_channel_group));
		pcg->features = cgs->features;
		cg->priv = pcg;
		sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
	}

	sr_scpi_hw_info_free(hw_info);
	hw_info = NULL;

	scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
	sr_scpi_close(scpi);

	return sdi;
}
Ejemplo n.º 6
0
static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	double d;
	int ret;

	if (!sdi)
		return SR_ERR_ARG;

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

	if (cg)
		/* Channel group specified. */
		select_channel(sdi, cg->channels->data);

	devc = sdi->priv;
	ret = SR_OK;
	switch (key) {
	case SR_CONF_ENABLED:
		if (g_variant_get_boolean(data))
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OUTPUT_ENABLE);
		else
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OUTPUT_DISABLE);
		break;
	case SR_CONF_VOLTAGE_TARGET:
		d = g_variant_get_double(data);
		ret = scpi_cmd(sdi, devc->device->commands,
				SCPI_CMD_SET_VOLTAGE_TARGET, d);
		break;
	case SR_CONF_OUTPUT_FREQUENCY_TARGET:
		d = g_variant_get_double(data);
		ret = scpi_cmd(sdi, devc->device->commands,
				SCPI_CMD_SET_FREQUENCY_TARGET, d);
		break;
	case SR_CONF_CURRENT_LIMIT:
		d = g_variant_get_double(data);
		ret = scpi_cmd(sdi, devc->device->commands,
				SCPI_CMD_SET_CURRENT_LIMIT, d);
		break;
	case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
		if (g_variant_get_boolean(data))
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLE);
		else
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_DISABLE);
		break;
	case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
		d = g_variant_get_double(data);
		ret = scpi_cmd(sdi, devc->device->commands,
				SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, d);
		break;
	case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
		if (g_variant_get_boolean(data))
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE);
		else
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE);
		break;
	case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
		d = g_variant_get_double(data);
		ret = scpi_cmd(sdi, devc->device->commands,
				SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, d);
		break;
	case SR_CONF_OVER_TEMPERATURE_PROTECTION:
		if (g_variant_get_boolean(data))
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_ENABLE);
		else
			ret = scpi_cmd(sdi, devc->device->commands,
					SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_DISABLE);
		break;
	default:
		ret = SR_ERR_NA;
	}

	return ret;
}
Ejemplo n.º 7
0
SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog analog;
	const struct sr_dev_inst *sdi;
	struct sr_channel *next_channel;
	struct sr_scpi_dev_inst *scpi;
	struct pps_channel *pch;
	float f;
	int cmd;

	(void)fd;
	(void)revents;

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

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

	scpi = sdi->conn;

	/* Retrieve requested value for this state. */
	if (sr_scpi_get_float(scpi, NULL, &f) == SR_OK) {
		pch = devc->cur_channel->priv;
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		analog.channels = g_slist_append(NULL, devc->cur_channel);
		analog.num_samples = 1;
		analog.mq = pch->mq;
		if (pch->mq == SR_MQ_VOLTAGE)
			analog.unit = SR_UNIT_VOLT;
		else if (pch->mq == SR_MQ_CURRENT)
			analog.unit = SR_UNIT_AMPERE;
		else if (pch->mq == SR_MQ_POWER)
			analog.unit = SR_UNIT_WATT;
		analog.mqflags = SR_MQFLAG_DC;
		analog.data = &f;
		sr_session_send(sdi, &packet);
		g_slist_free(analog.channels);
	}

	if (g_slist_length(sdi->channels) > 1) {
		next_channel = next_enabled_channel(sdi, devc->cur_channel);
		if (select_channel(sdi, next_channel) != SR_OK) {
			sr_err("Failed to select channel %s", next_channel->name);
			return FALSE;
		}
	}

	pch = devc->cur_channel->priv;
	if (pch->mq == SR_MQ_VOLTAGE)
		cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
	else if (pch->mq == SR_MQ_FREQUENCY)
		cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
	else if (pch->mq == SR_MQ_CURRENT)
		cmd = SCPI_CMD_GET_MEAS_CURRENT;
	else if (pch->mq == SR_MQ_POWER)
		cmd = SCPI_CMD_GET_MEAS_POWER;
	else
		return SR_ERR;
	scpi_cmd(sdi, cmd);

	return TRUE;
}
Ejemplo n.º 8
0
SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	const struct sr_dev_inst *sdi;
	struct sr_channel *next_channel;
	struct sr_scpi_dev_inst *scpi;
	struct pps_channel *pch;
	const struct channel_spec *ch_spec;
	float f;
	int cmd;

	(void)fd;
	(void)revents;

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

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

	scpi = sdi->conn;

	/* Retrieve requested value for this state. */
	if (sr_scpi_get_float(scpi, NULL, &f) == SR_OK) {
		pch = devc->cur_channel->priv;
		ch_spec = &devc->device->channels[pch->hw_output_idx];
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		/* Note: digits/spec_digits will be overridden later. */
		sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
		analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
		analog.num_samples = 1;
		analog.meaning->mq = pch->mq;
		if (pch->mq == SR_MQ_VOLTAGE) {
			analog.meaning->unit = SR_UNIT_VOLT;
			analog.encoding->digits = ch_spec->voltage[4];
			analog.spec->spec_digits = ch_spec->voltage[3];
		} else if (pch->mq == SR_MQ_CURRENT) {
			analog.meaning->unit = SR_UNIT_AMPERE;
			analog.encoding->digits = ch_spec->current[4];
			analog.spec->spec_digits = ch_spec->current[3];
		} else if (pch->mq == SR_MQ_POWER) {
			analog.meaning->unit = SR_UNIT_WATT;
			analog.encoding->digits = ch_spec->power[4];
			analog.spec->spec_digits = ch_spec->power[3];
		}
		analog.meaning->mqflags = SR_MQFLAG_DC;
		analog.data = &f;
		sr_session_send(sdi, &packet);
		g_slist_free(analog.meaning->channels);
	}

	if (g_slist_length(sdi->channels) > 1) {
		next_channel = sr_next_enabled_channel(sdi, devc->cur_channel);
		if (select_channel(sdi, next_channel) != SR_OK) {
			sr_err("Failed to select channel %s", next_channel->name);
			return FALSE;
		}
	}

	pch = devc->cur_channel->priv;
	if (pch->mq == SR_MQ_VOLTAGE)
		cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
	else if (pch->mq == SR_MQ_FREQUENCY)
		cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
	else if (pch->mq == SR_MQ_CURRENT)
		cmd = SCPI_CMD_GET_MEAS_CURRENT;
	else if (pch->mq == SR_MQ_POWER)
		cmd = SCPI_CMD_GET_MEAS_POWER;
	else
		return SR_ERR;
	scpi_cmd(sdi, devc->device->commands, cmd);

	return TRUE;
}