Example #1
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;
}
Example #2
0
static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	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;
	struct sr_channel *prev_chan;
	float fvalue;
	const char *s;
	char *mstr;
	int i, exp;

	sr_spew("FETC reply '%s'.", g_match_info_get_string(match));
	devc = sdi->priv;
	i = devc->cur_channel->index;

	if (devc->cur_mq[i] == -1)
		/* This detects when channel P2 is reporting TEMP as an identical
		 * copy of channel P3. In this case, we just skip P2. */
		goto skip_value;

	s = g_match_info_get_string(match);
	if (!strcmp(s, "-9.90000000E+37") || !strcmp(s, "+9.90000000E+37")) {
		/* An invalid measurement shows up on the display as "O.L", but
		 * comes through like this. Since comparing 38-digit floats
		 * is rather problematic, we'll cut through this here. */
		fvalue = NAN;
	} else {
		mstr = g_match_info_fetch(match, 1);
		if (sr_atof_ascii(mstr, &fvalue) != SR_OK) {
			g_free(mstr);
			sr_dbg("Invalid float.");
			return SR_ERR;
		}
		g_free(mstr);
		if (devc->cur_exponent[i] != 0)
			fvalue *= powf(10, devc->cur_exponent[i]);
	}

	if (devc->cur_unit[i] == SR_UNIT_DECIBEL_MW ||
	    devc->cur_unit[i] == SR_UNIT_DECIBEL_VOLT ||
	    devc->cur_unit[i] == SR_UNIT_PERCENTAGE) {
		mstr = g_match_info_fetch(match, 2);
		if (mstr && sr_atoi(mstr, &exp) == SR_OK) {
			devc->cur_digits[i] = MIN(4 - exp, devc->cur_digits[i]);
			devc->cur_encoding[i] = MIN(5 - exp, devc->cur_encoding[i]);
		}
		g_free(mstr);
	}

	sr_analog_init(&analog, &encoding, &meaning, &spec,
	               devc->cur_digits[i] - devc->cur_exponent[i]);
	analog.meaning->mq = devc->cur_mq[i];
	analog.meaning->unit = devc->cur_unit[i];
	analog.meaning->mqflags = devc->cur_mqflags[i];
	analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
	analog.num_samples = 1;
	analog.data = &fvalue;
	encoding.digits = devc->cur_encoding[i] - devc->cur_exponent[i];
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);
	g_slist_free(analog.meaning->channels);

	sr_sw_limits_update_samples_read(&devc->limits, 1);

