예제 #1
0
int sr_cset(src *c, srcstmt *stmt, char *value)
{
	int type = c->flags & ~SR_CRO;
	if (c->flags & SR_CRO) {
		sr_error(stmt->r->e, "%s is read-only", stmt->path);
		return -1;
	}
	switch (type) {
	case SR_CU32:
		*((uint32_t*)c->value) = sr_atoi(value);
		break;
	case SR_CU64:
		*((uint64_t*)c->value) = sr_atoi(value);
		break;
	case SR_CSZREF: {
		char *nsz = NULL;
		if (value) {
			nsz = sr_strdup(stmt->r->a, value);
			if (srunlikely(nsz == NULL)) {
				sr_error(stmt->r->e, "%s", "memory allocation failed");
				return -1;
			}
		}
		char **sz = (char**)c->value;
		if (*sz)
			sr_free(stmt->r->a, *sz);
		*sz = nsz;
		break;
	}
	default: assert(0);
	}
	return 0;
}
예제 #2
0
파일: scpi.c 프로젝트: bvanheu/libsigrok-ad
/**
 * Send a SCPI command, read the reply, parse it as comma separated list of
 * unsigned 8 bit integers 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_uint8v(struct sr_scpi_dev_inst *scpi,
			       const char *command, GArray **scpi_response)
{
	int tmp, ret;
	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(uint8_t), 256);

	while (*ptr) {
		if (sr_atoi(*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 (response_array->len == 0) {
		g_array_free(response_array, TRUE);
		*scpi_response = NULL;
		return SR_ERR;
	}

	*scpi_response = response_array;

	return ret;
}
예제 #3
0
/**
 * This function takes a value of the form "2.000E-03", converts it to a
 * significand / factor pair and returns the index of an array where
 * a matching pair was found.
 *
 * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
 * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
 * Therefore it's easier to break the number up into two strings and handle
 * them separately.
 *
 * @param value The string to be parsed.
 * @param array The array of s/f pairs.
 * @param array_len The number of pairs in the array.
 * @param result The index at which a matching pair was found.
 *
 * @return SR_ERR on any parsing error, SR_OK otherwise.
 */
static int array_float_get(gchar *value, const uint64_t array[][2],
		int array_len, int *result)
{
	int i;
	uint64_t f;
	float s;
	unsigned int s_int;
	gchar ss[10], es[10];

	memset(ss, 0, sizeof(ss));
	memset(es, 0, sizeof(es));

	strncpy(ss, value, 5);
	strncpy(es, &(value[6]), 3);

	if (sr_atof_ascii(ss, &s) != SR_OK)
		return SR_ERR;
	if (sr_atoi(es, &i) != SR_OK)
		return SR_ERR;

	/* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
	f = pow(10, abs(i));

	/*
	 * Adjust the significand/factor pair to make sure
	 * that f is a multiple of 1000.
	 */
	while ((int)fmod(log10(f), 3) > 0) { s *= 10; f *= 10; }

	/* Truncate s to circumvent rounding errors. */
	s_int = (unsigned int)s;

	for (i = 0; i < array_len; i++) {
		if ( (s_int == array[i][0]) && (f == array[i][1]) ) {
			*result = i;
			return SR_OK;
		}
	}

	return SR_ERR;
}
예제 #4
0
/**
 * Send a SCPI command, read the reply, parse it as an integer 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_int(struct sr_scpi_dev_inst *scpi,
			    const char *command, int *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_atoi(response, scpi_response) == SR_OK)
		ret = SR_OK;
	else
		ret = SR_ERR_DATA;

	g_free(response);

	return ret;
}
예제 #5
0
/**
 * Reads and removes the block data header from a given data input.
 * Format is #ndddd... with n being the number of decimal digits d.
 * The string dddd... contains the decimal-encoded length of the data.
 * Example: #9000000013 would yield a length of 13 bytes.
 *
 * @param data The input data.
 * @param len The determined input data length.
 */
