Beispiel #1
0
SR_PRIV int sr_metex14_packet_request(struct sr_serial_dev_inst *serial)
{
	const uint8_t wbuf = 'D';

	sr_spew("Requesting DMM packet.");

	return (serial_write_nonblocking(serial, &wbuf, 1) == 1) ? SR_OK : SR_ERR;
}
Beispiel #2
0
static const void *hw_dev_info_get(int dev_index, int dev_info_id)
{
	struct sr_dev_inst *sdi;
	struct context *ctx;
	const void *info;

	if (!(sdi = sr_dev_inst_get(genericdmm_dev_insts, dev_index))) {
		sr_err("genericdmm: sdi was NULL.");
		return NULL;
	}

	if (!(ctx = sdi->priv)) {
		sr_err("genericdmm: sdi->priv was NULL.");
		return NULL;
	}

		sr_spew("genericdmm: dev_index %d, dev_info_id %d.",
				dev_index, dev_info_id);

	switch (dev_info_id) {
	case SR_DI_INST:
		info = sdi;
		sr_spew("genericdmm: Returning sdi.");
		break;
	case SR_DI_NUM_PROBES:
		info = GINT_TO_POINTER(1);
		sr_spew("genericdmm: Returning number of probes: 1.");
		break;
	case SR_DI_PROBE_NAMES:
		info = probe_names;
		sr_spew("genericdmm: Returning probenames.");
		break;
	case SR_DI_CUR_SAMPLERATE:
		/* TODO get rid of this */
		info = NULL;
		sr_spew("genericdmm: Returning samplerate: 0.");
		break;
	default:
		/* Unknown device info ID. */
		sr_err("genericdmm: Unknown device info ID: %d.", dev_info_id);
		info = NULL;
		break;
	}

	return info;
}
Beispiel #3
0
/* This comes in whenever the rotary switch is changed to a new position.
 * We could use it to determine the major measurement mode, but we already
 * have the output of CONF? for that, which is more detailed. However
 * we do need to catch this here, or it'll show up in some other output. */
static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	(void)sdi;

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

	return SR_OK;
}
Beispiel #4
0
/** @private */
SR_PRIV int sr_sessionfile_check(const char *filename)
{
	struct zip *archive;
	struct zip_file *zf;
	struct zip_stat zs;
	uint64_t version;
	int ret;
	char s[11];

	if (!filename)
		return SR_ERR_ARG;

	if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
		sr_err("Not a regular file: %s.", filename);
		return SR_ERR;
	}

	if (!(archive = zip_open(filename, 0, NULL)))
		/* No logging: this can be used just to check if it's
		 * a sigrok session file or not. */
		return SR_ERR;

	/* check "version" */
	if (!(zf = zip_fopen(archive, "version", 0))) {
		sr_dbg("Not a sigrok session file: no version found.");
		zip_discard(archive);
		return SR_ERR;
	}
	ret = zip_fread(zf, s, sizeof(s) - 1);
	if (ret < 0) {
		sr_err("Failed to read version file: %s",
			zip_file_strerror(zf));
		zip_fclose(zf);
		zip_discard(archive);
		return SR_ERR;
	}
	zip_fclose(zf);
	s[ret] = '\0';
	version = g_ascii_strtoull(s, NULL, 10);
	if (version == 0 || version > 2) {
		sr_dbg("Cannot handle sigrok session file version %" PRIu64 ".",
			version);
		zip_discard(archive);
		return SR_ERR;
	}
	sr_spew("Detected sigrok session file version %" PRIu64 ".", version);

	/* read "metadata" */
	if (zip_stat(archive, "metadata", 0, &zs) < 0) {
		sr_dbg("Not a valid sigrok session file.");
		zip_discard(archive);
		return SR_ERR;
	}
	zip_discard(archive);

	return SR_OK;
}
Beispiel #5
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l;
	const char *conn, *serialcomm;

	conn = serialcomm = NULL;

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	/*
	 * We cannot scan for this device because it is write-only.
	 * So just check that the port parameters are valid and assume that
	 * the device is there.
	 */

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	serial_flush(serial);
	serial_close(serial);

	sr_spew("Conrad DIGI 35 CPU assumed at %s.", conn);

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Conrad");
	sdi->model = g_strdup("DIGI 35 CPU");
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
Beispiel #6
0
/**
 * Send a SCPI command, receive the reply and store the reply 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 SCPI response.
 *
 * @return SR_OK on success, SR_ERR* on failure.
 */
SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
			       const char *command, char **scpi_response)
{
	char buf[256];
	int len;
	GString *response;
	gint64 laststart;
	unsigned int elapsed_ms;

	if (command)
		if (sr_scpi_send(scpi, command) != SR_OK)
			return SR_ERR;

	if (sr_scpi_read_begin(scpi) != SR_OK)
		return SR_ERR;

	laststart = g_get_monotonic_time();

	response = g_string_new("");

	*scpi_response = NULL;

	while (!sr_scpi_read_complete(scpi)) {
		len = sr_scpi_read_data(scpi, buf, sizeof(buf));
		if (len < 0) {
			sr_err("Incompletely read SCPI response.");
			g_string_free(response, TRUE);
			return SR_ERR;
		} else if (len > 0) {
		        laststart = g_get_monotonic_time();
		}
		g_string_append_len(response, buf, len);
		elapsed_ms = (g_get_monotonic_time() - laststart) / 1000;
		if (elapsed_ms >= scpi->read_timeout_ms) {
			sr_err("Timed out waiting for SCPI response.");
			g_string_free(response, TRUE);
			return SR_ERR;
		}
	}

	/* Get rid of trailing linefeed if present */
	if (response->len >= 1 && response->str[response->len - 1] == '\n')
		g_string_truncate(response, response->len - 1);

	/* Get rid of trailing carriage return if present */
	if (response->len >= 1 && response->str[response->len - 1] == '\r')
		g_string_truncate(response, response->len - 1);

	sr_spew("Got response: '%.70s', length %" G_GSIZE_FORMAT ".",
		response->str, response->len);

	*scpi_response = g_string_free(response, FALSE);

	return SR_OK;
}
Beispiel #7
0
SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;

	(void)fd;

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

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

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/*
				 * TODO: According to specs, should be \r, but
				 * then we'd have to get rid of the \n.
				 */
				devc->last_req_pending = FALSE;
				nma_process_line(sdi);
				break;
			}
		}
	}

	if (sr_sw_limits_check(&devc->limits)) {
		sr_dev_acquisition_stop(sdi);
	} else {
		/* Request next package. */
		if (devc->last_req_pending) {
			gint64 elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
			if (elapsed_us > NMADMM_TIMEOUT_MS * 1000) {/* Timeout! */
				sr_spew("Request timeout!");
				devc->last_req_pending = FALSE;
			}
		}
		if (!devc->last_req_pending) {
			if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK)
				return FALSE;
		}
	}

	return TRUE;
}
Beispiel #8
0
/**
 * Get a block of data from the LA8.
 *
 * @param devc The struct containing private per-device-instance data. Must not
 *            be NULL. devc->ftdic must not be NULL either.
 * @return SR_OK upon success, or SR_ERR upon errors.
 */