skip_value:
	prev_chan = devc->cur_channel;
	devc->cur_channel = sr_next_enabled_channel(sdi, devc->cur_channel);
	if (devc->cur_channel->index > prev_chan->index)
		return JOB_AGAIN;
	else
		return JOB_FETC;
}
Example #3
0
static int recv_conf_u124x_5x(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	struct dev_context *devc;
	char *mstr, *rstr, *m2;
	int i, resolution;

	sr_spew("CONF? response '%s'.", g_match_info_get_string(match));
	devc = sdi->priv;
	i = devc->cur_conf->index;

	devc->mode_squarewave = 0;

	rstr = g_match_info_fetch(match, 4);
	if (rstr && sr_atoi(rstr, &resolution) == SR_OK) {
		devc->cur_digits[i] = -resolution;
		devc->cur_encoding[i] = -resolution + 1;
	}
	g_free(rstr);

	mstr = g_match_info_fetch(match, 1);
	if (!strncmp(mstr, "VOLT", 4)) {
		devc->cur_mq[i] = SR_MQ_VOLTAGE;
		devc->cur_unit[i] = SR_UNIT_VOLT;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		if (i == 0 && devc->mode_dbm_dbv) {
			devc->cur_unit[i] = devc->mode_dbm_dbv;
			devc->cur_digits[i] = 3;
			devc->cur_encoding[i] = 4;
		}
		if (mstr[4] == ':') {
			if (!strncmp(mstr + 5, "ACDC", 4)) {
				/* AC + DC offset */
				devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS;
			} else if (!strncmp(mstr + 5, "AC", 2)) {
				devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_RMS;
			} else if (!strncmp(mstr + 5, "DC", 2)) {
				devc->cur_mqflags[i] |= SR_MQFLAG_DC;
			} else if (!strncmp(mstr + 5, "HRAT", 4)) {
				devc->cur_mq[i] = SR_MQ_HARMONIC_RATIO;
				devc->cur_unit[i] = SR_UNIT_PERCENTAGE;
				devc->cur_digits[i] = 2;
				devc->cur_encoding[i] = 3;
			}
		} else
			devc->cur_mqflags[i] |= SR_MQFLAG_DC;
	} else if (!strncmp(mstr, "CURR", 4)) {
		devc->cur_mq[i] = SR_MQ_CURRENT;
		devc->cur_unit[i] = SR_UNIT_AMPERE;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		if (mstr[4] == ':') {
			if (!strncmp(mstr + 5, "ACDC", 4)) {
				/* AC + DC offset */
				devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS;
			} else if (!strncmp(mstr + 5, "AC", 2)) {
				devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_RMS;
			} else if (!strncmp(mstr + 5, "DC", 2)) {
				devc->cur_mqflags[i] |= SR_MQFLAG_DC;
			}
		} else
			devc->cur_mqflags[i] |= SR_MQFLAG_DC;
	} else if (!strcmp(mstr, "RES")) {
		devc->cur_mq[i] = SR_MQ_RESISTANCE;
		devc->cur_unit[i] = SR_UNIT_OHM;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
	} else if (!strcmp(mstr, "COND")) {
		devc->cur_mq[i] = SR_MQ_CONDUCTANCE;
		devc->cur_unit[i] = SR_UNIT_SIEMENS;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
	} else if (!strcmp(mstr, "CAP")) {
		devc->cur_mq[i] = SR_MQ_CAPACITANCE;
		devc->cur_unit[i] = SR_UNIT_FARAD;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
	} else if (!strncmp(mstr, "FREQ", 4) || !strncmp(mstr, "FC1", 3)) {
		devc->cur_mq[i] = SR_MQ_FREQUENCY;
		devc->cur_unit[i] = SR_UNIT_HERTZ;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
	} else if (!strncmp(mstr, "PULS:PWID", 9)) {
		devc->cur_mq[i] = SR_MQ_PULSE_WIDTH;
		devc->cur_unit[i] = SR_UNIT_SECOND;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_encoding[i] = MIN(devc->cur_encoding[i], 6);
	} else if (!strncmp(mstr, "PULS:PDUT", 9)) {
		devc->cur_mq[i] = SR_MQ_DUTY_CYCLE;
		devc->cur_unit[i] = SR_UNIT_PERCENTAGE;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 3;
		devc->cur_encoding[i] = 4;
	} else if (!strcmp(mstr, "CONT")) {
		devc->cur_mq[i] = SR_MQ_CONTINUITY;
		devc->cur_unit[i] = SR_UNIT_OHM;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
	} else if (!strcmp(mstr, "DIOD")) {
		devc->cur_mq[i] = SR_MQ_VOLTAGE;
		devc->cur_unit[i] = SR_UNIT_VOLT;
		devc->cur_mqflags[i] = SR_MQFLAG_DIODE | SR_MQFLAG_DC;
		devc->cur_exponent[i] = 0;
		if (devc->profile->model == KEYSIGHT_U1281 ||
		    devc->profile->model == KEYSIGHT_U1282) {
			devc->cur_digits[i] = 4;
			devc->cur_encoding[i] = 5;
		} else {
			devc->cur_digits[i] = 3;
			devc->cur_encoding[i] = 4;
		}
	} else if (!strncmp(mstr, "T1", 2) || !strncmp(mstr, "T2", 2) ||
		   !strncmp(mstr, "TEMP", 4)) {
		devc->cur_mq[i] = SR_MQ_TEMPERATURE;
		m2 = g_match_info_fetch(match, 2);
		if (!m2 && devc->profile->nb_channels == 3)
			/*
			 * TEMP without param is for secondary display (channel P2)
			 * and is identical to channel P3, so discard it.
			 */
			devc->cur_mq[i] = -1;
		else if (m2 && !strcmp(m2, "FAR"))
			devc->cur_unit[i] = SR_UNIT_FAHRENHEIT;
		else
			devc->cur_unit[i] = SR_UNIT_CELSIUS;
		g_free(m2);
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 1;
		devc->cur_encoding[i] = 2;
	} else if (!strcmp(mstr, "SCOU")) {
		/*
		 * Switch counter, not supported. Not sure what values
		 * come from FETC in this mode, or how they would map
		 * into libsigrok.
		 */
	} else if (!strncmp(mstr, "CPER:", 5)) {
		devc->cur_mq[i] = SR_MQ_CURRENT;
		devc->cur_unit[i] = SR_UNIT_PERCENTAGE;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 2;
		devc->cur_encoding[i] = 3;
	} else if (!strcmp(mstr, "SQU")) {
		/*
		 * Square wave output, not supported. FETC just return
		 * an error in this mode, so don't even call it.
		 */
		devc->mode_squarewave = 1;
	} else if (!strcmp(mstr, "NCV")) {
		devc->cur_mq[i] = SR_MQ_VOLTAGE;
		devc->cur_unit[i] = SR_UNIT_VOLT;
		devc->cur_mqflags[i] = SR_MQFLAG_AC;
		if (devc->profile->model == KEYSIGHT_U1281 ||
		    devc->profile->model == KEYSIGHT_U1282) {
			devc->cur_exponent[i] = -3;
			devc->cur_digits[i] = -1;
			devc->cur_encoding[i] = 0;
		} else {
			devc->cur_exponent[i] = 0;
			devc->cur_digits[i] = 2;
			devc->cur_encoding[i] = 3;
		}
	} else {
		sr_dbg("Unknown first argument '%s'.", mstr);
	}
	g_free(mstr);

	struct sr_channel *prev_conf = devc->cur_conf;
	devc->cur_conf = sr_next_enabled_channel(sdi, devc->cur_conf);
	if (devc->cur_conf->index >= MIN(devc->profile->nb_channels, 2))
		devc->cur_conf = sr_next_enabled_channel(sdi, devc->cur_conf);
	if (devc->cur_conf->index > prev_conf->index)
		return JOB_AGAIN;
	else
		return JOB_CONF;
}
Example #4
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;
}