static int dlm_block_data_header_process(GArray *data, int *len)
{
	int i, n;
	gchar s[20];

	if (g_array_index(data, gchar, 0) != '#')
		return SR_ERR;

	n = (uint8_t)(g_array_index(data, gchar, 1) - '0');

	for (i = 0; i < n; i++)
		s[i] = g_array_index(data, gchar, 2 + i);
	s[i] = 0;

	if (sr_atoi(s, len) != SR_OK)
		return SR_ERR;

	g_array_remove_range(data, 0, 2 + n);

	return SR_OK;
}
예제 #6
0
/** Process a complete line (without CR/LF) in buf. */
static void process_line(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	double dbl;
	int auxint;

	devc = sdi->priv;

	switch (devc->acq_req_pending) {
	case 0: /* Should not happen... */
		break;
	case 1: /* Waiting for data reply to request */
		/* Convert numbers */
		switch (devc->acq_req) {
		case AQ_U1:
		case AQ_U2:
		case AQ_I1:
		case AQ_I2:
			if (sr_atod(devc->buf, &dbl) != SR_OK) {
				sr_err("Failed to convert '%s' to double, errno=%d %s",
					devc->buf, errno, g_strerror(errno));
				dbl = 0.0;
			}
			break;
		case AQ_STATUS:
			if (sr_atoi(devc->buf, &auxint) != SR_OK) {
				sr_err("Failed to convert '%s' to int, errno=%d %s",
					devc->buf, errno, g_strerror(errno));
				auxint = 0;
			}
			break;
		default:
			break;
		}

		switch (devc->acq_req) {
		case AQ_U1:
			devc->channel_status[0].output_voltage_last = dbl;
			break;
		case AQ_I1:
			devc->channel_status[0].output_current_last = dbl;
			break;
		case AQ_U2:
			devc->channel_status[1].output_voltage_last = dbl;
			break;
		case AQ_I2:
			devc->channel_status[1].output_current_last = dbl;
			break;
		case AQ_STATUS: /* Process status and generate data. */
			if (lps_process_status(sdi, auxint) == SR_OK) {
				send_data(sdi);
			}
			break;
		default:
			break;
		}

		devc->acq_req_pending = 2;
		break;
	case 2: /* Waiting for OK after request */
		if (strcmp(devc->buf, "OK")) {
			sr_err("Unexpected reply while waiting for OK: '%s'", devc->buf);
		}
		devc->acq_req_pending = 0;
		break;
	}

	devc->buf[0] = '\0';
	devc->buflen = 0;
}
예제 #7
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;
}
예제 #8
0
파일: protocol.c 프로젝트: abraxa/libsigrok
static int recv_log(const struct sr_dev_inst *sdi, GMatchInfo *match,
                    const int mqs[], const int units[], const int exponents[],
                    unsigned int num_functions)
{
	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;
	char *mstr;
	unsigned function;
	int value, negative, overload, exponent, alternate_unit, mq, unit;
	int mqflags = 0;
	float fvalue;

	sr_spew("LOG response '%s'.", g_match_info_get_string(match));

	devc = sdi->priv;

	mstr = g_match_info_fetch(match, 2);
	if (sr_atoi(mstr, (int*)&function) != SR_OK || function >= num_functions) {
		g_free(mstr);
		sr_dbg("Invalid function.");
		return SR_ERR;
	}
	g_free(mstr);

	mstr = g_match_info_fetch(match, 3);
	if (sr_atoi(mstr, &value) != SR_OK) {
		g_free(mstr);
		sr_dbg("Invalid value.");
		return SR_ERR;
	}
	g_free(mstr);

	mstr = g_match_info_fetch(match, 1);
	negative = mstr[7] & 2 ? -1 : 1;
	overload = mstr[8] & 4;
	exponent = (mstr[9] & 0xF) + exponents[function];
	alternate_unit = mstr[10] & 1;

	if (mstr[ 8] & 1)  mqflags |= SR_MQFLAG_DC;
	if (mstr[ 8] & 2)  mqflags |= SR_MQFLAG_AC;
	if (mstr[11] & 4)  mqflags |= SR_MQFLAG_RELATIVE;
	if (mstr[12] & 1)  mqflags |= SR_MQFLAG_AVG;
	if (mstr[12] & 2)  mqflags |= SR_MQFLAG_MIN;
	if (mstr[12] & 4)  mqflags |= SR_MQFLAG_MAX;
	if (function == 5) mqflags |= SR_MQFLAG_DIODE | SR_MQFLAG_DC;
	g_free(mstr);

	mq = mqs[function];
	unit = units[function];
	if (alternate_unit) {
		if (mq == SR_MQ_RESISTANCE)
			mq = SR_MQ_CONTINUITY;
		if (unit == SR_UNIT_DECIBEL_MW)
			unit = SR_UNIT_DECIBEL_VOLT;
		if (unit == SR_UNIT_CELSIUS) {
			unit = SR_UNIT_FAHRENHEIT;
			if (devc->profile->model == KEYSIGHT_U1281 ||
			    devc->profile->model == KEYSIGHT_U1282)
				exponent--;
		}
	}

	if (overload)
		fvalue = NAN;
	else
		fvalue = negative * value * powf(10, exponent);

	sr_analog_init(&analog, &encoding, &meaning, &spec, -exponent);
	analog.meaning->mq = mq;
	analog.meaning->unit = unit;
	analog.meaning->mqflags = mqflags;
	analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
	analog.num_samples = 1;
	analog.data = &fvalue;
	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);
	devc->cur_sample++;

	return JOB_LOG;
}
예제 #9
0
파일: protocol.c 프로젝트: abraxa/libsigrok
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;
}
예제 #10
0
파일: protocol.c 프로젝트: abraxa/libsigrok
static int recv_conf_u123x(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	struct dev_context *devc;
	char *mstr, *rstr;
	int i, resolution;

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

	rstr = g_match_info_fetch(match, 2);
	if (rstr)
		sr_atoi(rstr, &resolution);
	g_free(rstr);

	mstr = g_match_info_fetch(match, 1);
	if (!strcmp(mstr, "V")) {
		devc->cur_mq[i] = SR_MQ_VOLTAGE;
		devc->cur_unit[i] = SR_UNIT_VOLT;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 4 - resolution;
	} else if (!strcmp(mstr, "MV")) {
		if (devc->mode_tempaux) {
			devc->cur_mq[i] = SR_MQ_TEMPERATURE;
			/* No way to detect whether Fahrenheit or Celsius
			 * is used, so we'll just default to Celsius. */
			devc->cur_unit[i] = SR_UNIT_CELSIUS;
			devc->cur_mqflags[i] = 0;
			devc->cur_exponent[i] = 0;
			devc->cur_digits[i] = 1;
		} else {
			devc->cur_mq[i] = SR_MQ_VOLTAGE;
			devc->cur_unit[i] = SR_UNIT_VOLT;
			devc->cur_mqflags[i] = 0;
			devc->cur_exponent[i] = -3;
			devc->cur_digits[i] = 5 - resolution;
		}
	} else if (!strcmp(mstr, "A")) {
		devc->cur_mq[i] = SR_MQ_CURRENT;
		devc->cur_unit[i] = SR_UNIT_AMPERE;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 3 - resolution;
	} else if (!strcmp(mstr, "UA")) {
		devc->cur_mq[i] = SR_MQ_CURRENT;
		devc->cur_unit[i] = SR_UNIT_AMPERE;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = -6;
		devc->cur_digits[i] = 8 - resolution;
	} else if (!strcmp(mstr, "FREQ")) {
		devc->cur_mq[i] = SR_MQ_FREQUENCY;
		devc->cur_unit[i] = SR_UNIT_HERTZ;
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 2 - resolution;
	} else if (!strcmp(mstr, "RES")) {
		if (devc->mode_continuity) {
			devc->cur_mq[i] = SR_MQ_CONTINUITY;
			devc->cur_unit[i] = SR_UNIT_BOOLEAN;
		} else {
			devc->cur_mq[i] = SR_MQ_RESISTANCE;
			devc->cur_unit[i] = SR_UNIT_OHM;
		}
		devc->cur_mqflags[i] = 0;
		devc->cur_exponent[i] = 0;
		devc->cur_digits[i] = 1 - resolution;
	} 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;
		devc->cur_digits[i] = 3;
	} 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;
		devc->cur_digits[i] = 9 - resolution;
	} else
		sr_dbg("Unknown first argument.");
	g_free(mstr);

	/* This is based on guess, supposing similarity with other models. */
	devc->cur_encoding[i] = devc->cur_digits[i] + 1;

	if (g_match_info_get_match_count(match) == 4) {
		mstr = g_match_info_fetch(match, 3);
		/* Third value, if present, is always AC or DC. */
		if (!strcmp(mstr, "AC")) {
			devc->cur_mqflags[i] |= SR_MQFLAG_AC;
			if (devc->cur_mq[i] == SR_MQ_VOLTAGE)
				devc->cur_mqflags[i] |= SR_MQFLAG_RMS;
		} else if (!strcmp(mstr, "DC")) {
			devc->cur_mqflags[i] |= SR_MQFLAG_DC;
		} else {
			sr_dbg("Unknown first argument '%s'.", mstr);
		}
		g_free(mstr);
	} else
		devc->cur_mqflags[i] &= ~(SR_MQFLAG_AC | SR_MQFLAG_DC);

	return JOB_CONF;
}
예제 #11
0
파일: protocol.c 프로젝트: abraxa/libsigrok
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;
}