SR_PRIV int la8_read_block(struct dev_context *devc)
{
	int i, byte_offset, m, mi, p, index, bytes_read;
	time_t now;

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

	sr_spew("Reading block %d.", devc->block_counter);

	bytes_read = la8_read(devc, devc->mangled_buf, BS);

	/* If first block read got 0 bytes, retry until success or timeout. */
	if ((bytes_read == 0) && (devc->block_counter == 0)) {
		do {
			sr_spew("Reading block 0 (again).");
			bytes_read = la8_read(devc, devc->mangled_buf, BS);
			/* TODO: How to handle read errors here? */
			now = time(NULL);
		} while ((devc->done > now) && (bytes_read == 0));
	}

	/* Check if block read was successful or a timeout occured. */
	if (bytes_read != BS) {
		sr_err("Trigger timed out. Bytes read: %d.", bytes_read);
		(void) la8_reset(devc); /* Ignore errors. */
		return SR_ERR;
	}

	/* De-mangle the data. */
	sr_spew("Demangling block %d.", devc->block_counter);
	byte_offset = devc->block_counter * BS;
	m = byte_offset / (1024 * 1024);
	mi = m * (1024 * 1024);
	for (i = 0; i < BS; i++) {
		p = i & (1 << 0);
		index = m * 2 + (((byte_offset + i) - mi) / 2) * 16;
		index += (devc->divcount == 0) ? p : (1 - p);
		devc->final_buf[index] = devc->mangled_buf[i];
	}

	return SR_OK;
}
Beispiel #9
0
static int parse_value(const uint8_t *buf, struct es519xx_info *info,
                       float *result)
{
	int i, intval, num_digits;
	float floatval;

	num_digits = 4 + ((info->packet_size == 14) ? 1 : 0);

	/* Bytes 1-4 (or 5): Value (4 or 5 decimal digits) */
	if (info->is_ol) {
		sr_spew("Over limit.");
		*result = INFINITY;
		return SR_OK;
	} else if (info->is_ul) {
		sr_spew("Under limit.");
		*result = INFINITY;
		return SR_OK;
	} else if (!isdigit(buf[1]) || !isdigit(buf[2]) ||
	           !isdigit(buf[3]) || !isdigit(buf[4]) ||
	           (num_digits == 5 && !isdigit(buf[5]))) {
		sr_dbg("Value contained invalid digits: %02x %02x %02x %02x "
		       "(%c %c %c %c).", buf[1], buf[2], buf[3], buf[4],
		       buf[1], buf[2], buf[3], buf[4]);
		return SR_ERR;
	}
	intval = (info->is_digit4) ? 1 : 0;
	for (i = 0; i < num_digits; i++)
		intval = 10 * intval + (buf[i + 1] - '0');

	/* Apply sign. */
	intval *= info->is_sign ? -1 : 1;

	floatval = (float)intval;

	/* Note: The decimal point position will be parsed later. */

	sr_spew("The display value is %f.", floatval);

	*result = floatval;

	return SR_OK;
}
Beispiel #10
0
/**
 * Arrange for the reception of another measurement from the DMM.
 *
 * This routine is unused in the currently implemented PRINT mode,
 * where the meter sends measurements to the PC in pre-set intervals,
 * without the PC's intervention.
 *
 * @param[in]	serial The serial connection.
 *
 * @private
 */
SR_PRIV int sr_asycii_packet_request(struct sr_serial_dev_inst *serial)
{
	/*
	 * The current implementation assumes that the user pressed
	 * the PRINT button. It has no support to query/trigger packet
	 * reception from the meter.
	 */
	(void)serial;
	sr_spew("NOT requesting DMM packet.");
	return SR_OK;
}
Beispiel #11
0
static int scpi_serial_read_data(void *priv, char *buf, int maxlen)
{
	struct scpi_serial *sscpi = priv;
	int len, ret;

	len = BUFFER_SIZE - sscpi->count;

	/* Try to read new data into the buffer if there is space. */
	if (len > 0) {
		ret = serial_read(sscpi->serial, sscpi->buffer + sscpi->read,
				BUFFER_SIZE - sscpi->count);

		if (ret < 0)
			return ret;

		sscpi->count += ret;

		if (ret > 0)
			sr_spew("Read %d bytes into buffer.", ret);
	}

	/* Return as many bytes as possible from buffer, excluding any trailing newline. */
	if (sscpi->read < sscpi->count) {
		len = sscpi->count - sscpi->read;
		if (len > maxlen)
			len = maxlen;
		if (sscpi->buffer[sscpi->read + len - 1] == '\n')
			len--;
		sr_spew("Returning %d bytes from buffer.", len);
		memcpy(buf, sscpi->buffer + sscpi->read, len);
		sscpi->read += len;
		if (sscpi->read == BUFFER_SIZE) {
			sr_spew("Resetting buffer.");
			sscpi->count = 0;
			sscpi->read = 0;
		}
		return len;
	}

	return 0;
}
static int scpi_usbtmc_libusb_send(void *priv, const char *command)
{
	struct scpi_usbtmc_libusb *uscpi = priv;

	if (scpi_usbtmc_bulkout(uscpi, DEV_DEP_MSG_OUT,
	                        command, strlen(command), EOM) <= 0)
		return SR_ERR;

	sr_spew("Successfully sent SCPI command: '%s'.", command);

	return SR_OK;
}
Beispiel #13
0
static void log_packet(const uint8_t *buf, int idx)
{
	int i;
	GString *s;

	s = g_string_sized_new(100);
	g_string_printf(s, "Packet: ");
	for (i = 0; i < center_devs[idx].packet_size; i++)
	        g_string_append_printf(s, "%02x ", buf[i]);
	sr_spew("%s", s->str);
	g_string_free(s, TRUE);
}
Beispiel #14
0
/** USB event source dispatch() method.
 */
