Пример #1
0
/* Read the header of a data block */
static int rigol_ds_read_header(struct sr_dev_inst *sdi)
{
	struct sr_scpi_dev_inst *scpi = sdi->conn;
	struct dev_context *devc = sdi->priv;
	char *buf = (char *) devc->buffer;
	size_t header_length;
	int ret;

	/* Try to read the hashsign and length digit. */
	if (devc->num_header_bytes < 2) {
		ret = sr_scpi_read_data(scpi, buf + devc->num_header_bytes,
				2 - devc->num_header_bytes);
		if (ret < 0) {
			sr_err("Read error while reading data header.");
			return SR_ERR;
		}
		devc->num_header_bytes += ret;
	}

	if (devc->num_header_bytes < 2)
		return 0;

	if (buf[0] != '#' || !isdigit(buf[1]) || buf[1] == '0') {
		sr_err("Received invalid data block header '%c%c'.", buf[0], buf[1]);
		return SR_ERR;
	}

	header_length = 2 + buf[1] - '0';

	/* Try to read the length. */
	if (devc->num_header_bytes < header_length) {
		ret = sr_scpi_read_data(scpi, buf + devc->num_header_bytes,
				header_length - devc->num_header_bytes);
		if (ret < 0) {
			sr_err("Read error while reading data header.");
			return SR_ERR;
		}
		devc->num_header_bytes += ret;
	}

	if (devc->num_header_bytes < header_length)
		return 0;

	/* Read the data length. */
	buf[header_length] = '\0';

	if (parse_int(buf + 2, &ret) != SR_OK) {
		sr_err("Received invalid data block length '%s'.", buf + 2);
		return -1;
	}

	sr_dbg("Received data block header: '%s' -> block length %d", buf, ret);

	return ret;
}
Пример #2
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;

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

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

	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) {
			g_string_free(response, TRUE);
			return SR_ERR;
		}
		g_string_append_len(response, buf, len);
	}

	*scpi_response = response->str;
	g_string_free(response, FALSE);

	return SR_OK;
}
Пример #3
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;
}
Пример #4
0
static int read_data(struct sr_dev_inst *sdi,
		struct sr_scpi_dev_inst *scpi, struct dev_context *devc,
		int data_size)
{
	int len;

	len = sr_scpi_read_data(scpi,
		&devc->rcv_buffer[devc->cur_rcv_buffer_position],
		data_size - devc->cur_rcv_buffer_position);
	if (len < 0) {
		sr_err("Read data error.");
		sdi->driver->dev_acquisition_stop(sdi);
		devc->cur_rcv_buffer_position = 0;
		return SR_ERR;
	}

	devc->cur_rcv_buffer_position += len;

	/* Handle the case where sr_scpi_read_data stopped at the newline. */
	if (len < data_size && sr_scpi_read_complete(scpi)) {
		devc->rcv_buffer[devc->cur_rcv_buffer_position] = '\n';
		devc->cur_rcv_buffer_position++;
	}

	if (devc->cur_rcv_buffer_position < data_size)
		return SR_ERR; /* Not finished yet. */
	else if (devc->cur_rcv_buffer_position == data_size) {
		 devc->cur_rcv_buffer_position = 0;
		return SR_OK;
	} else {
		sr_err("Too many bytes read.");
		sdi->driver->dev_acquisition_stop(sdi);
		devc->cur_rcv_buffer_position = 0;
		return SR_ERR;
	}
}
Пример #5
0
SR_PRIV int rigol_ds_receive(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;
	struct sr_datafeed_logic logic;
	double vdiv, offset;
	int len, i, vref;
	struct sr_channel *ch;
	gsize expected_data_bytes;

	(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->wait_event) {
	case WAIT_NONE:
		break;
	case WAIT_TRIGGER:
		if (rigol_ds_trigger_wait(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_channel_start(sdi) != SR_OK)
			return TRUE;
		return TRUE;
	case WAIT_BLOCK:
		if (rigol_ds_block_wait(sdi) != SR_OK)
			return TRUE;
		break;
	case WAIT_STOP:
		if (rigol_ds_stop_wait(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_check_stop(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_channel_start(sdi) != SR_OK)
			return TRUE;
		return TRUE;
	default:
		sr_err("BUG: Unknown event target encountered");
		break;
	}

	ch = devc->channel_entry->data;

	expected_data_bytes = ch->type == SR_CHANNEL_ANALOG ?
			devc->analog_frame_size : devc->digital_frame_size;

	if (devc->num_block_bytes == 0) {
		if (devc->model->series->protocol >= PROTOCOL_V4) {
			if (sr_scpi_send(sdi->conn, ":WAV:START %d",
					devc->num_channel_bytes + 1) != SR_OK)
				return TRUE;
			if (sr_scpi_send(sdi->conn, ":WAV:STOP %d",
					MIN(devc->num_channel_bytes + ACQ_BLOCK_SIZE,
						devc->analog_frame_size)) != SR_OK)
				return TRUE;
		}

		if (devc->model->series->protocol >= PROTOCOL_V3)
			if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK)
				return TRUE;

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

		if (devc->format == FORMAT_IEEE488_2) {
			sr_dbg("New block header expected");
			len = rigol_ds_read_header(sdi);
			if (len == 0)
				/* Still reading the header. */
				return TRUE;
			if (len == -1) {
				sr_err("Read error, aborting capture.");
				packet.type = SR_DF_FRAME_END;
				sr_session_send(cb_data, &packet);
				sdi->driver->dev_acquisition_stop(sdi, cb_data);
				return TRUE;
			}
			/* At slow timebases in live capture the DS2072
			 * sometimes returns "short" data blocks, with
			 * apparently no way to get the rest of the data.
			 * Discard these, the complete data block will
			 * appear eventually.
			 */
			if (devc->data_source == DATA_SOURCE_LIVE
					&& (unsigned)len < expected_data_bytes) {
				sr_dbg("Discarding short data block");
				sr_scpi_read_data(scpi, (char *)devc->buffer, len + 1);
				return TRUE;
			}
			devc->num_block_bytes = len;
		} else {
			devc->num_block_bytes = expected_data_bytes;
		}
		devc->num_block_read = 0;
	}

	len = devc->num_block_bytes - devc->num_block_read;
	if (len > ACQ_BUFFER_SIZE)
		len = ACQ_BUFFER_SIZE;
	sr_dbg("Requesting read of %d bytes", len);

	len = sr_scpi_read_data(scpi, (char *)devc->buffer, len);

	if (len == -1) {
		sr_err("Read error, aborting capture.");
		packet.type = SR_DF_FRAME_END;
		sr_session_send(cb_data, &packet);
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		return TRUE;
	}

	sr_dbg("Received %d bytes.", len);

	devc->num_block_read += len;

	if (ch->type == SR_CHANNEL_ANALOG) {
		vref = devc->vert_reference[ch->index];
		vdiv = devc->vdiv[ch->index] / 25.6;
		offset = devc->vert_offset[ch->index];
		if (devc->model->series->protocol >= PROTOCOL_V3)
			for (i = 0; i < len; i++)
				devc->data[i] = ((int)devc->buffer[i] - vref) * vdiv - offset;
		else
			for (i = 0; i < len; i++)
				devc->data[i] = (128 - devc->buffer[i]) * vdiv - offset;
		analog.channels = g_slist_append(NULL, ch);
		analog.num_samples = len;
		analog.data = devc->data;
		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(cb_data, &packet);
		g_slist_free(analog.channels);
	} else {
		logic.length = len;
		// TODO: For the MSO1000Z series, we need a way to express that
		// this data is in fact just for a single channel, with the valid
		// data for that channel in the LSB of each byte.
		logic.unitsize = devc->model->series->protocol == PROTOCOL_V4 ? 1 : 2;
		logic.data = devc->buffer;
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		sr_session_send(cb_data, &packet);
	}

	if (devc->num_block_read == devc->num_block_bytes) {
		sr_dbg("Block has been completed");
		if (devc->model->series->protocol >= PROTOCOL_V3) {
			/* Discard the terminating linefeed */
			sr_scpi_read_data(scpi, (char *)devc->buffer, 1);
		}
		if (devc->format == FORMAT_IEEE488_2) {
			/* Prepare for possible next block */
			devc->num_header_bytes = 0;
			devc->num_block_bytes = 0;
			if (devc->data_source != DATA_SOURCE_LIVE)
				rigol_ds_set_wait_event(devc, WAIT_BLOCK);
		}
		if (!sr_scpi_read_complete(scpi)) {
			sr_err("Read should have been completed");
			packet.type = SR_DF_FRAME_END;
			sr_session_send(cb_data, &packet);
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			return TRUE;
		}
		devc->num_block_read = 0;
	} else {
		sr_dbg("%" PRIu64 " of %" PRIu64 " block bytes read",
			devc->num_block_read, devc->num_block_bytes);
	}

	devc->num_channel_bytes += len;

	if (devc->num_channel_bytes < expected_data_bytes)
		/* Don't have the full data for this channel yet, re-run. */
		return TRUE;

	/* End of data for this channel. */
	if (devc->model->series->protocol == PROTOCOL_V3) {
		/* Signal end of data download to scope */
		if (devc->data_source != DATA_SOURCE_LIVE)
			/*
			 * This causes a query error, without it switching
			 * to the next channel causes an error. Fun with
			 * firmware...
			 */
			rigol_ds_config_set(sdi, ":WAV:END");
	}

	if (devc->channel_entry->next) {
		/* We got the frame for this channel, now get the next channel. */
		devc->channel_entry = devc->channel_entry->next;
		rigol_ds_channel_start(sdi);
	} else {
		/* Done with this frame. */
		packet.type = SR_DF_FRAME_END;
		sr_session_send(cb_data, &packet);

		if (++devc->num_frames == devc->limit_frames) {
			/* Last frame, stop capture. */
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
		} else {
			/* Get the next frame, starting with the first channel. */
			devc->channel_entry = devc->enabled_channels;

			rigol_ds_capture_start(sdi);

			/* Start of next frame. */
			packet.type = SR_DF_FRAME_BEGIN;
			sr_session_send(cb_data, &packet);
		}
	}

	return TRUE;
}
Пример #6
0
/**
 * Attempts to query sample data from the oscilloscope in order to send it
 * to the session bus for further processing.
 *
 * @param fd The file descriptor used as the event source.
 * @param revents The received events.
 * @param cb_data Callback data, in this case our device instance.
 *
 * @return TRUE in case of success or a recoverable error,
 *         FALSE when a fatal error was encountered.
 */
SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct scope_state *model_state;
	struct dev_context *devc;
	struct sr_channel *ch;
	struct sr_datafeed_packet packet;
	int chunk_len, num_bytes;
	static GArray *data = NULL;

	(void)fd;
	(void)revents;

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

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

	if (!(model_state = (struct scope_state*)devc->model_state))
		return FALSE;

	/* Are we waiting for a response from the device? */
	if (!devc->data_pending)
		return TRUE;

	/* Check if a new query response is coming our way. */
	if (!data) {
		if (sr_scpi_read_begin(sdi->conn) == SR_OK)
			/* The 16 here accounts for the header and EOL. */
			data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
					16 + model_state->samples_per_frame);
		else
			return TRUE;
	}

	/* Store incoming data. */
	chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
			RECEIVE_BUFFER_SIZE);
	if (chunk_len < 0) {
		sr_err("Error while reading data: %d", chunk_len);
		goto fail;
	}
	g_array_append_vals(data, devc->receive_buffer, chunk_len);

	/* Read the entire query response before processing. */
	if (!sr_scpi_read_complete(sdi->conn))
		return TRUE;

	/* We finished reading and are no longer waiting for data. */
	devc->data_pending = FALSE;

	/* Signal the beginning of a new frame if this is the first channel. */
	if (devc->current_channel == devc->enabled_channels) {
		packet.type = SR_DF_FRAME_BEGIN;
		sr_session_send(sdi, &packet);
	}

	if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
		sr_err("Encountered malformed block data header.");
		goto fail;
	}

	if (num_bytes == 0) {
		sr_warn("Zero-length waveform data packet received. " \
				"Live mode not supported yet, stopping " \
				"acquisition and retrying.");
		/* Don't care about return value here. */
		dlm_acquisition_stop(sdi->conn);
		g_array_free(data, TRUE);
		dlm_channel_data_request(sdi);
		return TRUE;
	}

	ch = devc->current_channel->data;
	switch (ch->type) {
	case SR_CHANNEL_ANALOG:
		if (dlm_analog_samples_send(data,
				&model_state->analog_states[ch->index],
				sdi) != SR_OK)
			goto fail;
		break;
	case SR_CHANNEL_LOGIC:
		if (dlm_digital_samples_send(data, sdi) != SR_OK)
			goto fail;
		break;
	default:
		sr_err("Invalid channel type encountered.");
		break;
	}

	g_array_free(data, TRUE);
	data = NULL;

	/*
	 * Signal the end of this frame if this was the last enabled channel
	 * and set the next enabled channel. Then, request its data.
	 */
	if (!devc->current_channel->next) {
		packet.type = SR_DF_FRAME_END;
		sr_session_send(sdi, &packet);
		devc->current_channel = devc->enabled_channels;

		/*
		 * As of now we only support importing the current acquisition
		 * data so we're going to stop at this point.
		 */
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		return TRUE;
	} else
		devc->current_channel = devc->current_channel->next;

	if (dlm_channel_data_request(sdi) != SR_OK) {
		sr_err("Failed to request acquisition data.");
		goto fail;
	}

	return TRUE;

fail:
	if (data) {
		g_array_free(data, TRUE);
		data = NULL;
	}

	return FALSE;
}