예제 #1
0
파일: scpi.c 프로젝트: bvanheu/libsigrok-ad
/**
 * 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;
}
예제 #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;
	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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
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;
}