static gboolean usb_source_dispatch(GSource *source,
		GSourceFunc callback, void *user_data)
{
	struct usb_source *usource;
	GPollFD *pollfd;
	unsigned int revents;
	unsigned int i;
	gboolean keep;

	usource = (struct usb_source *)source;
	revents = 0;
	/*
	 * This is somewhat arbitrary, but drivers use revents to distinguish
	 * actual I/O from timeouts. When we remove the user timeout from the
	 * driver API, this will no longer be needed.
	 */
	for (i = 0; i < usource->pollfds->len; i++) {
		pollfd = g_ptr_array_index(usource->pollfds, i);
		revents |= pollfd->revents;
	}
	if (revents != 0)
		sr_spew("%s: revents 0x%.2X", __func__, revents);
	else
		sr_spew("%s: timed out", __func__);

	if (!callback) {
		sr_err("Callback not set, cannot dispatch event.");
		return G_SOURCE_REMOVE;
	}
	keep = (*(sr_receive_data_callback)callback)(-1, revents, user_data);

	if (G_LIKELY(keep) && G_LIKELY(!g_source_is_destroyed(source))) {
		if (usource->timeout_us >= 0)
			usource->due_us = g_source_get_time(source)
					+ usource->timeout_us;
		else
			usource->due_us = INT64_MAX;
	}
	return keep;
}
Beispiel #15
0
SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	int len;
	int64_t now, elapsed;

	(void)fd;

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

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

	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while(FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read(devc->serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen++;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\r') {
				*(devc->buf + --devc->buflen) = '\0';
				handle_line(sdi);
				break;
			}
		}
	}

	if (devc->num_samples >= devc->limit_samples) {
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		return TRUE;
	}

	now = g_get_monotonic_time() / 1000;
	elapsed = now - devc->cmd_sent_at;
	/* Send query command at poll_period interval, or after 1 second
	 * has elapsed. This will make it recover from any out-of-sync
	 * or temporary disconnect issues. */
	if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period)
			|| elapsed > 1000) {
		sr_spew("Sending QM.");
		if (serial_write(devc->serial, "QM\r", 3) == -1)
			sr_err("Unable to send QM: %s.", strerror(errno));
		devc->cmd_sent_at = now;
		devc->expect_response = TRUE;
	}

	return TRUE;
}
Beispiel #16
0
static int parse_value(const uint8_t *buf, struct vc870_info *info,
                       float *result)
{
	int i, intval;
	float floatval;

	/* Bytes 3-7: Main display value (5 decimal digits) */
	if (info->is_open || info->is_ol1) {
		sr_spew("Over limit.");
		*result = INFINITY;
		return SR_OK;
	} else if (!isdigit(buf[3]) || !isdigit(buf[4]) ||
	           !isdigit(buf[5]) || !isdigit(buf[6]) || !isdigit(buf[7])) {
		sr_dbg("Invalid digits: %02x %02x %02x %02x %02X "
			"(%c %c %c %c %c).",
			buf[3], buf[4], buf[5], buf[6], buf[7],
			buf[3], buf[4], buf[5], buf[6], buf[7]);
		return SR_ERR;
	}

	intval = 0;
	for (i = 0; i < 5; i++)
		intval = 10 * intval + (buf[i + 3] - '0'); /* Main display. */
		// intval = 10 * intval + (buf[i + 8] - '0'); /* TODO: Aux display. */

	/* Apply sign. */
	intval *= info->is_sign1 ? -1 : 1;
	// intval *= info->is_sign2 ? -1 : 1; /* TODO: Fahrenheit / aux display. */

	floatval = (float)intval;

	/* Note: The decimal point position will be parsed later. */

	sr_spew("The display value is %f.", floatval);

	*result = floatval;

	return SR_OK;
}
Beispiel #17
0
static int receive(const struct sr_transform *t,
		struct sr_datafeed_packet *packet_in,
		struct sr_datafeed_packet **packet_out)
{
	if (!t || !t->sdi || !packet_in || !packet_out)
		return SR_ERR_ARG;

	/* Do nothing, just pass on packets unmodified. */
	sr_spew("Received packet of type %d, passing on unmodified.", packet_in->type);
	*packet_out = packet_in;

	return SR_OK;
}
/** @private */
SR_PRIV int sr_sessionfile_check(const char *filename)
{
	struct stat st;
	struct zip *archive;
	struct zip_file *zf;
	struct zip_stat zs;
	int version, ret;
	char s[11];

	if (!filename)
		return SR_ERR_ARG;

	if (stat(filename, &st) == -1) {
		sr_err("Couldn't stat %s: %s", filename, g_strerror(errno));
		return SR_ERR;
	}

	if (!(archive = zip_open(filename, 0, &ret)))
		/* No logging: this can be used just to check if it's
		 * a sigrok session file or not. */
		return SR_ERR;

	/* check "version" */
	if (!(zf = zip_fopen(archive, "version", 0))) {
		sr_dbg("Not a sigrok session file: no version found.");
		return SR_ERR;
	}
	if ((ret = zip_fread(zf, s, 10)) == -1)
		return SR_ERR;
	zip_fclose(zf);
	s[ret] = 0;
	version = strtoull(s, NULL, 10);
	if (version > 2) {
		sr_dbg("Cannot handle sigrok session file version %d.", version);
		return SR_ERR;
	}
	sr_spew("Detected sigrok session file version %d.", version);

	/* read "metadata" */
	if (zip_stat(archive, "metadata", 0, &zs) == -1) {
		sr_dbg("Not a valid sigrok session file.");
		return SR_ERR;
	}

	if ((ret = zip_close(archive)) == -1) {
		sr_dbg("error closing zipfile: %s", zip_strerror(archive));
		return SR_ERR;
	}

	return SR_OK;
}
Beispiel #19
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_old analog;
	float fvalue;
	const char *s;
	char *mstr;

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

	if (devc->cur_mq == -1)
		/* Haven't seen configuration yet, so can't know what
		 * the fetched float means. Not really an error, we'll
		 * get metadata soon enough. */
		return SR_OK;

	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_divider > 0)
			fvalue /= devc->cur_divider;
	}

	memset(&analog, 0, sizeof(struct sr_datafeed_analog_old));
	analog.mq = devc->cur_mq;
	analog.unit = devc->cur_unit;
	analog.mqflags = devc->cur_mqflags;
	analog.channels = sdi->channels;
	analog.num_samples = 1;
	analog.data = &fvalue;
	packet.type = SR_DF_ANALOG_OLD;
	packet.payload = &analog;
	sr_session_send(devc->cb_data, &packet);

	devc->num_samples++;

	return SR_OK;
}
Beispiel #20
0
static int receive(const struct sr_transform *t,
		struct sr_datafeed_packet *packet_in,
		struct sr_datafeed_packet **packet_out)
{
	const struct sr_datafeed_logic *logic;
	const struct sr_datafeed_analog *analog;
	struct sr_channel *ch;
	GSList *l;
	float *fdata, *f;
	int si, num_channels, c;
	uint8_t *b;
	uint64_t i, j;

	if (!t || !t->sdi || !packet_in || !packet_out)
		return SR_ERR_ARG;

	switch (packet_in->type) {
	case SR_DF_LOGIC:
		logic = packet_in->payload;
		for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) {
			for (j = 0; j < logic->unitsize; j++) {
				/* For now invert every bit in every byte. */
				b = (uint8_t *)logic->data + i + logic->unitsize - 1 - j;
				*b = ~(*b);
			}
		}
		break;
	case SR_DF_ANALOG:
		analog = packet_in->payload;
		fdata = (float *)analog->data;
		num_channels = g_slist_length(analog->channels);
		for (si = 0; si < analog->num_samples; si++) {
			/* For now invert all values in all channels. */
			for (l = analog->channels, c = 0; l; l = l->next, c++) {
				ch = l->data;
				(void)ch;
				f = &fdata[si * num_channels + c];
				*f = 1.0 / *f;
			}
		}
		break;
	default:
		sr_spew("Unsupported packet type %d, ignoring.", packet_in->type);
		break;
	}

	/* Return the in-place-modified packet. */
	*packet_out = packet_in;

	return SR_OK;
}
Beispiel #21
0
/*
 * Since the 22-812 does not identify itself in any way, shape, or form,
 * we really don't know for sure who is sending the data. We must use every
 * possible check to filter out bad packets, especially since detection of the
 * 22-812 depends on how well we can filter the packets.
 */
SR_PRIV gboolean sr_rs9lcd_packet_valid(const uint8_t *buf)
{
	const struct rs9lcd_packet *rs_packet = (void *)buf;

	/*
	 * Check for valid mode first, before calculating the checksum. No
	 * point calculating the checksum, if we know we'll reject the packet.
	 */
	if (!(rs_packet->mode < MODE_INVALID))
		return FALSE;

	if (!checksum_valid(rs_packet)) {
		sr_spew("Packet with invalid checksum. Discarding.");
		return FALSE;
	}

	if (!selection_good(rs_packet)) {
		sr_spew("Packet with invalid selection bits. Discarding.");
		return FALSE;
	}

	return TRUE;
}
Beispiel #22
0
static int get_cfg(const struct sr_dev_inst *sdi, char *cmd, char *reply)
{
	int len;

	if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
		return SR_ERR;

	if ((len = serial_read(sdi->conn, reply, 255)) < 0)
		return SR_ERR;
	reply[len] = '\0';
	sr_spew("Received '%s'.", reply);

	return SR_OK;
}
Beispiel #23
0
static gboolean receive_line(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	const struct agdmm_recv *recvs, *recv;
	GRegex *reg;
	GMatchInfo *match;
	gboolean stop = FALSE;
	int i;

	devc = sdi->priv;

	/* Strip CRLF */
	while (devc->buflen) {
		if (*(devc->buf + devc->buflen - 1) == '\r'
				|| *(devc->buf + devc->buflen - 1) == '\n')
			*(devc->buf + --devc->buflen) = '\0';
		else
			break;
	}
	sr_spew("Received '%s'.", devc->buf);

	recv = NULL;
	recvs = devc->profile->recvs;
	for (i = 0; (&recvs[i])->recv_regex; i++) {
		reg = g_regex_new((&recvs[i])->recv_regex, 0, 0, NULL);
		if (g_regex_match(reg, (char *)devc->buf, 0, &match)) {
			recv = &recvs[i];
			break;
		}
		g_match_info_unref(match);
		g_regex_unref(reg);
	}
	if (recv) {
		enum job_type type = recv->recv(sdi, match);
		if (type == job_current(devc)->type)
			job_done(devc);
		else if (type == JOB_AGAIN)
			job_again(devc);
		else if (type == JOB_STOP)
			stop = TRUE;
		g_match_info_unref(match);
		g_regex_unref(reg);
	} else
		sr_dbg("Unknown line '%s'.", devc->buf);

	/* Done with this. */
	devc->buflen = 0;
	return stop;
}
Beispiel #24
0
static int dev_open(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	int ret;
	int64_t timediff_us, timediff_ms;

	devc = sdi->priv;

	/*
	 * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS
	 * milliseconds for the FX2 to renumerate.
	 */
	ret = SR_ERR;
	if (devc->fw_updated > 0) {
		sr_info("Waiting for device to reset.");
		/* Takes >= 300ms for the FX2 to be gone from the USB bus. */
		g_usleep(300 * 1000);
		timediff_ms = 0;
		while (timediff_ms < MAX_RENUM_DELAY_MS) {
			if ((ret = logic16_dev_open(sdi)) == SR_OK)
				break;
			g_usleep(100 * 1000);

			timediff_us = g_get_monotonic_time() - devc->fw_updated;
			timediff_ms = timediff_us / 1000;
			sr_spew("Waited %" PRIi64 "ms.", timediff_ms);
		}
		if (ret != SR_OK) {
			sr_err("Device failed to renumerate.");
			return SR_ERR;
		}
		sr_info("Device came back after %" PRIi64 "ms.", timediff_ms);
	} else {
		sr_info("Firmware upload was not needed.");
		ret = logic16_dev_open(sdi);
	}

	if (ret != SR_OK) {
		sr_err("Unable to open device.");
		return SR_ERR;
	}

	if (devc->cur_samplerate == 0) {
		/* Samplerate hasn't been set; default to the slowest one. */
		devc->cur_samplerate = samplerates[0];
	}

	return SR_OK;
}
Beispiel #25
0
/* This comes in whenever the rotary switch is changed to a new position.
 * We could use it to determine the major measurement mode, but we already
 * have the output of CONF? for that, which is more detailed. However
 * we do need to catch this here, or it'll show up in some other output. */
static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	struct dev_context *devc = sdi->priv;

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

	devc->current_job = 0;
	devc->job_running = FALSE;
	memset(devc->jobs_start, 0, sizeof(devc->jobs_start));
	devc->cur_mq[0] = -1;
	if (devc->profile->nb_channels > 2)
		devc->cur_mq[1] = -1;

	return SR_OK;
}
Beispiel #26
0
static int scpi_serial_read_data(void *priv, char *buf, int maxlen)
{
	struct scpi_serial *sscpi = priv;
	int ret;

	/* Try to read new data into the buffer. */
	ret = serial_read_nonblocking(sscpi->serial, buf, maxlen);

	if (ret < 0)
		return ret;

	if (ret > 0) {
		sr_spew("Read %d bytes into buffer.", ret);

		if (buf[ret - 1] == '\n') {
			sscpi->got_newline = TRUE;
			sr_spew("Received terminator");
		} else {
			sscpi->got_newline = FALSE;
		}
	}

	return ret;
}
Beispiel #27
0
static int dev_open(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	int64_t timediff_us, timediff_ms;
	int err;

	devc = sdi->priv;
	usb = sdi->conn;

	/*
	 * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS
	 * for the FX2 to renumerate.
	 */
	err = SR_ERR;
	if (devc->fw_updated > 0) {
		sr_info("Waiting for device to reset.");
		/* Takes >= 300ms for the FX2 to be gone from the USB bus. */
		g_usleep(300 * 1000);
		timediff_ms = 0;
		while (timediff_ms < MAX_RENUM_DELAY_MS) {
			if ((err = hantek_6xxx_open(sdi)) == SR_OK)
				break;
			g_usleep(100 * 1000);
			timediff_us = g_get_monotonic_time() - devc->fw_updated;
			timediff_ms = timediff_us / 1000;
			sr_spew("Waited %" PRIi64 " ms.", timediff_ms);
		}
		if (timediff_ms < MAX_RENUM_DELAY_MS)
			sr_info("Device came back after %"PRIu64" ms.", timediff_ms);
	} else {
		err = hantek_6xxx_open(sdi);
	}

	if (err != SR_OK) {
		sr_err("Unable to open device.");
		return SR_ERR;
	}

	err = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
	if (err != 0) {
		sr_err("Unable to claim interface: %s.",
			   libusb_error_name(err));
		return SR_ERR;
	}

	return SR_OK;
}
Beispiel #28
0
SR_PRIV void sl2_receive_transfer_out( struct libusb_transfer *transfer)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	int ret = 0;

	sdi = transfer->user_data;
	devc = sdi->priv;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		sr_err("Transfer to device failed: %i.", transfer->status);
		devc->transfer_error = TRUE;
		return;
	}

	if (sdi->status == SR_ST_STOPPING && !devc->stopping_in_progress) {
		devc->next_state = STATE_RESET_AND_IDLE;
		devc->stopping_in_progress = TRUE;

		if (libusb_submit_transfer(devc->xfer_in) != 0) {
			sr_err("Submit transfer failed: %s.",
				libusb_error_name(ret));

			devc->transfer_error = TRUE;
		}

		return;
	}

	if (devc->state != devc->next_state)
		sr_spew("State changed from %i to %i.",
			devc->state, devc->next_state);
	devc->state = devc->next_state;

	if (devc->state == STATE_IDLE) {
		stop_acquisition(sdi);
	} else if (devc->state == STATE_SAMPLE) {
		devc->next_state = STATE_WAIT_DATA_READY;
		ret = libusb_submit_transfer(devc->xfer_in);
	} else if (devc->state == STATE_WAIT_DEVICE_READY) {
		ret = libusb_submit_transfer(devc->xfer_in);
	}

	if (ret != 0) {
		sr_err("Submit transfer failed: %s.", libusb_error_name(ret));
		devc->transfer_error = TRUE;
	}
}
Beispiel #29
0
/** USB event source finalize() method.
 */
static void usb_source_finalize(GSource *source)
{
	struct usb_source *usource;

	usource = (struct usb_source *)source;

	sr_spew("%s", __func__);

	libusb_set_pollfd_notifiers(usource->usb_ctx, NULL, NULL, NULL);

	g_ptr_array_unref(usource->pollfds);
	usource->pollfds = NULL;

	sr_session_source_destroyed(usource->session,
			usource->usb_ctx, source);
}
Beispiel #30
0
/**
 * Read single byte from serial port.
 *
 * @retval -1 Timeout or error.
 * @retval other Byte.
 */
static int read_byte(struct sr_serial_dev_inst *serial, gint64 timeout)
{
	uint8_t result = 0;
	int rc = 0;

	for (;;) {
		rc = serial_read_nonblocking(serial, &result, 1);
		if (rc == 1) {
			sr_spew("read: 0x%02x/%d", result, result);
			return result;
		}
		if (g_get_monotonic_time() > timeout)
			return -1;
		g_usleep(2000);
	}
}